These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a
document processor specifically written for the Python documentation.
-.. _reStructuredText: http://docutils.sourceforge.net/rst.html
+.. _reStructuredText: https://docutils.sourceforge.io/rst.html
.. _Sphinx: http://sphinx-doc.org/
.. In the online version of these documents, you can submit comments and suggest
* Fred L. Drake, Jr., the creator of the original Python documentation toolset
and writer of much of the content;
-* the `Docutils <http://docutils.sourceforge.net/>`_ project for creating
+* the `Docutils <https://docutils.sourceforge.io/>`_ project for creating
reStructuredText and the Docutils suite;
* Fredrik Lundh for his Alternative Python Reference project from which Sphinx
got many good ideas.
Using the Python issue tracker
==============================
-Bug reports for Python itself should be submitted via the Python Bug Tracker
-(https://bugs.python.org/). The bug tracker offers a web form which allows
-pertinent information to be entered and submitted to the developers.
+Issue reports for Python itself should be submitted via the GitHub issues
+tracker (https://github.com/python/cpython/issues).
+The GitHub issues tracker offers a web form which allows pertinent information
+to be entered and submitted to the developers.
The first step in filing a report is to determine whether the problem has
already been reported. The advantage in doing so, aside from saving the
-developers time, is that you learn what has been done to fix it; it may be that
+developers' time, is that you learn what has been done to fix it; it may be that
the problem has already been fixed for the next release, or additional
information is needed (in which case you are welcome to provide it if you can!).
-To do this, search the bug database using the search box on the top of the page.
+To do this, search the tracker using the search box at the top of the page.
-If the problem you're reporting is not already in the bug tracker, go back to
-the Python Bug Tracker and log in. If you don't already have a tracker account,
-select the "Register" link or, if you use OpenID, one of the OpenID provider
-logos in the sidebar. It is not possible to submit a bug report anonymously.
+If the problem you're reporting is not already in the list, log in to GitHub.
+If you don't already have a GitHub account, create a new account using the
+"Sign up" link.
+It is not possible to submit a bug report anonymously.
-Being now logged in, you can submit a bug. Select the "Create New" link in the
-sidebar to open the bug reporting form.
+Being now logged in, you can submit an issue.
+Click on the "New issue" button in the top bar to report a new issue.
-The submission form has a number of fields. For the "Title" field, enter a
-*very* short description of the problem; less than ten words is good. In the
-"Type" field, select the type of your problem; also select the "Component" and
-"Versions" to which the bug relates.
+The submission form has two fields, "Title" and "Comment".
+
+For the "Title" field, enter a *very* short description of the problem;
+less than ten words is good.
In the "Comment" field, describe the problem in detail, including what you
expected to happen and what did happen. Be sure to include whether any
extension modules were involved, and what hardware and software platform you
were using (including version information as appropriate).
-Each bug report will be assigned to a developer who will determine what needs to
-be done to correct the problem. You will receive an update each time action is
-taken on the bug.
+Each issue report will be reviewed by a developer who will determine what needs to
+be done to correct the problem. You will receive an update each time an action is
+taken on the issue.
.. seealso::
the `core-mentorship mailing list`_ is a friendly place to get answers to
any and all questions pertaining to the process of fixing issues in Python.
-.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity
+.. _Documentation bugs: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs
.. _Python Developer's Guide: https://devguide.python.org/
.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/
PyErr_Restore(error_type, error_value, error_traceback);
}
- For this field to be taken into account (even through inheritance),
- you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit.
-
Also, note that, in a garbage collected Python,
:c:member:`~PyTypeObject.tp_dealloc` may be called from
any Python thread, not just the thread which created the object (if the object
.. versionadded:: 3.4
+ .. versionchanged:: 3.8
+
+ Before version 3.8 it was necessary to set the
+ :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be
+ used. This is no longer required.
+
.. seealso:: "Safe object finalization" (:pep:`442`)
:ref:`sub-interpreters <sub-interpreter-support>`, so they should not
include any subinterpreter-specific state.
-Also, since :c:type:`PyTypeObject` is not part of the :ref:`stable ABI <stable>`,
-any extension modules using static types must be compiled for a specific
-Python minor version.
+Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API
+<stable>` as an opaque struct, any extension modules using static types must be
+compiled for a specific Python minor version.
.. _heap-types:
'root_include_title': False # We use the version switcher instead.
}
+# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207
+# https://github.com/python/cpython/issues/91207
+if any('htmlhelp' in arg for arg in sys.argv):
+ html_style = 'pydoctheme.css'
+
# Short title used e.g. for <title> HTML tags.
html_short_title = '%s Documentation' % release
<var-decl name='root_cframe' type-id='type-id-23' visibility='default' filepath='./Include/cpython/pystate.h' line='148' column='1'/>
</data-member>
</class-decl>
- <class-decl name='_is' size-in-bits='908160' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='220' column='1' id='type-id-224'>
+ <class-decl name='_is' size-in-bits='908224' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='220' column='1' id='type-id-224'>
<data-member access='public' layout-offset-in-bits='0'>
<var-decl name='next' type-id='type-id-225' visibility='default' filepath='./Include/internal/pycore_interp.h' line='222' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='121728'>
<var-decl name='type_cache' type-id='type-id-249' visibility='default' filepath='./Include/internal/pycore_interp.h' line='313' column='1'/>
</data-member>
+ <data-member access='public' layout-offset-in-bits='908160'>
+ <var-decl name='int_max_str_digits' type-id='type-id-9' visibility='default' filepath='./Include/internal/pycore_interp.h' line='309' column='1'/>
+ </data-member>
</class-decl>
<pointer-type-def type-id='type-id-224' size-in-bits='64' id='type-id-225'/>
<class-decl name='pyruntimestate' size-in-bits='5376' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='61' column='1' id='type-id-250'>
-role,name,added,ifdef_note
-function,PyAIter_Check,3.10,
-function,PyArg_Parse,3.2,
-function,PyArg_ParseTuple,3.2,
-function,PyArg_ParseTupleAndKeywords,3.2,
-function,PyArg_UnpackTuple,3.2,
-function,PyArg_VaParse,3.2,
-function,PyArg_VaParseTupleAndKeywords,3.2,
-function,PyArg_ValidateKeywordArguments,3.2,
-var,PyBaseObject_Type,3.2,
-function,PyBool_FromLong,3.2,
-var,PyBool_Type,3.2,
-var,PyByteArrayIter_Type,3.2,
-function,PyByteArray_AsString,3.2,
-function,PyByteArray_Concat,3.2,
-function,PyByteArray_FromObject,3.2,
-function,PyByteArray_FromStringAndSize,3.2,
-function,PyByteArray_Resize,3.2,
-function,PyByteArray_Size,3.2,
-var,PyByteArray_Type,3.2,
-var,PyBytesIter_Type,3.2,
-function,PyBytes_AsString,3.2,
-function,PyBytes_AsStringAndSize,3.2,
-function,PyBytes_Concat,3.2,
-function,PyBytes_ConcatAndDel,3.2,
-function,PyBytes_DecodeEscape,3.2,
-function,PyBytes_FromFormat,3.2,
-function,PyBytes_FromFormatV,3.2,
-function,PyBytes_FromObject,3.2,
-function,PyBytes_FromString,3.2,
-function,PyBytes_FromStringAndSize,3.2,
-function,PyBytes_Repr,3.2,
-function,PyBytes_Size,3.2,
-var,PyBytes_Type,3.2,
-type,PyCFunction,3.2,
-type,PyCFunctionWithKeywords,3.2,
-function,PyCFunction_Call,3.2,
-function,PyCFunction_GetFlags,3.2,
-function,PyCFunction_GetFunction,3.2,
-function,PyCFunction_GetSelf,3.2,
-function,PyCFunction_New,3.4,
-function,PyCFunction_NewEx,3.2,
-var,PyCFunction_Type,3.2,
-function,PyCMethod_New,3.9,
-function,PyCallIter_New,3.2,
-var,PyCallIter_Type,3.2,
-function,PyCallable_Check,3.2,
-type,PyCapsule_Destructor,3.2,
-function,PyCapsule_GetContext,3.2,
-function,PyCapsule_GetDestructor,3.2,
-function,PyCapsule_GetName,3.2,
-function,PyCapsule_GetPointer,3.2,
-function,PyCapsule_Import,3.2,
-function,PyCapsule_IsValid,3.2,
-function,PyCapsule_New,3.2,
-function,PyCapsule_SetContext,3.2,
-function,PyCapsule_SetDestructor,3.2,
-function,PyCapsule_SetName,3.2,
-function,PyCapsule_SetPointer,3.2,
-var,PyCapsule_Type,3.2,
-var,PyClassMethodDescr_Type,3.2,
-function,PyCodec_BackslashReplaceErrors,3.2,
-function,PyCodec_Decode,3.2,
-function,PyCodec_Decoder,3.2,
-function,PyCodec_Encode,3.2,
-function,PyCodec_Encoder,3.2,
-function,PyCodec_IgnoreErrors,3.2,
-function,PyCodec_IncrementalDecoder,3.2,
-function,PyCodec_IncrementalEncoder,3.2,
-function,PyCodec_KnownEncoding,3.2,
-function,PyCodec_LookupError,3.2,
-function,PyCodec_NameReplaceErrors,3.7,
-function,PyCodec_Register,3.2,
-function,PyCodec_RegisterError,3.2,
-function,PyCodec_ReplaceErrors,3.2,
-function,PyCodec_StreamReader,3.2,
-function,PyCodec_StreamWriter,3.2,
-function,PyCodec_StrictErrors,3.2,
-function,PyCodec_Unregister,3.10,
-function,PyCodec_XMLCharRefReplaceErrors,3.2,
-function,PyComplex_FromDoubles,3.2,
-function,PyComplex_ImagAsDouble,3.2,
-function,PyComplex_RealAsDouble,3.2,
-var,PyComplex_Type,3.2,
-function,PyDescr_NewClassMethod,3.2,
-function,PyDescr_NewGetSet,3.2,
-function,PyDescr_NewMember,3.2,
-function,PyDescr_NewMethod,3.2,
-var,PyDictItems_Type,3.2,
-var,PyDictIterItem_Type,3.2,
-var,PyDictIterKey_Type,3.2,
-var,PyDictIterValue_Type,3.2,
-var,PyDictKeys_Type,3.2,
-function,PyDictProxy_New,3.2,
-var,PyDictProxy_Type,3.2,
-var,PyDictRevIterItem_Type,3.8,
-var,PyDictRevIterKey_Type,3.8,
-var,PyDictRevIterValue_Type,3.8,
-var,PyDictValues_Type,3.2,
-function,PyDict_Clear,3.2,
-function,PyDict_Contains,3.2,
-function,PyDict_Copy,3.2,
-function,PyDict_DelItem,3.2,
-function,PyDict_DelItemString,3.2,
-function,PyDict_GetItem,3.2,
-function,PyDict_GetItemString,3.2,
-function,PyDict_GetItemWithError,3.2,
-function,PyDict_Items,3.2,
-function,PyDict_Keys,3.2,
-function,PyDict_Merge,3.2,
-function,PyDict_MergeFromSeq2,3.2,
-function,PyDict_New,3.2,
-function,PyDict_Next,3.2,
-function,PyDict_SetItem,3.2,
-function,PyDict_SetItemString,3.2,
-function,PyDict_Size,3.2,
-var,PyDict_Type,3.2,
-function,PyDict_Update,3.2,
-function,PyDict_Values,3.2,
-var,PyEllipsis_Type,3.2,
-var,PyEnum_Type,3.2,
-function,PyErr_BadArgument,3.2,
-function,PyErr_BadInternalCall,3.2,
-function,PyErr_CheckSignals,3.2,
-function,PyErr_Clear,3.2,
-function,PyErr_Display,3.2,
-function,PyErr_ExceptionMatches,3.2,
-function,PyErr_Fetch,3.2,
-function,PyErr_Format,3.2,
-function,PyErr_FormatV,3.5,
-function,PyErr_GetExcInfo,3.7,
-function,PyErr_GivenExceptionMatches,3.2,
-function,PyErr_NewException,3.2,
-function,PyErr_NewExceptionWithDoc,3.2,
-function,PyErr_NoMemory,3.2,
-function,PyErr_NormalizeException,3.2,
-function,PyErr_Occurred,3.2,
-function,PyErr_Print,3.2,
-function,PyErr_PrintEx,3.2,
-function,PyErr_ProgramText,3.2,
-function,PyErr_ResourceWarning,3.6,
-function,PyErr_Restore,3.2,
-function,PyErr_SetExcFromWindowsErr,3.7,on Windows
-function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows
-function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows
-function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows
-function,PyErr_SetExcInfo,3.7,
-function,PyErr_SetFromErrno,3.2,
-function,PyErr_SetFromErrnoWithFilename,3.2,
-function,PyErr_SetFromErrnoWithFilenameObject,3.2,
-function,PyErr_SetFromErrnoWithFilenameObjects,3.7,
-function,PyErr_SetFromWindowsErr,3.7,on Windows
-function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows
-function,PyErr_SetImportError,3.7,
-function,PyErr_SetImportErrorSubclass,3.6,
-function,PyErr_SetInterrupt,3.2,
-function,PyErr_SetInterruptEx,3.10,
-function,PyErr_SetNone,3.2,
-function,PyErr_SetObject,3.2,
-function,PyErr_SetString,3.2,
-function,PyErr_SyntaxLocation,3.2,
-function,PyErr_SyntaxLocationEx,3.7,
-function,PyErr_WarnEx,3.2,
-function,PyErr_WarnExplicit,3.2,
-function,PyErr_WarnFormat,3.2,
-function,PyErr_WriteUnraisable,3.2,
-function,PyEval_AcquireLock,3.2,
-function,PyEval_AcquireThread,3.2,
-function,PyEval_CallFunction,3.2,
-function,PyEval_CallMethod,3.2,
-function,PyEval_CallObjectWithKeywords,3.2,
-function,PyEval_EvalCode,3.2,
-function,PyEval_EvalCodeEx,3.2,
-function,PyEval_EvalFrame,3.2,
-function,PyEval_EvalFrameEx,3.2,
-function,PyEval_GetBuiltins,3.2,
-function,PyEval_GetFrame,3.2,
-function,PyEval_GetFuncDesc,3.2,
-function,PyEval_GetFuncName,3.2,
-function,PyEval_GetGlobals,3.2,
-function,PyEval_GetLocals,3.2,
-function,PyEval_InitThreads,3.2,
-function,PyEval_ReleaseLock,3.2,
-function,PyEval_ReleaseThread,3.2,
-function,PyEval_RestoreThread,3.2,
-function,PyEval_SaveThread,3.2,
-function,PyEval_ThreadsInitialized,3.2,
-var,PyExc_ArithmeticError,3.2,
-var,PyExc_AssertionError,3.2,
-var,PyExc_AttributeError,3.2,
-var,PyExc_BaseException,3.2,
-var,PyExc_BlockingIOError,3.7,
-var,PyExc_BrokenPipeError,3.7,
-var,PyExc_BufferError,3.2,
-var,PyExc_BytesWarning,3.2,
-var,PyExc_ChildProcessError,3.7,
-var,PyExc_ConnectionAbortedError,3.7,
-var,PyExc_ConnectionError,3.7,
-var,PyExc_ConnectionRefusedError,3.7,
-var,PyExc_ConnectionResetError,3.7,
-var,PyExc_DeprecationWarning,3.2,
-var,PyExc_EOFError,3.2,
-var,PyExc_EncodingWarning,3.10,
-var,PyExc_EnvironmentError,3.2,
-var,PyExc_Exception,3.2,
-var,PyExc_FileExistsError,3.7,
-var,PyExc_FileNotFoundError,3.7,
-var,PyExc_FloatingPointError,3.2,
-var,PyExc_FutureWarning,3.2,
-var,PyExc_GeneratorExit,3.2,
-var,PyExc_IOError,3.2,
-var,PyExc_ImportError,3.2,
-var,PyExc_ImportWarning,3.2,
-var,PyExc_IndentationError,3.2,
-var,PyExc_IndexError,3.2,
-var,PyExc_InterruptedError,3.7,
-var,PyExc_IsADirectoryError,3.7,
-var,PyExc_KeyError,3.2,
-var,PyExc_KeyboardInterrupt,3.2,
-var,PyExc_LookupError,3.2,
-var,PyExc_MemoryError,3.2,
-var,PyExc_ModuleNotFoundError,3.6,
-var,PyExc_NameError,3.2,
-var,PyExc_NotADirectoryError,3.7,
-var,PyExc_NotImplementedError,3.2,
-var,PyExc_OSError,3.2,
-var,PyExc_OverflowError,3.2,
-var,PyExc_PendingDeprecationWarning,3.2,
-var,PyExc_PermissionError,3.7,
-var,PyExc_ProcessLookupError,3.7,
-var,PyExc_RecursionError,3.7,
-var,PyExc_ReferenceError,3.2,
-var,PyExc_ResourceWarning,3.7,
-var,PyExc_RuntimeError,3.2,
-var,PyExc_RuntimeWarning,3.2,
-var,PyExc_StopAsyncIteration,3.7,
-var,PyExc_StopIteration,3.2,
-var,PyExc_SyntaxError,3.2,
-var,PyExc_SyntaxWarning,3.2,
-var,PyExc_SystemError,3.2,
-var,PyExc_SystemExit,3.2,
-var,PyExc_TabError,3.2,
-var,PyExc_TimeoutError,3.7,
-var,PyExc_TypeError,3.2,
-var,PyExc_UnboundLocalError,3.2,
-var,PyExc_UnicodeDecodeError,3.2,
-var,PyExc_UnicodeEncodeError,3.2,
-var,PyExc_UnicodeError,3.2,
-var,PyExc_UnicodeTranslateError,3.2,
-var,PyExc_UnicodeWarning,3.2,
-var,PyExc_UserWarning,3.2,
-var,PyExc_ValueError,3.2,
-var,PyExc_Warning,3.2,
-var,PyExc_WindowsError,3.7,on Windows
-var,PyExc_ZeroDivisionError,3.2,
-function,PyExceptionClass_Name,3.8,
-function,PyException_GetCause,3.2,
-function,PyException_GetContext,3.2,
-function,PyException_GetTraceback,3.2,
-function,PyException_SetCause,3.2,
-function,PyException_SetContext,3.2,
-function,PyException_SetTraceback,3.2,
-function,PyFile_FromFd,3.2,
-function,PyFile_GetLine,3.2,
-function,PyFile_WriteObject,3.2,
-function,PyFile_WriteString,3.2,
-var,PyFilter_Type,3.2,
-function,PyFloat_AsDouble,3.2,
-function,PyFloat_FromDouble,3.2,
-function,PyFloat_FromString,3.2,
-function,PyFloat_GetInfo,3.2,
-function,PyFloat_GetMax,3.2,
-function,PyFloat_GetMin,3.2,
-var,PyFloat_Type,3.2,
-type,PyFrameObject,3.2,
-function,PyFrame_GetCode,3.10,
-function,PyFrame_GetLineNumber,3.10,
-function,PyFrozenSet_New,3.2,
-var,PyFrozenSet_Type,3.2,
-function,PyGC_Collect,3.2,
-function,PyGC_Disable,3.10,
-function,PyGC_Enable,3.10,
-function,PyGC_IsEnabled,3.10,
-function,PyGILState_Ensure,3.2,
-function,PyGILState_GetThisThreadState,3.2,
-function,PyGILState_Release,3.2,
-type,PyGILState_STATE,3.2,
-type,PyGetSetDef,3.2,
-var,PyGetSetDescr_Type,3.2,
-function,PyImport_AddModule,3.2,
-function,PyImport_AddModuleObject,3.7,
-function,PyImport_AppendInittab,3.2,
-function,PyImport_ExecCodeModule,3.2,
-function,PyImport_ExecCodeModuleEx,3.2,
-function,PyImport_ExecCodeModuleObject,3.7,
-function,PyImport_ExecCodeModuleWithPathnames,3.2,
-function,PyImport_GetImporter,3.2,
-function,PyImport_GetMagicNumber,3.2,
-function,PyImport_GetMagicTag,3.2,
-function,PyImport_GetModule,3.8,
-function,PyImport_GetModuleDict,3.2,
-function,PyImport_Import,3.2,
-function,PyImport_ImportFrozenModule,3.2,
-function,PyImport_ImportFrozenModuleObject,3.7,
-function,PyImport_ImportModule,3.2,
-function,PyImport_ImportModuleLevel,3.2,
-function,PyImport_ImportModuleLevelObject,3.7,
-function,PyImport_ImportModuleNoBlock,3.2,
-function,PyImport_ReloadModule,3.2,
-function,PyIndex_Check,3.8,
-type,PyInterpreterState,3.2,
-function,PyInterpreterState_Clear,3.2,
-function,PyInterpreterState_Delete,3.2,
-function,PyInterpreterState_Get,3.9,
-function,PyInterpreterState_GetDict,3.8,
-function,PyInterpreterState_GetID,3.7,
-function,PyInterpreterState_New,3.2,
-function,PyIter_Check,3.8,
-function,PyIter_Next,3.2,
-function,PyIter_Send,3.10,
-var,PyListIter_Type,3.2,
-var,PyListRevIter_Type,3.2,
-function,PyList_Append,3.2,
-function,PyList_AsTuple,3.2,
-function,PyList_GetItem,3.2,
-function,PyList_GetSlice,3.2,
-function,PyList_Insert,3.2,
-function,PyList_New,3.2,
-function,PyList_Reverse,3.2,
-function,PyList_SetItem,3.2,
-function,PyList_SetSlice,3.2,
-function,PyList_Size,3.2,
-function,PyList_Sort,3.2,
-var,PyList_Type,3.2,
-type,PyLongObject,3.2,
-var,PyLongRangeIter_Type,3.2,
-function,PyLong_AsDouble,3.2,
-function,PyLong_AsLong,3.2,
-function,PyLong_AsLongAndOverflow,3.2,
-function,PyLong_AsLongLong,3.2,
-function,PyLong_AsLongLongAndOverflow,3.2,
-function,PyLong_AsSize_t,3.2,
-function,PyLong_AsSsize_t,3.2,
-function,PyLong_AsUnsignedLong,3.2,
-function,PyLong_AsUnsignedLongLong,3.2,
-function,PyLong_AsUnsignedLongLongMask,3.2,
-function,PyLong_AsUnsignedLongMask,3.2,
-function,PyLong_AsVoidPtr,3.2,
-function,PyLong_FromDouble,3.2,
-function,PyLong_FromLong,3.2,
-function,PyLong_FromLongLong,3.2,
-function,PyLong_FromSize_t,3.2,
-function,PyLong_FromSsize_t,3.2,
-function,PyLong_FromString,3.2,
-function,PyLong_FromUnsignedLong,3.2,
-function,PyLong_FromUnsignedLongLong,3.2,
-function,PyLong_FromVoidPtr,3.2,
-function,PyLong_GetInfo,3.2,
-var,PyLong_Type,3.2,
-var,PyMap_Type,3.2,
-function,PyMapping_Check,3.2,
-function,PyMapping_GetItemString,3.2,
-function,PyMapping_HasKey,3.2,
-function,PyMapping_HasKeyString,3.2,
-function,PyMapping_Items,3.2,
-function,PyMapping_Keys,3.2,
-function,PyMapping_Length,3.2,
-function,PyMapping_SetItemString,3.2,
-function,PyMapping_Size,3.2,
-function,PyMapping_Values,3.2,
-function,PyMem_Calloc,3.7,
-function,PyMem_Free,3.2,
-function,PyMem_Malloc,3.2,
-function,PyMem_Realloc,3.2,
-type,PyMemberDef,3.2,
-var,PyMemberDescr_Type,3.2,
-function,PyMemoryView_FromMemory,3.7,
-function,PyMemoryView_FromObject,3.2,
-function,PyMemoryView_GetContiguous,3.2,
-var,PyMemoryView_Type,3.2,
-type,PyMethodDef,3.2,
-var,PyMethodDescr_Type,3.2,
-type,PyModuleDef,3.2,
-type,PyModuleDef_Base,3.2,
-function,PyModuleDef_Init,3.5,
-var,PyModuleDef_Type,3.5,
-function,PyModule_AddFunctions,3.7,
-function,PyModule_AddIntConstant,3.2,
-function,PyModule_AddObject,3.2,
-function,PyModule_AddObjectRef,3.10,
-function,PyModule_AddStringConstant,3.2,
-function,PyModule_AddType,3.10,
-function,PyModule_Create2,3.2,
-function,PyModule_ExecDef,3.7,
-function,PyModule_FromDefAndSpec2,3.7,
-function,PyModule_GetDef,3.2,
-function,PyModule_GetDict,3.2,
-function,PyModule_GetFilename,3.2,
-function,PyModule_GetFilenameObject,3.2,
-function,PyModule_GetName,3.2,
-function,PyModule_GetNameObject,3.7,
-function,PyModule_GetState,3.2,
-function,PyModule_New,3.2,
-function,PyModule_NewObject,3.7,
-function,PyModule_SetDocString,3.7,
-var,PyModule_Type,3.2,
-function,PyNumber_Absolute,3.2,
-function,PyNumber_Add,3.2,
-function,PyNumber_And,3.2,
-function,PyNumber_AsSsize_t,3.2,
-function,PyNumber_Check,3.2,
-function,PyNumber_Divmod,3.2,
-function,PyNumber_Float,3.2,
-function,PyNumber_FloorDivide,3.2,
-function,PyNumber_InPlaceAdd,3.2,
-function,PyNumber_InPlaceAnd,3.2,
-function,PyNumber_InPlaceFloorDivide,3.2,
-function,PyNumber_InPlaceLshift,3.2,
-function,PyNumber_InPlaceMatrixMultiply,3.7,
-function,PyNumber_InPlaceMultiply,3.2,
-function,PyNumber_InPlaceOr,3.2,
-function,PyNumber_InPlacePower,3.2,
-function,PyNumber_InPlaceRemainder,3.2,
-function,PyNumber_InPlaceRshift,3.2,
-function,PyNumber_InPlaceSubtract,3.2,
-function,PyNumber_InPlaceTrueDivide,3.2,
-function,PyNumber_InPlaceXor,3.2,
-function,PyNumber_Index,3.2,
-function,PyNumber_Invert,3.2,
-function,PyNumber_Long,3.2,
-function,PyNumber_Lshift,3.2,
-function,PyNumber_MatrixMultiply,3.7,
-function,PyNumber_Multiply,3.2,
-function,PyNumber_Negative,3.2,
-function,PyNumber_Or,3.2,
-function,PyNumber_Positive,3.2,
-function,PyNumber_Power,3.2,
-function,PyNumber_Remainder,3.2,
-function,PyNumber_Rshift,3.2,
-function,PyNumber_Subtract,3.2,
-function,PyNumber_ToBase,3.2,
-function,PyNumber_TrueDivide,3.2,
-function,PyNumber_Xor,3.2,
-function,PyOS_AfterFork,3.2,on platforms with fork()
-function,PyOS_AfterFork_Child,3.7,on platforms with fork()
-function,PyOS_AfterFork_Parent,3.7,on platforms with fork()
-function,PyOS_BeforeFork,3.7,on platforms with fork()
-function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK
-function,PyOS_FSPath,3.6,
-var,PyOS_InputHook,3.2,
-function,PyOS_InterruptOccurred,3.2,
-function,PyOS_double_to_string,3.2,
-function,PyOS_getsig,3.2,
-function,PyOS_mystricmp,3.2,
-function,PyOS_mystrnicmp,3.2,
-function,PyOS_setsig,3.2,
-type,PyOS_sighandler_t,3.2,
-function,PyOS_snprintf,3.2,
-function,PyOS_string_to_double,3.2,
-function,PyOS_strtol,3.2,
-function,PyOS_strtoul,3.2,
-function,PyOS_vsnprintf,3.2,
-type,PyObject,3.2,
-function,PyObject_ASCII,3.2,
-function,PyObject_AsCharBuffer,3.2,
-function,PyObject_AsFileDescriptor,3.2,
-function,PyObject_AsReadBuffer,3.2,
-function,PyObject_AsWriteBuffer,3.2,
-function,PyObject_Bytes,3.2,
-function,PyObject_Call,3.2,
-function,PyObject_CallFunction,3.2,
-function,PyObject_CallFunctionObjArgs,3.2,
-function,PyObject_CallMethod,3.2,
-function,PyObject_CallMethodObjArgs,3.2,
-function,PyObject_CallNoArgs,3.10,
-function,PyObject_CallObject,3.2,
-function,PyObject_Calloc,3.7,
-function,PyObject_CheckReadBuffer,3.2,
-function,PyObject_ClearWeakRefs,3.2,
-function,PyObject_DelItem,3.2,
-function,PyObject_DelItemString,3.2,
-function,PyObject_Dir,3.2,
-function,PyObject_Format,3.2,
-function,PyObject_Free,3.2,
-function,PyObject_GC_Del,3.2,
-function,PyObject_GC_IsFinalized,3.9,
-function,PyObject_GC_IsTracked,3.9,
-function,PyObject_GC_Track,3.2,
-function,PyObject_GC_UnTrack,3.2,
-function,PyObject_GenericGetAttr,3.2,
-function,PyObject_GenericGetDict,3.10,
-function,PyObject_GenericSetAttr,3.2,
-function,PyObject_GenericSetDict,3.7,
-function,PyObject_GetAIter,3.10,
-function,PyObject_GetAttr,3.2,
-function,PyObject_GetAttrString,3.2,
-function,PyObject_GetItem,3.2,
-function,PyObject_GetIter,3.2,
-function,PyObject_HasAttr,3.2,
-function,PyObject_HasAttrString,3.2,
-function,PyObject_Hash,3.2,
-function,PyObject_HashNotImplemented,3.2,
-function,PyObject_Init,3.2,
-function,PyObject_InitVar,3.2,
-function,PyObject_IsInstance,3.2,
-function,PyObject_IsSubclass,3.2,
-function,PyObject_IsTrue,3.2,
-function,PyObject_Length,3.2,
-function,PyObject_Malloc,3.2,
-function,PyObject_Not,3.2,
-function,PyObject_Realloc,3.2,
-function,PyObject_Repr,3.2,
-function,PyObject_RichCompare,3.2,
-function,PyObject_RichCompareBool,3.2,
-function,PyObject_SelfIter,3.2,
-function,PyObject_SetAttr,3.2,
-function,PyObject_SetAttrString,3.2,
-function,PyObject_SetItem,3.2,
-function,PyObject_Size,3.2,
-function,PyObject_Str,3.2,
-function,PyObject_Type,3.2,
-var,PyProperty_Type,3.2,
-var,PyRangeIter_Type,3.2,
-var,PyRange_Type,3.2,
-var,PyReversed_Type,3.2,
-function,PySeqIter_New,3.2,
-var,PySeqIter_Type,3.2,
-function,PySequence_Check,3.2,
-function,PySequence_Concat,3.2,
-function,PySequence_Contains,3.2,
-function,PySequence_Count,3.2,
-function,PySequence_DelItem,3.2,
-function,PySequence_DelSlice,3.2,
-function,PySequence_Fast,3.2,
-function,PySequence_GetItem,3.2,
-function,PySequence_GetSlice,3.2,
-function,PySequence_In,3.2,
-function,PySequence_InPlaceConcat,3.2,
-function,PySequence_InPlaceRepeat,3.2,
-function,PySequence_Index,3.2,
-function,PySequence_Length,3.2,
-function,PySequence_List,3.2,
-function,PySequence_Repeat,3.2,
-function,PySequence_SetItem,3.2,
-function,PySequence_SetSlice,3.2,
-function,PySequence_Size,3.2,
-function,PySequence_Tuple,3.2,
-var,PySetIter_Type,3.2,
-function,PySet_Add,3.2,
-function,PySet_Clear,3.2,
-function,PySet_Contains,3.2,
-function,PySet_Discard,3.2,
-function,PySet_New,3.2,
-function,PySet_Pop,3.2,
-function,PySet_Size,3.2,
-var,PySet_Type,3.2,
-function,PySlice_AdjustIndices,3.7,
-function,PySlice_GetIndices,3.2,
-function,PySlice_GetIndicesEx,3.2,
-function,PySlice_New,3.2,
-var,PySlice_Type,3.2,
-function,PySlice_Unpack,3.7,
-function,PyState_AddModule,3.3,
-function,PyState_FindModule,3.2,
-function,PyState_RemoveModule,3.3,
-type,PyStructSequence_Desc,3.2,
-type,PyStructSequence_Field,3.2,
-function,PyStructSequence_GetItem,3.2,
-function,PyStructSequence_New,3.2,
-function,PyStructSequence_NewType,3.2,
-function,PyStructSequence_SetItem,3.2,
-var,PySuper_Type,3.2,
-function,PySys_AddWarnOption,3.2,
-function,PySys_AddWarnOptionUnicode,3.2,
-function,PySys_AddXOption,3.7,
-function,PySys_FormatStderr,3.2,
-function,PySys_FormatStdout,3.2,
-function,PySys_GetObject,3.2,
-function,PySys_GetXOptions,3.7,
-function,PySys_HasWarnOptions,3.2,
-function,PySys_ResetWarnOptions,3.2,
-function,PySys_SetArgv,3.2,
-function,PySys_SetArgvEx,3.2,
-function,PySys_SetObject,3.2,
-function,PySys_SetPath,3.2,
-function,PySys_WriteStderr,3.2,
-function,PySys_WriteStdout,3.2,
-type,PyThreadState,3.2,
-function,PyThreadState_Clear,3.2,
-function,PyThreadState_Delete,3.2,
-function,PyThreadState_Get,3.2,
-function,PyThreadState_GetDict,3.2,
-function,PyThreadState_GetFrame,3.10,
-function,PyThreadState_GetID,3.10,
-function,PyThreadState_GetInterpreter,3.10,
-function,PyThreadState_New,3.2,
-function,PyThreadState_SetAsyncExc,3.2,
-function,PyThreadState_Swap,3.2,
-function,PyThread_GetInfo,3.3,
-function,PyThread_ReInitTLS,3.2,
-function,PyThread_acquire_lock,3.2,
-function,PyThread_acquire_lock_timed,3.2,
-function,PyThread_allocate_lock,3.2,
-function,PyThread_create_key,3.2,
-function,PyThread_delete_key,3.2,
-function,PyThread_delete_key_value,3.2,
-function,PyThread_exit_thread,3.2,
-function,PyThread_free_lock,3.2,
-function,PyThread_get_key_value,3.2,
-function,PyThread_get_stacksize,3.2,
-function,PyThread_get_thread_ident,3.2,
-function,PyThread_get_thread_native_id,3.2,
-function,PyThread_init_thread,3.2,
-function,PyThread_release_lock,3.2,
-function,PyThread_set_key_value,3.2,
-function,PyThread_set_stacksize,3.2,
-function,PyThread_start_new_thread,3.2,
-function,PyThread_tss_alloc,3.7,
-function,PyThread_tss_create,3.7,
-function,PyThread_tss_delete,3.7,
-function,PyThread_tss_free,3.7,
-function,PyThread_tss_get,3.7,
-function,PyThread_tss_is_created,3.7,
-function,PyThread_tss_set,3.7,
-function,PyTraceBack_Here,3.2,
-function,PyTraceBack_Print,3.2,
-var,PyTraceBack_Type,3.2,
-var,PyTupleIter_Type,3.2,
-function,PyTuple_GetItem,3.2,
-function,PyTuple_GetSlice,3.2,
-function,PyTuple_New,3.2,
-function,PyTuple_Pack,3.2,
-function,PyTuple_SetItem,3.2,
-function,PyTuple_Size,3.2,
-var,PyTuple_Type,3.2,
-type,PyTypeObject,3.2,
-function,PyType_ClearCache,3.2,
-function,PyType_FromModuleAndSpec,3.10,
-function,PyType_FromSpec,3.2,
-function,PyType_FromSpecWithBases,3.3,
-function,PyType_GenericAlloc,3.2,
-function,PyType_GenericNew,3.2,
-function,PyType_GetFlags,3.2,
-function,PyType_GetModule,3.10,
-function,PyType_GetModuleState,3.10,
-function,PyType_GetSlot,3.4,
-function,PyType_IsSubtype,3.2,
-function,PyType_Modified,3.2,
-function,PyType_Ready,3.2,
-type,PyType_Slot,3.2,
-type,PyType_Spec,3.2,
-var,PyType_Type,3.2,
-function,PyUnicodeDecodeError_Create,3.2,
-function,PyUnicodeDecodeError_GetEncoding,3.2,
-function,PyUnicodeDecodeError_GetEnd,3.2,
-function,PyUnicodeDecodeError_GetObject,3.2,
-function,PyUnicodeDecodeError_GetReason,3.2,
-function,PyUnicodeDecodeError_GetStart,3.2,
-function,PyUnicodeDecodeError_SetEnd,3.2,
-function,PyUnicodeDecodeError_SetReason,3.2,
-function,PyUnicodeDecodeError_SetStart,3.2,
-function,PyUnicodeEncodeError_GetEncoding,3.2,
-function,PyUnicodeEncodeError_GetEnd,3.2,
-function,PyUnicodeEncodeError_GetObject,3.2,
-function,PyUnicodeEncodeError_GetReason,3.2,
-function,PyUnicodeEncodeError_GetStart,3.2,
-function,PyUnicodeEncodeError_SetEnd,3.2,
-function,PyUnicodeEncodeError_SetReason,3.2,
-function,PyUnicodeEncodeError_SetStart,3.2,
-var,PyUnicodeIter_Type,3.2,
-function,PyUnicodeTranslateError_GetEnd,3.2,
-function,PyUnicodeTranslateError_GetObject,3.2,
-function,PyUnicodeTranslateError_GetReason,3.2,
-function,PyUnicodeTranslateError_GetStart,3.2,
-function,PyUnicodeTranslateError_SetEnd,3.2,
-function,PyUnicodeTranslateError_SetReason,3.2,
-function,PyUnicodeTranslateError_SetStart,3.2,
-function,PyUnicode_Append,3.2,
-function,PyUnicode_AppendAndDel,3.2,
-function,PyUnicode_AsASCIIString,3.2,
-function,PyUnicode_AsCharmapString,3.2,
-function,PyUnicode_AsDecodedObject,3.2,
-function,PyUnicode_AsDecodedUnicode,3.2,
-function,PyUnicode_AsEncodedObject,3.2,
-function,PyUnicode_AsEncodedString,3.2,
-function,PyUnicode_AsEncodedUnicode,3.2,
-function,PyUnicode_AsLatin1String,3.2,
-function,PyUnicode_AsMBCSString,3.7,on Windows
-function,PyUnicode_AsRawUnicodeEscapeString,3.2,
-function,PyUnicode_AsUCS4,3.7,
-function,PyUnicode_AsUCS4Copy,3.7,
-function,PyUnicode_AsUTF16String,3.2,
-function,PyUnicode_AsUTF32String,3.2,
-function,PyUnicode_AsUTF8AndSize,3.10,
-function,PyUnicode_AsUTF8String,3.2,
-function,PyUnicode_AsUnicodeEscapeString,3.2,
-function,PyUnicode_AsWideChar,3.2,
-function,PyUnicode_AsWideCharString,3.7,
-function,PyUnicode_BuildEncodingMap,3.2,
-function,PyUnicode_Compare,3.2,
-function,PyUnicode_CompareWithASCIIString,3.2,
-function,PyUnicode_Concat,3.2,
-function,PyUnicode_Contains,3.2,
-function,PyUnicode_Count,3.2,
-function,PyUnicode_Decode,3.2,
-function,PyUnicode_DecodeASCII,3.2,
-function,PyUnicode_DecodeCharmap,3.2,
-function,PyUnicode_DecodeCodePageStateful,3.7,on Windows
-function,PyUnicode_DecodeFSDefault,3.2,
-function,PyUnicode_DecodeFSDefaultAndSize,3.2,
-function,PyUnicode_DecodeLatin1,3.2,
-function,PyUnicode_DecodeLocale,3.7,
-function,PyUnicode_DecodeLocaleAndSize,3.7,
-function,PyUnicode_DecodeMBCS,3.7,on Windows
-function,PyUnicode_DecodeMBCSStateful,3.7,on Windows
-function,PyUnicode_DecodeRawUnicodeEscape,3.2,
-function,PyUnicode_DecodeUTF16,3.2,
-function,PyUnicode_DecodeUTF16Stateful,3.2,
-function,PyUnicode_DecodeUTF32,3.2,
-function,PyUnicode_DecodeUTF32Stateful,3.2,
-function,PyUnicode_DecodeUTF7,3.2,
-function,PyUnicode_DecodeUTF7Stateful,3.2,
-function,PyUnicode_DecodeUTF8,3.2,
-function,PyUnicode_DecodeUTF8Stateful,3.2,
-function,PyUnicode_DecodeUnicodeEscape,3.2,
-function,PyUnicode_EncodeCodePage,3.7,on Windows
-function,PyUnicode_EncodeFSDefault,3.2,
-function,PyUnicode_EncodeLocale,3.7,
-function,PyUnicode_FSConverter,3.2,
-function,PyUnicode_FSDecoder,3.2,
-function,PyUnicode_Find,3.2,
-function,PyUnicode_FindChar,3.7,
-function,PyUnicode_Format,3.2,
-function,PyUnicode_FromEncodedObject,3.2,
-function,PyUnicode_FromFormat,3.2,
-function,PyUnicode_FromFormatV,3.2,
-function,PyUnicode_FromObject,3.2,
-function,PyUnicode_FromOrdinal,3.2,
-function,PyUnicode_FromString,3.2,
-function,PyUnicode_FromStringAndSize,3.2,
-function,PyUnicode_FromWideChar,3.2,
-function,PyUnicode_GetDefaultEncoding,3.2,
-function,PyUnicode_GetLength,3.7,
-function,PyUnicode_GetSize,3.2,
-function,PyUnicode_InternFromString,3.2,
-function,PyUnicode_InternImmortal,3.2,
-function,PyUnicode_InternInPlace,3.2,
-function,PyUnicode_IsIdentifier,3.2,
-function,PyUnicode_Join,3.2,
-function,PyUnicode_Partition,3.2,
-function,PyUnicode_RPartition,3.2,
-function,PyUnicode_RSplit,3.2,
-function,PyUnicode_ReadChar,3.7,
-function,PyUnicode_Replace,3.2,
-function,PyUnicode_Resize,3.2,
-function,PyUnicode_RichCompare,3.2,
-function,PyUnicode_Split,3.2,
-function,PyUnicode_Splitlines,3.2,
-function,PyUnicode_Substring,3.7,
-function,PyUnicode_Tailmatch,3.2,
-function,PyUnicode_Translate,3.2,
-var,PyUnicode_Type,3.2,
-function,PyUnicode_WriteChar,3.7,
-type,PyVarObject,3.2,
-type,PyWeakReference,3.2,
-function,PyWeakref_GetObject,3.2,
-function,PyWeakref_NewProxy,3.2,
-function,PyWeakref_NewRef,3.2,
-var,PyWrapperDescr_Type,3.2,
-function,PyWrapper_New,3.2,
-var,PyZip_Type,3.2,
-function,Py_AddPendingCall,3.2,
-function,Py_AtExit,3.2,
-macro,Py_BEGIN_ALLOW_THREADS,3.2,
-macro,Py_BLOCK_THREADS,3.2,
-function,Py_BuildValue,3.2,
-function,Py_BytesMain,3.8,
-function,Py_CompileString,3.2,
-function,Py_DecRef,3.2,
-function,Py_DecodeLocale,3.7,
-macro,Py_END_ALLOW_THREADS,3.2,
-function,Py_EncodeLocale,3.7,
-function,Py_EndInterpreter,3.2,
-function,Py_EnterRecursiveCall,3.9,
-function,Py_Exit,3.2,
-function,Py_FatalError,3.2,
-var,Py_FileSystemDefaultEncodeErrors,3.10,
-var,Py_FileSystemDefaultEncoding,3.2,
-function,Py_Finalize,3.2,
-function,Py_FinalizeEx,3.6,
-function,Py_GenericAlias,3.9,
-var,Py_GenericAliasType,3.9,
-function,Py_GetBuildInfo,3.2,
-function,Py_GetCompiler,3.2,
-function,Py_GetCopyright,3.2,
-function,Py_GetExecPrefix,3.2,
-function,Py_GetPath,3.2,
-function,Py_GetPlatform,3.2,
-function,Py_GetPrefix,3.2,
-function,Py_GetProgramFullPath,3.2,
-function,Py_GetProgramName,3.2,
-function,Py_GetPythonHome,3.2,
-function,Py_GetRecursionLimit,3.2,
-function,Py_GetVersion,3.2,
-var,Py_HasFileSystemDefaultEncoding,3.2,
-function,Py_IncRef,3.2,
-function,Py_Initialize,3.2,
-function,Py_InitializeEx,3.2,
-function,Py_Is,3.10,
-function,Py_IsFalse,3.10,
-function,Py_IsInitialized,3.2,
-function,Py_IsNone,3.10,
-function,Py_IsTrue,3.10,
-function,Py_LeaveRecursiveCall,3.9,
-function,Py_Main,3.2,
-function,Py_MakePendingCalls,3.2,
-function,Py_NewInterpreter,3.2,
-function,Py_NewRef,3.10,
-function,Py_ReprEnter,3.2,
-function,Py_ReprLeave,3.2,
-function,Py_SetPath,3.7,
-function,Py_SetProgramName,3.2,
-function,Py_SetPythonHome,3.2,
-function,Py_SetRecursionLimit,3.2,
-type,Py_UCS4,3.2,
-macro,Py_UNBLOCK_THREADS,3.2,
-var,Py_UTF8Mode,3.8,
-function,Py_VaBuildValue,3.2,
-function,Py_XNewRef,3.10,
-type,Py_intptr_t,3.2,
-type,Py_ssize_t,3.2,
-type,Py_uintptr_t,3.2,
-type,allocfunc,3.2,
-type,binaryfunc,3.2,
-type,descrgetfunc,3.2,
-type,descrsetfunc,3.2,
-type,destructor,3.2,
-type,getattrfunc,3.2,
-type,getattrofunc,3.2,
-type,getiterfunc,3.2,
-type,getter,3.2,
-type,hashfunc,3.2,
-type,initproc,3.2,
-type,inquiry,3.2,
-type,iternextfunc,3.2,
-type,lenfunc,3.2,
-type,newfunc,3.2,
-type,objobjargproc,3.2,
-type,objobjproc,3.2,
-type,reprfunc,3.2,
-type,richcmpfunc,3.2,
-type,setattrfunc,3.2,
-type,setattrofunc,3.2,
-type,setter,3.2,
-type,ssizeargfunc,3.2,
-type,ssizeobjargproc,3.2,
-type,ssizessizeargfunc,3.2,
-type,ssizessizeobjargproc,3.2,
-type,symtable,3.2,
-type,ternaryfunc,3.2,
-type,traverseproc,3.2,
-type,unaryfunc,3.2,
-type,visitproc,3.2,
+role,name,added,ifdef_note,struct_abi_kind
+function,PyAIter_Check,3.10,,
+function,PyArg_Parse,3.2,,
+function,PyArg_ParseTuple,3.2,,
+function,PyArg_ParseTupleAndKeywords,3.2,,
+function,PyArg_UnpackTuple,3.2,,
+function,PyArg_VaParse,3.2,,
+function,PyArg_VaParseTupleAndKeywords,3.2,,
+function,PyArg_ValidateKeywordArguments,3.2,,
+var,PyBaseObject_Type,3.2,,
+function,PyBool_FromLong,3.2,,
+var,PyBool_Type,3.2,,
+var,PyByteArrayIter_Type,3.2,,
+function,PyByteArray_AsString,3.2,,
+function,PyByteArray_Concat,3.2,,
+function,PyByteArray_FromObject,3.2,,
+function,PyByteArray_FromStringAndSize,3.2,,
+function,PyByteArray_Resize,3.2,,
+function,PyByteArray_Size,3.2,,
+var,PyByteArray_Type,3.2,,
+var,PyBytesIter_Type,3.2,,
+function,PyBytes_AsString,3.2,,
+function,PyBytes_AsStringAndSize,3.2,,
+function,PyBytes_Concat,3.2,,
+function,PyBytes_ConcatAndDel,3.2,,
+function,PyBytes_DecodeEscape,3.2,,
+function,PyBytes_FromFormat,3.2,,
+function,PyBytes_FromFormatV,3.2,,
+function,PyBytes_FromObject,3.2,,
+function,PyBytes_FromString,3.2,,
+function,PyBytes_FromStringAndSize,3.2,,
+function,PyBytes_Repr,3.2,,
+function,PyBytes_Size,3.2,,
+var,PyBytes_Type,3.2,,
+type,PyCFunction,3.2,,
+type,PyCFunctionWithKeywords,3.2,,
+function,PyCFunction_Call,3.2,,
+function,PyCFunction_GetFlags,3.2,,
+function,PyCFunction_GetFunction,3.2,,
+function,PyCFunction_GetSelf,3.2,,
+function,PyCFunction_New,3.4,,
+function,PyCFunction_NewEx,3.2,,
+var,PyCFunction_Type,3.2,,
+function,PyCMethod_New,3.9,,
+function,PyCallIter_New,3.2,,
+var,PyCallIter_Type,3.2,,
+function,PyCallable_Check,3.2,,
+type,PyCapsule_Destructor,3.2,,
+function,PyCapsule_GetContext,3.2,,
+function,PyCapsule_GetDestructor,3.2,,
+function,PyCapsule_GetName,3.2,,
+function,PyCapsule_GetPointer,3.2,,
+function,PyCapsule_Import,3.2,,
+function,PyCapsule_IsValid,3.2,,
+function,PyCapsule_New,3.2,,
+function,PyCapsule_SetContext,3.2,,
+function,PyCapsule_SetDestructor,3.2,,
+function,PyCapsule_SetName,3.2,,
+function,PyCapsule_SetPointer,3.2,,
+var,PyCapsule_Type,3.2,,
+var,PyClassMethodDescr_Type,3.2,,
+function,PyCodec_BackslashReplaceErrors,3.2,,
+function,PyCodec_Decode,3.2,,
+function,PyCodec_Decoder,3.2,,
+function,PyCodec_Encode,3.2,,
+function,PyCodec_Encoder,3.2,,
+function,PyCodec_IgnoreErrors,3.2,,
+function,PyCodec_IncrementalDecoder,3.2,,
+function,PyCodec_IncrementalEncoder,3.2,,
+function,PyCodec_KnownEncoding,3.2,,
+function,PyCodec_LookupError,3.2,,
+function,PyCodec_NameReplaceErrors,3.7,,
+function,PyCodec_Register,3.2,,
+function,PyCodec_RegisterError,3.2,,
+function,PyCodec_ReplaceErrors,3.2,,
+function,PyCodec_StreamReader,3.2,,
+function,PyCodec_StreamWriter,3.2,,
+function,PyCodec_StrictErrors,3.2,,
+function,PyCodec_Unregister,3.10,,
+function,PyCodec_XMLCharRefReplaceErrors,3.2,,
+function,PyComplex_FromDoubles,3.2,,
+function,PyComplex_ImagAsDouble,3.2,,
+function,PyComplex_RealAsDouble,3.2,,
+var,PyComplex_Type,3.2,,
+function,PyDescr_NewClassMethod,3.2,,
+function,PyDescr_NewGetSet,3.2,,
+function,PyDescr_NewMember,3.2,,
+function,PyDescr_NewMethod,3.2,,
+var,PyDictItems_Type,3.2,,
+var,PyDictIterItem_Type,3.2,,
+var,PyDictIterKey_Type,3.2,,
+var,PyDictIterValue_Type,3.2,,
+var,PyDictKeys_Type,3.2,,
+function,PyDictProxy_New,3.2,,
+var,PyDictProxy_Type,3.2,,
+var,PyDictRevIterItem_Type,3.8,,
+var,PyDictRevIterKey_Type,3.8,,
+var,PyDictRevIterValue_Type,3.8,,
+var,PyDictValues_Type,3.2,,
+function,PyDict_Clear,3.2,,
+function,PyDict_Contains,3.2,,
+function,PyDict_Copy,3.2,,
+function,PyDict_DelItem,3.2,,
+function,PyDict_DelItemString,3.2,,
+function,PyDict_GetItem,3.2,,
+function,PyDict_GetItemString,3.2,,
+function,PyDict_GetItemWithError,3.2,,
+function,PyDict_Items,3.2,,
+function,PyDict_Keys,3.2,,
+function,PyDict_Merge,3.2,,
+function,PyDict_MergeFromSeq2,3.2,,
+function,PyDict_New,3.2,,
+function,PyDict_Next,3.2,,
+function,PyDict_SetItem,3.2,,
+function,PyDict_SetItemString,3.2,,
+function,PyDict_Size,3.2,,
+var,PyDict_Type,3.2,,
+function,PyDict_Update,3.2,,
+function,PyDict_Values,3.2,,
+var,PyEllipsis_Type,3.2,,
+var,PyEnum_Type,3.2,,
+function,PyErr_BadArgument,3.2,,
+function,PyErr_BadInternalCall,3.2,,
+function,PyErr_CheckSignals,3.2,,
+function,PyErr_Clear,3.2,,
+function,PyErr_Display,3.2,,
+function,PyErr_ExceptionMatches,3.2,,
+function,PyErr_Fetch,3.2,,
+function,PyErr_Format,3.2,,
+function,PyErr_FormatV,3.5,,
+function,PyErr_GetExcInfo,3.7,,
+function,PyErr_GivenExceptionMatches,3.2,,
+function,PyErr_NewException,3.2,,
+function,PyErr_NewExceptionWithDoc,3.2,,
+function,PyErr_NoMemory,3.2,,
+function,PyErr_NormalizeException,3.2,,
+function,PyErr_Occurred,3.2,,
+function,PyErr_Print,3.2,,
+function,PyErr_PrintEx,3.2,,
+function,PyErr_ProgramText,3.2,,
+function,PyErr_ResourceWarning,3.6,,
+function,PyErr_Restore,3.2,,
+function,PyErr_SetExcFromWindowsErr,3.7,on Windows,
+function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows,
+function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows,
+function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows,
+function,PyErr_SetExcInfo,3.7,,
+function,PyErr_SetFromErrno,3.2,,
+function,PyErr_SetFromErrnoWithFilename,3.2,,
+function,PyErr_SetFromErrnoWithFilenameObject,3.2,,
+function,PyErr_SetFromErrnoWithFilenameObjects,3.7,,
+function,PyErr_SetFromWindowsErr,3.7,on Windows,
+function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows,
+function,PyErr_SetImportError,3.7,,
+function,PyErr_SetImportErrorSubclass,3.6,,
+function,PyErr_SetInterrupt,3.2,,
+function,PyErr_SetInterruptEx,3.10,,
+function,PyErr_SetNone,3.2,,
+function,PyErr_SetObject,3.2,,
+function,PyErr_SetString,3.2,,
+function,PyErr_SyntaxLocation,3.2,,
+function,PyErr_SyntaxLocationEx,3.7,,
+function,PyErr_WarnEx,3.2,,
+function,PyErr_WarnExplicit,3.2,,
+function,PyErr_WarnFormat,3.2,,
+function,PyErr_WriteUnraisable,3.2,,
+function,PyEval_AcquireLock,3.2,,
+function,PyEval_AcquireThread,3.2,,
+function,PyEval_CallFunction,3.2,,
+function,PyEval_CallMethod,3.2,,
+function,PyEval_CallObjectWithKeywords,3.2,,
+function,PyEval_EvalCode,3.2,,
+function,PyEval_EvalCodeEx,3.2,,
+function,PyEval_EvalFrame,3.2,,
+function,PyEval_EvalFrameEx,3.2,,
+function,PyEval_GetBuiltins,3.2,,
+function,PyEval_GetFrame,3.2,,
+function,PyEval_GetFuncDesc,3.2,,
+function,PyEval_GetFuncName,3.2,,
+function,PyEval_GetGlobals,3.2,,
+function,PyEval_GetLocals,3.2,,
+function,PyEval_InitThreads,3.2,,
+function,PyEval_ReleaseLock,3.2,,
+function,PyEval_ReleaseThread,3.2,,
+function,PyEval_RestoreThread,3.2,,
+function,PyEval_SaveThread,3.2,,
+function,PyEval_ThreadsInitialized,3.2,,
+var,PyExc_ArithmeticError,3.2,,
+var,PyExc_AssertionError,3.2,,
+var,PyExc_AttributeError,3.2,,
+var,PyExc_BaseException,3.2,,
+var,PyExc_BlockingIOError,3.7,,
+var,PyExc_BrokenPipeError,3.7,,
+var,PyExc_BufferError,3.2,,
+var,PyExc_BytesWarning,3.2,,
+var,PyExc_ChildProcessError,3.7,,
+var,PyExc_ConnectionAbortedError,3.7,,
+var,PyExc_ConnectionError,3.7,,
+var,PyExc_ConnectionRefusedError,3.7,,
+var,PyExc_ConnectionResetError,3.7,,
+var,PyExc_DeprecationWarning,3.2,,
+var,PyExc_EOFError,3.2,,
+var,PyExc_EncodingWarning,3.10,,
+var,PyExc_EnvironmentError,3.2,,
+var,PyExc_Exception,3.2,,
+var,PyExc_FileExistsError,3.7,,
+var,PyExc_FileNotFoundError,3.7,,
+var,PyExc_FloatingPointError,3.2,,
+var,PyExc_FutureWarning,3.2,,
+var,PyExc_GeneratorExit,3.2,,
+var,PyExc_IOError,3.2,,
+var,PyExc_ImportError,3.2,,
+var,PyExc_ImportWarning,3.2,,
+var,PyExc_IndentationError,3.2,,
+var,PyExc_IndexError,3.2,,
+var,PyExc_InterruptedError,3.7,,
+var,PyExc_IsADirectoryError,3.7,,
+var,PyExc_KeyError,3.2,,
+var,PyExc_KeyboardInterrupt,3.2,,
+var,PyExc_LookupError,3.2,,
+var,PyExc_MemoryError,3.2,,
+var,PyExc_ModuleNotFoundError,3.6,,
+var,PyExc_NameError,3.2,,
+var,PyExc_NotADirectoryError,3.7,,
+var,PyExc_NotImplementedError,3.2,,
+var,PyExc_OSError,3.2,,
+var,PyExc_OverflowError,3.2,,
+var,PyExc_PendingDeprecationWarning,3.2,,
+var,PyExc_PermissionError,3.7,,
+var,PyExc_ProcessLookupError,3.7,,
+var,PyExc_RecursionError,3.7,,
+var,PyExc_ReferenceError,3.2,,
+var,PyExc_ResourceWarning,3.7,,
+var,PyExc_RuntimeError,3.2,,
+var,PyExc_RuntimeWarning,3.2,,
+var,PyExc_StopAsyncIteration,3.7,,
+var,PyExc_StopIteration,3.2,,
+var,PyExc_SyntaxError,3.2,,
+var,PyExc_SyntaxWarning,3.2,,
+var,PyExc_SystemError,3.2,,
+var,PyExc_SystemExit,3.2,,
+var,PyExc_TabError,3.2,,
+var,PyExc_TimeoutError,3.7,,
+var,PyExc_TypeError,3.2,,
+var,PyExc_UnboundLocalError,3.2,,
+var,PyExc_UnicodeDecodeError,3.2,,
+var,PyExc_UnicodeEncodeError,3.2,,
+var,PyExc_UnicodeError,3.2,,
+var,PyExc_UnicodeTranslateError,3.2,,
+var,PyExc_UnicodeWarning,3.2,,
+var,PyExc_UserWarning,3.2,,
+var,PyExc_ValueError,3.2,,
+var,PyExc_Warning,3.2,,
+var,PyExc_WindowsError,3.7,on Windows,
+var,PyExc_ZeroDivisionError,3.2,,
+function,PyExceptionClass_Name,3.8,,
+function,PyException_GetCause,3.2,,
+function,PyException_GetContext,3.2,,
+function,PyException_GetTraceback,3.2,,
+function,PyException_SetCause,3.2,,
+function,PyException_SetContext,3.2,,
+function,PyException_SetTraceback,3.2,,
+function,PyFile_FromFd,3.2,,
+function,PyFile_GetLine,3.2,,
+function,PyFile_WriteObject,3.2,,
+function,PyFile_WriteString,3.2,,
+var,PyFilter_Type,3.2,,
+function,PyFloat_AsDouble,3.2,,
+function,PyFloat_FromDouble,3.2,,
+function,PyFloat_FromString,3.2,,
+function,PyFloat_GetInfo,3.2,,
+function,PyFloat_GetMax,3.2,,
+function,PyFloat_GetMin,3.2,,
+var,PyFloat_Type,3.2,,
+type,PyFrameObject,3.2,,opaque
+function,PyFrame_GetCode,3.10,,
+function,PyFrame_GetLineNumber,3.10,,
+function,PyFrozenSet_New,3.2,,
+var,PyFrozenSet_Type,3.2,,
+function,PyGC_Collect,3.2,,
+function,PyGC_Disable,3.10,,
+function,PyGC_Enable,3.10,,
+function,PyGC_IsEnabled,3.10,,
+function,PyGILState_Ensure,3.2,,
+function,PyGILState_GetThisThreadState,3.2,,
+function,PyGILState_Release,3.2,,
+type,PyGILState_STATE,3.2,,
+type,PyGetSetDef,3.2,,full-abi
+var,PyGetSetDescr_Type,3.2,,
+function,PyImport_AddModule,3.2,,
+function,PyImport_AddModuleObject,3.7,,
+function,PyImport_AppendInittab,3.2,,
+function,PyImport_ExecCodeModule,3.2,,
+function,PyImport_ExecCodeModuleEx,3.2,,
+function,PyImport_ExecCodeModuleObject,3.7,,
+function,PyImport_ExecCodeModuleWithPathnames,3.2,,
+function,PyImport_GetImporter,3.2,,
+function,PyImport_GetMagicNumber,3.2,,
+function,PyImport_GetMagicTag,3.2,,
+function,PyImport_GetModule,3.8,,
+function,PyImport_GetModuleDict,3.2,,
+function,PyImport_Import,3.2,,
+function,PyImport_ImportFrozenModule,3.2,,
+function,PyImport_ImportFrozenModuleObject,3.7,,
+function,PyImport_ImportModule,3.2,,
+function,PyImport_ImportModuleLevel,3.2,,
+function,PyImport_ImportModuleLevelObject,3.7,,
+function,PyImport_ImportModuleNoBlock,3.2,,
+function,PyImport_ReloadModule,3.2,,
+function,PyIndex_Check,3.8,,
+type,PyInterpreterState,3.2,,opaque
+function,PyInterpreterState_Clear,3.2,,
+function,PyInterpreterState_Delete,3.2,,
+function,PyInterpreterState_Get,3.9,,
+function,PyInterpreterState_GetDict,3.8,,
+function,PyInterpreterState_GetID,3.7,,
+function,PyInterpreterState_New,3.2,,
+function,PyIter_Check,3.8,,
+function,PyIter_Next,3.2,,
+function,PyIter_Send,3.10,,
+var,PyListIter_Type,3.2,,
+var,PyListRevIter_Type,3.2,,
+function,PyList_Append,3.2,,
+function,PyList_AsTuple,3.2,,
+function,PyList_GetItem,3.2,,
+function,PyList_GetSlice,3.2,,
+function,PyList_Insert,3.2,,
+function,PyList_New,3.2,,
+function,PyList_Reverse,3.2,,
+function,PyList_SetItem,3.2,,
+function,PyList_SetSlice,3.2,,
+function,PyList_Size,3.2,,
+function,PyList_Sort,3.2,,
+var,PyList_Type,3.2,,
+type,PyLongObject,3.2,,opaque
+var,PyLongRangeIter_Type,3.2,,
+function,PyLong_AsDouble,3.2,,
+function,PyLong_AsLong,3.2,,
+function,PyLong_AsLongAndOverflow,3.2,,
+function,PyLong_AsLongLong,3.2,,
+function,PyLong_AsLongLongAndOverflow,3.2,,
+function,PyLong_AsSize_t,3.2,,
+function,PyLong_AsSsize_t,3.2,,
+function,PyLong_AsUnsignedLong,3.2,,
+function,PyLong_AsUnsignedLongLong,3.2,,
+function,PyLong_AsUnsignedLongLongMask,3.2,,
+function,PyLong_AsUnsignedLongMask,3.2,,
+function,PyLong_AsVoidPtr,3.2,,
+function,PyLong_FromDouble,3.2,,
+function,PyLong_FromLong,3.2,,
+function,PyLong_FromLongLong,3.2,,
+function,PyLong_FromSize_t,3.2,,
+function,PyLong_FromSsize_t,3.2,,
+function,PyLong_FromString,3.2,,
+function,PyLong_FromUnsignedLong,3.2,,
+function,PyLong_FromUnsignedLongLong,3.2,,
+function,PyLong_FromVoidPtr,3.2,,
+function,PyLong_GetInfo,3.2,,
+var,PyLong_Type,3.2,,
+var,PyMap_Type,3.2,,
+function,PyMapping_Check,3.2,,
+function,PyMapping_GetItemString,3.2,,
+function,PyMapping_HasKey,3.2,,
+function,PyMapping_HasKeyString,3.2,,
+function,PyMapping_Items,3.2,,
+function,PyMapping_Keys,3.2,,
+function,PyMapping_Length,3.2,,
+function,PyMapping_SetItemString,3.2,,
+function,PyMapping_Size,3.2,,
+function,PyMapping_Values,3.2,,
+function,PyMem_Calloc,3.7,,
+function,PyMem_Free,3.2,,
+function,PyMem_Malloc,3.2,,
+function,PyMem_Realloc,3.2,,
+type,PyMemberDef,3.2,,full-abi
+var,PyMemberDescr_Type,3.2,,
+function,PyMemoryView_FromMemory,3.7,,
+function,PyMemoryView_FromObject,3.2,,
+function,PyMemoryView_GetContiguous,3.2,,
+var,PyMemoryView_Type,3.2,,
+type,PyMethodDef,3.2,,full-abi
+var,PyMethodDescr_Type,3.2,,
+type,PyModuleDef,3.2,,full-abi
+type,PyModuleDef_Base,3.2,,full-abi
+function,PyModuleDef_Init,3.5,,
+var,PyModuleDef_Type,3.5,,
+function,PyModule_AddFunctions,3.7,,
+function,PyModule_AddIntConstant,3.2,,
+function,PyModule_AddObject,3.2,,
+function,PyModule_AddObjectRef,3.10,,
+function,PyModule_AddStringConstant,3.2,,
+function,PyModule_AddType,3.10,,
+function,PyModule_Create2,3.2,,
+function,PyModule_ExecDef,3.7,,
+function,PyModule_FromDefAndSpec2,3.7,,
+function,PyModule_GetDef,3.2,,
+function,PyModule_GetDict,3.2,,
+function,PyModule_GetFilename,3.2,,
+function,PyModule_GetFilenameObject,3.2,,
+function,PyModule_GetName,3.2,,
+function,PyModule_GetNameObject,3.7,,
+function,PyModule_GetState,3.2,,
+function,PyModule_New,3.2,,
+function,PyModule_NewObject,3.7,,
+function,PyModule_SetDocString,3.7,,
+var,PyModule_Type,3.2,,
+function,PyNumber_Absolute,3.2,,
+function,PyNumber_Add,3.2,,
+function,PyNumber_And,3.2,,
+function,PyNumber_AsSsize_t,3.2,,
+function,PyNumber_Check,3.2,,
+function,PyNumber_Divmod,3.2,,
+function,PyNumber_Float,3.2,,
+function,PyNumber_FloorDivide,3.2,,
+function,PyNumber_InPlaceAdd,3.2,,
+function,PyNumber_InPlaceAnd,3.2,,
+function,PyNumber_InPlaceFloorDivide,3.2,,
+function,PyNumber_InPlaceLshift,3.2,,
+function,PyNumber_InPlaceMatrixMultiply,3.7,,
+function,PyNumber_InPlaceMultiply,3.2,,
+function,PyNumber_InPlaceOr,3.2,,
+function,PyNumber_InPlacePower,3.2,,
+function,PyNumber_InPlaceRemainder,3.2,,
+function,PyNumber_InPlaceRshift,3.2,,
+function,PyNumber_InPlaceSubtract,3.2,,
+function,PyNumber_InPlaceTrueDivide,3.2,,
+function,PyNumber_InPlaceXor,3.2,,
+function,PyNumber_Index,3.2,,
+function,PyNumber_Invert,3.2,,
+function,PyNumber_Long,3.2,,
+function,PyNumber_Lshift,3.2,,
+function,PyNumber_MatrixMultiply,3.7,,
+function,PyNumber_Multiply,3.2,,
+function,PyNumber_Negative,3.2,,
+function,PyNumber_Or,3.2,,
+function,PyNumber_Positive,3.2,,
+function,PyNumber_Power,3.2,,
+function,PyNumber_Remainder,3.2,,
+function,PyNumber_Rshift,3.2,,
+function,PyNumber_Subtract,3.2,,
+function,PyNumber_ToBase,3.2,,
+function,PyNumber_TrueDivide,3.2,,
+function,PyNumber_Xor,3.2,,
+function,PyOS_AfterFork,3.2,on platforms with fork(),
+function,PyOS_AfterFork_Child,3.7,on platforms with fork(),
+function,PyOS_AfterFork_Parent,3.7,on platforms with fork(),
+function,PyOS_BeforeFork,3.7,on platforms with fork(),
+function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK,
+function,PyOS_FSPath,3.6,,
+var,PyOS_InputHook,3.2,,
+function,PyOS_InterruptOccurred,3.2,,
+function,PyOS_double_to_string,3.2,,
+function,PyOS_getsig,3.2,,
+function,PyOS_mystricmp,3.2,,
+function,PyOS_mystrnicmp,3.2,,
+function,PyOS_setsig,3.2,,
+type,PyOS_sighandler_t,3.2,,
+function,PyOS_snprintf,3.2,,
+function,PyOS_string_to_double,3.2,,
+function,PyOS_strtol,3.2,,
+function,PyOS_strtoul,3.2,,
+function,PyOS_vsnprintf,3.2,,
+type,PyObject,3.2,,members
+member,PyObject.ob_refcnt,3.2,,
+member,PyObject.ob_type,3.2,,
+function,PyObject_ASCII,3.2,,
+function,PyObject_AsCharBuffer,3.2,,
+function,PyObject_AsFileDescriptor,3.2,,
+function,PyObject_AsReadBuffer,3.2,,
+function,PyObject_AsWriteBuffer,3.2,,
+function,PyObject_Bytes,3.2,,
+function,PyObject_Call,3.2,,
+function,PyObject_CallFunction,3.2,,
+function,PyObject_CallFunctionObjArgs,3.2,,
+function,PyObject_CallMethod,3.2,,
+function,PyObject_CallMethodObjArgs,3.2,,
+function,PyObject_CallNoArgs,3.10,,
+function,PyObject_CallObject,3.2,,
+function,PyObject_Calloc,3.7,,
+function,PyObject_CheckReadBuffer,3.2,,
+function,PyObject_ClearWeakRefs,3.2,,
+function,PyObject_DelItem,3.2,,
+function,PyObject_DelItemString,3.2,,
+function,PyObject_Dir,3.2,,
+function,PyObject_Format,3.2,,
+function,PyObject_Free,3.2,,
+function,PyObject_GC_Del,3.2,,
+function,PyObject_GC_IsFinalized,3.9,,
+function,PyObject_GC_IsTracked,3.9,,
+function,PyObject_GC_Track,3.2,,
+function,PyObject_GC_UnTrack,3.2,,
+function,PyObject_GenericGetAttr,3.2,,
+function,PyObject_GenericGetDict,3.10,,
+function,PyObject_GenericSetAttr,3.2,,
+function,PyObject_GenericSetDict,3.7,,
+function,PyObject_GetAIter,3.10,,
+function,PyObject_GetAttr,3.2,,
+function,PyObject_GetAttrString,3.2,,
+function,PyObject_GetItem,3.2,,
+function,PyObject_GetIter,3.2,,
+function,PyObject_HasAttr,3.2,,
+function,PyObject_HasAttrString,3.2,,
+function,PyObject_Hash,3.2,,
+function,PyObject_HashNotImplemented,3.2,,
+function,PyObject_Init,3.2,,
+function,PyObject_InitVar,3.2,,
+function,PyObject_IsInstance,3.2,,
+function,PyObject_IsSubclass,3.2,,
+function,PyObject_IsTrue,3.2,,
+function,PyObject_Length,3.2,,
+function,PyObject_Malloc,3.2,,
+function,PyObject_Not,3.2,,
+function,PyObject_Realloc,3.2,,
+function,PyObject_Repr,3.2,,
+function,PyObject_RichCompare,3.2,,
+function,PyObject_RichCompareBool,3.2,,
+function,PyObject_SelfIter,3.2,,
+function,PyObject_SetAttr,3.2,,
+function,PyObject_SetAttrString,3.2,,
+function,PyObject_SetItem,3.2,,
+function,PyObject_Size,3.2,,
+function,PyObject_Str,3.2,,
+function,PyObject_Type,3.2,,
+var,PyProperty_Type,3.2,,
+var,PyRangeIter_Type,3.2,,
+var,PyRange_Type,3.2,,
+var,PyReversed_Type,3.2,,
+function,PySeqIter_New,3.2,,
+var,PySeqIter_Type,3.2,,
+function,PySequence_Check,3.2,,
+function,PySequence_Concat,3.2,,
+function,PySequence_Contains,3.2,,
+function,PySequence_Count,3.2,,
+function,PySequence_DelItem,3.2,,
+function,PySequence_DelSlice,3.2,,
+function,PySequence_Fast,3.2,,
+function,PySequence_GetItem,3.2,,
+function,PySequence_GetSlice,3.2,,
+function,PySequence_In,3.2,,
+function,PySequence_InPlaceConcat,3.2,,
+function,PySequence_InPlaceRepeat,3.2,,
+function,PySequence_Index,3.2,,
+function,PySequence_Length,3.2,,
+function,PySequence_List,3.2,,
+function,PySequence_Repeat,3.2,,
+function,PySequence_SetItem,3.2,,
+function,PySequence_SetSlice,3.2,,
+function,PySequence_Size,3.2,,
+function,PySequence_Tuple,3.2,,
+var,PySetIter_Type,3.2,,
+function,PySet_Add,3.2,,
+function,PySet_Clear,3.2,,
+function,PySet_Contains,3.2,,
+function,PySet_Discard,3.2,,
+function,PySet_New,3.2,,
+function,PySet_Pop,3.2,,
+function,PySet_Size,3.2,,
+var,PySet_Type,3.2,,
+function,PySlice_AdjustIndices,3.7,,
+function,PySlice_GetIndices,3.2,,
+function,PySlice_GetIndicesEx,3.2,,
+function,PySlice_New,3.2,,
+var,PySlice_Type,3.2,,
+function,PySlice_Unpack,3.7,,
+function,PyState_AddModule,3.3,,
+function,PyState_FindModule,3.2,,
+function,PyState_RemoveModule,3.3,,
+type,PyStructSequence_Desc,3.2,,full-abi
+type,PyStructSequence_Field,3.2,,full-abi
+function,PyStructSequence_GetItem,3.2,,
+function,PyStructSequence_New,3.2,,
+function,PyStructSequence_NewType,3.2,,
+function,PyStructSequence_SetItem,3.2,,
+var,PySuper_Type,3.2,,
+function,PySys_AddWarnOption,3.2,,
+function,PySys_AddWarnOptionUnicode,3.2,,
+function,PySys_AddXOption,3.7,,
+function,PySys_FormatStderr,3.2,,
+function,PySys_FormatStdout,3.2,,
+function,PySys_GetObject,3.2,,
+function,PySys_GetXOptions,3.7,,
+function,PySys_HasWarnOptions,3.2,,
+function,PySys_ResetWarnOptions,3.2,,
+function,PySys_SetArgv,3.2,,
+function,PySys_SetArgvEx,3.2,,
+function,PySys_SetObject,3.2,,
+function,PySys_SetPath,3.2,,
+function,PySys_WriteStderr,3.2,,
+function,PySys_WriteStdout,3.2,,
+type,PyThreadState,3.2,,opaque
+function,PyThreadState_Clear,3.2,,
+function,PyThreadState_Delete,3.2,,
+function,PyThreadState_Get,3.2,,
+function,PyThreadState_GetDict,3.2,,
+function,PyThreadState_GetFrame,3.10,,
+function,PyThreadState_GetID,3.10,,
+function,PyThreadState_GetInterpreter,3.10,,
+function,PyThreadState_New,3.2,,
+function,PyThreadState_SetAsyncExc,3.2,,
+function,PyThreadState_Swap,3.2,,
+function,PyThread_GetInfo,3.3,,
+function,PyThread_ReInitTLS,3.2,,
+function,PyThread_acquire_lock,3.2,,
+function,PyThread_acquire_lock_timed,3.2,,
+function,PyThread_allocate_lock,3.2,,
+function,PyThread_create_key,3.2,,
+function,PyThread_delete_key,3.2,,
+function,PyThread_delete_key_value,3.2,,
+function,PyThread_exit_thread,3.2,,
+function,PyThread_free_lock,3.2,,
+function,PyThread_get_key_value,3.2,,
+function,PyThread_get_stacksize,3.2,,
+function,PyThread_get_thread_ident,3.2,,
+function,PyThread_get_thread_native_id,3.2,,
+function,PyThread_init_thread,3.2,,
+function,PyThread_release_lock,3.2,,
+function,PyThread_set_key_value,3.2,,
+function,PyThread_set_stacksize,3.2,,
+function,PyThread_start_new_thread,3.2,,
+function,PyThread_tss_alloc,3.7,,
+function,PyThread_tss_create,3.7,,
+function,PyThread_tss_delete,3.7,,
+function,PyThread_tss_free,3.7,,
+function,PyThread_tss_get,3.7,,
+function,PyThread_tss_is_created,3.7,,
+function,PyThread_tss_set,3.7,,
+function,PyTraceBack_Here,3.2,,
+function,PyTraceBack_Print,3.2,,
+var,PyTraceBack_Type,3.2,,
+var,PyTupleIter_Type,3.2,,
+function,PyTuple_GetItem,3.2,,
+function,PyTuple_GetSlice,3.2,,
+function,PyTuple_New,3.2,,
+function,PyTuple_Pack,3.2,,
+function,PyTuple_SetItem,3.2,,
+function,PyTuple_Size,3.2,,
+var,PyTuple_Type,3.2,,
+type,PyTypeObject,3.2,,opaque
+function,PyType_ClearCache,3.2,,
+function,PyType_FromModuleAndSpec,3.10,,
+function,PyType_FromSpec,3.2,,
+function,PyType_FromSpecWithBases,3.3,,
+function,PyType_GenericAlloc,3.2,,
+function,PyType_GenericNew,3.2,,
+function,PyType_GetFlags,3.2,,
+function,PyType_GetModule,3.10,,
+function,PyType_GetModuleState,3.10,,
+function,PyType_GetSlot,3.4,,
+function,PyType_IsSubtype,3.2,,
+function,PyType_Modified,3.2,,
+function,PyType_Ready,3.2,,
+type,PyType_Slot,3.2,,full-abi
+type,PyType_Spec,3.2,,full-abi
+var,PyType_Type,3.2,,
+function,PyUnicodeDecodeError_Create,3.2,,
+function,PyUnicodeDecodeError_GetEncoding,3.2,,
+function,PyUnicodeDecodeError_GetEnd,3.2,,
+function,PyUnicodeDecodeError_GetObject,3.2,,
+function,PyUnicodeDecodeError_GetReason,3.2,,
+function,PyUnicodeDecodeError_GetStart,3.2,,
+function,PyUnicodeDecodeError_SetEnd,3.2,,
+function,PyUnicodeDecodeError_SetReason,3.2,,
+function,PyUnicodeDecodeError_SetStart,3.2,,
+function,PyUnicodeEncodeError_GetEncoding,3.2,,
+function,PyUnicodeEncodeError_GetEnd,3.2,,
+function,PyUnicodeEncodeError_GetObject,3.2,,
+function,PyUnicodeEncodeError_GetReason,3.2,,
+function,PyUnicodeEncodeError_GetStart,3.2,,
+function,PyUnicodeEncodeError_SetEnd,3.2,,
+function,PyUnicodeEncodeError_SetReason,3.2,,
+function,PyUnicodeEncodeError_SetStart,3.2,,
+var,PyUnicodeIter_Type,3.2,,
+function,PyUnicodeTranslateError_GetEnd,3.2,,
+function,PyUnicodeTranslateError_GetObject,3.2,,
+function,PyUnicodeTranslateError_GetReason,3.2,,
+function,PyUnicodeTranslateError_GetStart,3.2,,
+function,PyUnicodeTranslateError_SetEnd,3.2,,
+function,PyUnicodeTranslateError_SetReason,3.2,,
+function,PyUnicodeTranslateError_SetStart,3.2,,
+function,PyUnicode_Append,3.2,,
+function,PyUnicode_AppendAndDel,3.2,,
+function,PyUnicode_AsASCIIString,3.2,,
+function,PyUnicode_AsCharmapString,3.2,,
+function,PyUnicode_AsDecodedObject,3.2,,
+function,PyUnicode_AsDecodedUnicode,3.2,,
+function,PyUnicode_AsEncodedObject,3.2,,
+function,PyUnicode_AsEncodedString,3.2,,
+function,PyUnicode_AsEncodedUnicode,3.2,,
+function,PyUnicode_AsLatin1String,3.2,,
+function,PyUnicode_AsMBCSString,3.7,on Windows,
+function,PyUnicode_AsRawUnicodeEscapeString,3.2,,
+function,PyUnicode_AsUCS4,3.7,,
+function,PyUnicode_AsUCS4Copy,3.7,,
+function,PyUnicode_AsUTF16String,3.2,,
+function,PyUnicode_AsUTF32String,3.2,,
+function,PyUnicode_AsUTF8AndSize,3.10,,
+function,PyUnicode_AsUTF8String,3.2,,
+function,PyUnicode_AsUnicodeEscapeString,3.2,,
+function,PyUnicode_AsWideChar,3.2,,
+function,PyUnicode_AsWideCharString,3.7,,
+function,PyUnicode_BuildEncodingMap,3.2,,
+function,PyUnicode_Compare,3.2,,
+function,PyUnicode_CompareWithASCIIString,3.2,,
+function,PyUnicode_Concat,3.2,,
+function,PyUnicode_Contains,3.2,,
+function,PyUnicode_Count,3.2,,
+function,PyUnicode_Decode,3.2,,
+function,PyUnicode_DecodeASCII,3.2,,
+function,PyUnicode_DecodeCharmap,3.2,,
+function,PyUnicode_DecodeCodePageStateful,3.7,on Windows,
+function,PyUnicode_DecodeFSDefault,3.2,,
+function,PyUnicode_DecodeFSDefaultAndSize,3.2,,
+function,PyUnicode_DecodeLatin1,3.2,,
+function,PyUnicode_DecodeLocale,3.7,,
+function,PyUnicode_DecodeLocaleAndSize,3.7,,
+function,PyUnicode_DecodeMBCS,3.7,on Windows,
+function,PyUnicode_DecodeMBCSStateful,3.7,on Windows,
+function,PyUnicode_DecodeRawUnicodeEscape,3.2,,
+function,PyUnicode_DecodeUTF16,3.2,,
+function,PyUnicode_DecodeUTF16Stateful,3.2,,
+function,PyUnicode_DecodeUTF32,3.2,,
+function,PyUnicode_DecodeUTF32Stateful,3.2,,
+function,PyUnicode_DecodeUTF7,3.2,,
+function,PyUnicode_DecodeUTF7Stateful,3.2,,
+function,PyUnicode_DecodeUTF8,3.2,,
+function,PyUnicode_DecodeUTF8Stateful,3.2,,
+function,PyUnicode_DecodeUnicodeEscape,3.2,,
+function,PyUnicode_EncodeCodePage,3.7,on Windows,
+function,PyUnicode_EncodeFSDefault,3.2,,
+function,PyUnicode_EncodeLocale,3.7,,
+function,PyUnicode_FSConverter,3.2,,
+function,PyUnicode_FSDecoder,3.2,,
+function,PyUnicode_Find,3.2,,
+function,PyUnicode_FindChar,3.7,,
+function,PyUnicode_Format,3.2,,
+function,PyUnicode_FromEncodedObject,3.2,,
+function,PyUnicode_FromFormat,3.2,,
+function,PyUnicode_FromFormatV,3.2,,
+function,PyUnicode_FromObject,3.2,,
+function,PyUnicode_FromOrdinal,3.2,,
+function,PyUnicode_FromString,3.2,,
+function,PyUnicode_FromStringAndSize,3.2,,
+function,PyUnicode_FromWideChar,3.2,,
+function,PyUnicode_GetDefaultEncoding,3.2,,
+function,PyUnicode_GetLength,3.7,,
+function,PyUnicode_GetSize,3.2,,
+function,PyUnicode_InternFromString,3.2,,
+function,PyUnicode_InternImmortal,3.2,,
+function,PyUnicode_InternInPlace,3.2,,
+function,PyUnicode_IsIdentifier,3.2,,
+function,PyUnicode_Join,3.2,,
+function,PyUnicode_Partition,3.2,,
+function,PyUnicode_RPartition,3.2,,
+function,PyUnicode_RSplit,3.2,,
+function,PyUnicode_ReadChar,3.7,,
+function,PyUnicode_Replace,3.2,,
+function,PyUnicode_Resize,3.2,,
+function,PyUnicode_RichCompare,3.2,,
+function,PyUnicode_Split,3.2,,
+function,PyUnicode_Splitlines,3.2,,
+function,PyUnicode_Substring,3.7,,
+function,PyUnicode_Tailmatch,3.2,,
+function,PyUnicode_Translate,3.2,,
+var,PyUnicode_Type,3.2,,
+function,PyUnicode_WriteChar,3.7,,
+type,PyVarObject,3.2,,members
+member,PyVarObject.ob_base,3.2,,
+member,PyVarObject.ob_size,3.2,,
+type,PyWeakReference,3.2,,opaque
+function,PyWeakref_GetObject,3.2,,
+function,PyWeakref_NewProxy,3.2,,
+function,PyWeakref_NewRef,3.2,,
+var,PyWrapperDescr_Type,3.2,,
+function,PyWrapper_New,3.2,,
+var,PyZip_Type,3.2,,
+function,Py_AddPendingCall,3.2,,
+function,Py_AtExit,3.2,,
+macro,Py_BEGIN_ALLOW_THREADS,3.2,,
+macro,Py_BLOCK_THREADS,3.2,,
+function,Py_BuildValue,3.2,,
+function,Py_BytesMain,3.8,,
+function,Py_CompileString,3.2,,
+function,Py_DecRef,3.2,,
+function,Py_DecodeLocale,3.7,,
+macro,Py_END_ALLOW_THREADS,3.2,,
+function,Py_EncodeLocale,3.7,,
+function,Py_EndInterpreter,3.2,,
+function,Py_EnterRecursiveCall,3.9,,
+function,Py_Exit,3.2,,
+function,Py_FatalError,3.2,,
+var,Py_FileSystemDefaultEncodeErrors,3.10,,
+var,Py_FileSystemDefaultEncoding,3.2,,
+function,Py_Finalize,3.2,,
+function,Py_FinalizeEx,3.6,,
+function,Py_GenericAlias,3.9,,
+var,Py_GenericAliasType,3.9,,
+function,Py_GetBuildInfo,3.2,,
+function,Py_GetCompiler,3.2,,
+function,Py_GetCopyright,3.2,,
+function,Py_GetExecPrefix,3.2,,
+function,Py_GetPath,3.2,,
+function,Py_GetPlatform,3.2,,
+function,Py_GetPrefix,3.2,,
+function,Py_GetProgramFullPath,3.2,,
+function,Py_GetProgramName,3.2,,
+function,Py_GetPythonHome,3.2,,
+function,Py_GetRecursionLimit,3.2,,
+function,Py_GetVersion,3.2,,
+var,Py_HasFileSystemDefaultEncoding,3.2,,
+function,Py_IncRef,3.2,,
+function,Py_Initialize,3.2,,
+function,Py_InitializeEx,3.2,,
+function,Py_Is,3.10,,
+function,Py_IsFalse,3.10,,
+function,Py_IsInitialized,3.2,,
+function,Py_IsNone,3.10,,
+function,Py_IsTrue,3.10,,
+function,Py_LeaveRecursiveCall,3.9,,
+function,Py_Main,3.2,,
+function,Py_MakePendingCalls,3.2,,
+function,Py_NewInterpreter,3.2,,
+function,Py_NewRef,3.10,,
+function,Py_ReprEnter,3.2,,
+function,Py_ReprLeave,3.2,,
+function,Py_SetPath,3.7,,
+function,Py_SetProgramName,3.2,,
+function,Py_SetPythonHome,3.2,,
+function,Py_SetRecursionLimit,3.2,,
+type,Py_UCS4,3.2,,
+macro,Py_UNBLOCK_THREADS,3.2,,
+var,Py_UTF8Mode,3.8,,
+function,Py_VaBuildValue,3.2,,
+function,Py_XNewRef,3.10,,
+type,Py_intptr_t,3.2,,
+type,Py_ssize_t,3.2,,
+type,Py_uintptr_t,3.2,,
+type,allocfunc,3.2,,
+type,binaryfunc,3.2,,
+type,descrgetfunc,3.2,,
+type,descrsetfunc,3.2,,
+type,destructor,3.2,,
+type,getattrfunc,3.2,,
+type,getattrofunc,3.2,,
+type,getiterfunc,3.2,,
+type,getter,3.2,,
+type,hashfunc,3.2,,
+type,initproc,3.2,,
+type,inquiry,3.2,,
+type,iternextfunc,3.2,,
+type,lenfunc,3.2,,
+type,newfunc,3.2,,
+type,objobjargproc,3.2,,
+type,objobjproc,3.2,,
+type,reprfunc,3.2,,
+type,richcmpfunc,3.2,,
+type,setattrfunc,3.2,,
+type,setattrofunc,3.2,,
+type,setter,3.2,,
+type,ssizeargfunc,3.2,,
+type,ssizeobjargproc,3.2,,
+type,ssizessizeargfunc,3.2,,
+type,ssizessizeobjargproc,3.2,,
+type,symtable,3.2,,opaque
+type,ternaryfunc,3.2,,
+type,traverseproc,3.2,,
+type,unaryfunc,3.2,,
+type,visitproc,3.2,,
--- /dev/null
+#
+# Python documentation docutils configuration file
+#
+# https://docutils.sourceforge.io/docs/user/config.html
+
+[parsers]
+# Override the default RFC base URL from sphinx
+rfc_base_url=https://datatracker.ietf.org/doc/html/
This guide only covers the basic tools for creating extensions provided
as part of this version of CPython. Third party tools like
-`Cython <http://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_,
-`SWIG <http://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_
+`Cython <https://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_,
+`SWIG <https://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_
offer both simpler and more sophisticated approaches to creating C and C++
extensions for Python.
Can Python be compiled to machine code, C or some other language?
-----------------------------------------------------------------
-`Cython <http://cython.org/>`_ compiles a modified version of Python with
-optional annotations into C extensions. `Nuitka <http://www.nuitka.net/>`_ is
+`Cython <https://cython.org/>`_ compiles a modified version of Python with
+optional annotations into C extensions. `Nuitka <https://www.nuitka.net/>`_ is
an up-and-coming compiler of Python into C++ code, aiming to support the full
Python language.
to perform a garbage collection, obtain debugging statistics, and tune the
collector's parameters.
-Other implementations (such as `Jython <http://www.jython.org>`_ or
-`PyPy <http://www.pypy.org>`_), however, can rely on a different mechanism
+Other implementations (such as `Jython <https://www.jython.org>`_ or
+`PyPy <https://www.pypy.org>`_), however, can rely on a different mechanism
such as a full-blown garbage collector. This difference can cause some
subtle porting problems if your Python code depends on the behavior of the
reference counting implementation.
.. XXX make sure these all work
-`Cython <http://cython.org>`_ and its relative `Pyrex
+`Cython <https://cython.org>`_ and its relative `Pyrex
<https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers
that accept a slightly modified form of Python and generate the corresponding
C code. Cython and Pyrex make it possible to write an extension without having
If you need to interface to some C or C++ library for which no Python extension
currently exists, you can try wrapping the library's data types and functions
-with a tool such as `SWIG <http://www.swig.org>`_. `SIP
+with a tool such as `SWIG <https://www.swig.org>`_. `SIP
<https://riverbankcomputing.com/software/sip/intro>`__, `CXX
<http://cxx.sourceforge.net/>`_ `Boost
-<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave
+<https://www.boost.org/libs/python/doc/index.html>`_, or `Weave
<https://github.com/scipy/weave>`_ are also
alternatives for wrapping C++ libraries.
Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`,
:class:`dict`, etc.
-The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html)
+The Boost Python Library (BPL, https://www.boost.org/libs/python/doc/index.html)
provides a way of doing this from C++ (i.e. you can inherit from an extension
class written in C++ using the BPL).
High-profile Python projects include `the Mailman mailing list manager
<http://www.list.org>`_ and `the Zope application server
-<http://www.zope.org>`_. Several Linux distributions, most notably `Red Hat
+<https://www.zope.dev>`_. Several Linux distributions, most notably `Red Hat
<https://www.redhat.com>`_, have written part or all of their installer and
system administration software in Python. Companies that use Python internally
include Google, Yahoo, and Lucasfilm Ltd.
executables:
* `Nuitka <https://nuitka.net/>`_ (Cross-platform)
-* `PyInstaller <http://www.pyinstaller.org/>`_ (Cross-platform)
+* `PyInstaller <https://pyinstaller.org/>`_ (Cross-platform)
* `PyOxidizer <https://pyoxidizer.readthedocs.io/en/stable/>`_ (Cross-platform)
* `cx_Freeze <https://marcelotduarte.github.io/cx_Freeze/>`_ (Cross-platform)
* `py2app <https://github.com/ronaldoussoren/py2app>`_ (macOS only)
detrimental to readability).
If you have reached the limit of what pure Python can allow, there are tools
-to take you further away. For example, `Cython <http://cython.org>`_ can
+to take you further away. For example, `Cython <https://cython.org>`_ can
compile a slightly modified version of Python code into a C extension, and
can be used on many different platforms. Cython can take advantage of
compilation (and optional type annotations) to make your code significantly
from their :func:`id`.
IDLE
- An Integrated Development Environment for Python. IDLE is a basic editor
- and interpreter environment which ships with the standard distribution of
- Python.
+ An Integrated Development and Learning Environment for Python.
+ :ref:`idle` is a basic editor and interpreter environment
+ which ships with the standard distribution of Python.
immutable
An object with a fixed value. Immutable objects include numbers, strings and
.. _Migrating C extensions: http://python3porting.com/cextensions.html
.. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html
-.. _Cython: http://cython.org/
+.. _Cython: https://cython.org/
.. _CFFI: https://cffi.readthedocs.io/en/latest/
`the Python Developer's Guide <https://devguide.python.org/>`_ to
learn more about submitting patches to Python.
-* `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_:
+* `Writing Programs with NCURSES <https://invisible-island.net/ncurses/ncurses-intro.html>`_:
a lengthy tutorial for C programmers.
* `The ncurses man page <https://linux.die.net/man/3/ncurses>`_
-* `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_
+* `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_
* `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_:
video of a PyCon 2013 talk on controlling terminals using curses or Urwid.
-* `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_:
+* `"Console Applications with Urwid" <https://pyvideo.org/video/1568/console-applications-with-urwid>`_:
video of a PyCon CA 2012 talk demonstrating some applications written using
Urwid.
.. testcode::
+ def find_name_in_mro(cls, name, default):
+ "Emulate _PyType_Lookup() in Objects/typeobject.c"
+ for base in cls.__mro__:
+ if name in vars(base):
+ return vars(base)[name]
+ return default
+
def object_getattribute(obj, name):
"Emulate PyObject_GenericGetAttr() in Objects/object.c"
null = object()
objtype = type(obj)
- cls_var = getattr(objtype, name, null)
+ cls_var = find_name_in_mro(objtype, name, null)
descr_get = getattr(type(cls_var), '__get__', null)
if descr_get is not null:
if (hasattr(type(cls_var), '__set__')
def __getattr__(self, name):
return ('getattr_hook', self, name)
+ class D1:
+ def __get__(self, obj, objtype=None):
+ return type(self), obj, objtype
+
+ class U1:
+ x = D1()
+
+ class U2(U1):
+ pass
.. doctest::
:hide:
>>> b.g == b['g'] == ('getattr_hook', b, 'g')
True
+ >>> u2 = U2()
+ >>> object_getattribute(u2, 'x') == u2.x == (D1, u2, U2)
+ True
+
Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__`
code. That is why calling :meth:`__getattribute__` directly or with
``super().__getattribute__`` will bypass :meth:`__getattr__` entirely.
design approaches described in these chapters are applicable to functional-style
Python code.
-http://www.defmacro.org/ramblings/fp.html: A general introduction to functional
+https://www.defmacro.org/ramblings/fp.html: A general introduction to functional
programming that uses Java examples and has a lengthy historical introduction.
https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry
Python-specific
---------------
-http://gnosis.cx/TPiP/: The first chapter of David Mertz's book
+https://gnosis.cx/TPiP/: The first chapter of David Mertz's book
:title-reference:`Text Processing in Python` discusses functional programming
for text processing, in the section titled "Utilizing Higher-Order Functions in
Text Processing".
...
+.. _buffered-smtp:
+
+Sending logging messages to email, with buffering
+-------------------------------------------------
+
+To illustrate how you can send log messages via email, so that a set number of
+messages are sent per email, you can subclass
+:class:`~logging.handlers.BufferingHandler`. In the following example, which you can
+adapt to suit your specific needs, a simple test harness is provided which allows you
+to run the script with command line arguments specifying what you typically need to
+send things via SMTP. (Run the downloaded script with the ``-h`` argument to see the
+required and optional arguments.)
+
+.. code-block:: python
+
+ import logging
+ import logging.handlers
+ import smtplib
+
+ class BufferingSMTPHandler(logging.handlers.BufferingHandler):
+ def __init__(self, mailhost, port, username, password, fromaddr, toaddrs,
+ subject, capacity):
+ logging.handlers.BufferingHandler.__init__(self, capacity)
+ self.mailhost = mailhost
+ self.mailport = port
+ self.username = username
+ self.password = password
+ self.fromaddr = fromaddr
+ if isinstance(toaddrs, str):
+ toaddrs = [toaddrs]
+ self.toaddrs = toaddrs
+ self.subject = subject
+ self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
+
+ def flush(self):
+ if len(self.buffer) > 0:
+ try:
+ smtp = smtplib.SMTP(self.mailhost, self.mailport)
+ smtp.starttls()
+ smtp.login(self.username, self.password)
+ msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject)
+ for record in self.buffer:
+ s = self.format(record)
+ msg = msg + s + "\r\n"
+ smtp.sendmail(self.fromaddr, self.toaddrs, msg)
+ smtp.quit()
+ except Exception:
+ if logging.raiseExceptions:
+ raise
+ self.buffer = []
+
+ if __name__ == '__main__':
+ import argparse
+
+ ap = argparse.ArgumentParser()
+ aa = ap.add_argument
+ aa('host', metavar='HOST', help='SMTP server')
+ aa('--port', '-p', type=int, default=587, help='SMTP port')
+ aa('user', metavar='USER', help='SMTP username')
+ aa('password', metavar='PASSWORD', help='SMTP password')
+ aa('to', metavar='TO', help='Addressee for emails')
+ aa('sender', metavar='SENDER', help='Sender email address')
+ aa('--subject', '-s',
+ default='Test Logging email from Python logging module (buffering)',
+ help='Subject of email')
+ options = ap.parse_args()
+ logger = logging.getLogger()
+ logger.setLevel(logging.DEBUG)
+ h = BufferingSMTPHandler(options.host, options.port, options.user,
+ options.password, options.sender,
+ options.to, options.subject, 10)
+ logger.addHandler(h)
+ for i in range(102):
+ logger.info("Info index = %d", i)
+ h.flush()
+ h.close()
+
+If you run this script and your SMTP server is correctly set up, you should find that
+it sends eleven emails to the addressee you specify. The first ten emails will each
+have ten log messages, and the eleventh will have two messages. That makes up 102
+messages as specified in the script.
+
.. _utc-formatting:
Formatting times using UTC (GMT) via configuration
.. _caniusepython3: https://pypi.org/project/caniusepython3
-.. _cheat sheet: http://python-future.org/compatible_idioms.html
+.. _cheat sheet: https://python-future.org/compatible_idioms.html
.. _coverage.py: https://pypi.org/project/coverage
-.. _Futurize: http://python-future.org/automatic_conversion.html
+.. _Futurize: https://python-future.org/automatic_conversion.html
.. _importlib2: https://pypi.org/project/importlib2
.. _Modernize: https://python-modernize.readthedocs.io/
.. _mypy: http://mypy-lang.org/
.. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html
.. _pytype: https://github.com/google/pytype
-.. _python-future: http://python-future.org/
+.. _python-future: https://python-future.org/
.. _python-porting: https://mail.python.org/pipermail/python-porting/
.. _six: https://pypi.org/project/six
.. _tox: https://pypi.org/project/tox
(9 minutes 36 seconds).
To help understand the standard, Jukka Korpela has written `an introductory
-guide <http://jkorpela.fi/unicode/guide.html>`_ to reading the
+guide <https://jkorpela.fi/unicode/guide.html>`_ to reading the
Unicode character tables.
Another `good introductory article <https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_
----------
One section of `Mastering Python 3 Input/Output
-<http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_,
+<https://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_,
a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling.
The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware
and localize an application. These slides cover Python 2.x only.
`The Guts of Unicode in Python
-<http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_
+<https://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_
is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode
representation in Python 3.3.
:class:`http.client.HTTPMessage` instance.
Typical headers include 'Content-length', 'Content-type', and so on. See the
-`Quick Reference to HTTP Headers <http://jkorpela.fi/http.html>`_
+`Quick Reference to HTTP Headers <https://jkorpela.fi/http.html>`_
for a useful listing of HTTP headers with brief explanations of their meaning
and use.
+++ /dev/null
-import sqlite3
-
-class Point:
- def __init__(self, x, y):
- self.x, self.y = x, y
-
- def __conform__(self, protocol):
- if protocol is sqlite3.PrepareProtocol:
- return "%f;%f" % (self.x, self.y)
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-p = Point(4.0, -3.2)
-cur.execute("select ?", (p,))
-print(cur.fetchone()[0])
-
-con.close()
+++ /dev/null
-import sqlite3
-
-class Point:
- def __init__(self, x, y):
- self.x, self.y = x, y
-
-def adapt_point(point):
- return "%f;%f" % (point.x, point.y)
-
-sqlite3.register_adapter(Point, adapt_point)
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-p = Point(4.0, -3.2)
-cur.execute("select ?", (p,))
-print(cur.fetchone()[0])
-
-con.close()
+++ /dev/null
-import sqlite3
-
-def collate_reverse(string1, string2):
- if string1 == string2:
- return 0
- elif string1 < string2:
- return 1
- else:
- return -1
-
-con = sqlite3.connect(":memory:")
-con.create_collation("reverse", collate_reverse)
-
-cur = con.cursor()
-cur.execute("create table test(x)")
-cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
-cur.execute("select x from test order by x collate reverse")
-for row in cur:
- print(row)
-con.close()
+++ /dev/null
-# A minimal SQLite shell for experiments
-
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-con.isolation_level = None
-cur = con.cursor()
-
-buffer = ""
-
-print("Enter your SQL commands to execute in sqlite3.")
-print("Enter a blank line to exit.")
-
-while True:
- line = input()
- if line == "":
- break
- buffer += line
- if sqlite3.complete_statement(buffer):
- try:
- buffer = buffer.strip()
- cur.execute(buffer)
-
- if buffer.lstrip().upper().startswith("SELECT"):
- print(cur.fetchall())
- except sqlite3.Error as e:
- print("An error occurred:", e.args[0])
- buffer = ""
-
-con.close()
+++ /dev/null
-import sqlite3
-
-class Point:
- def __init__(self, x, y):
- self.x, self.y = x, y
-
- def __repr__(self):
- return f"Point({self.x}, {self.y})"
-
-def adapt_point(point):
- return f"{point.x};{point.y}".encode("utf-8")
-
-def convert_point(s):
- x, y = list(map(float, s.split(b";")))
- return Point(x, y)
-
-# Register the adapter and converter
-sqlite3.register_adapter(Point, adapt_point)
-sqlite3.register_converter("point", convert_point)
-
-# 1) Parse using declared types
-p = Point(4.0, -3.2)
-con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
-cur = con.execute("create table test(p point)")
-
-cur.execute("insert into test(p) values (?)", (p,))
-cur.execute("select p from test")
-print("with declared types:", cur.fetchone()[0])
-cur.close()
-con.close()
-
-# 2) Parse using column names
-con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
-cur = con.execute("create table test(p)")
-
-cur.execute("insert into test(p) values (?)", (p,))
-cur.execute('select p as "p [point]" from test')
-print("with column names:", cur.fetchone()[0])
-cur.close()
-con.close()
+++ /dev/null
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-con.execute("create table lang (id integer primary key, name varchar unique)")
-
-# Successful, con.commit() is called automatically afterwards
-with con:
- con.execute("insert into lang(name) values (?)", ("Python",))
-
-# con.rollback() is called after the with block finishes with an exception, the
-# exception is still raised and must be caught
-try:
- with con:
- con.execute("insert into lang(name) values (?)", ("Python",))
-except sqlite3.IntegrityError:
- print("couldn't add Python twice")
-
-# Connection object used as context manager only commits or rollbacks transactions,
-# so the connection object should be closed manually
-con.close()
+++ /dev/null
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-cur.execute("create table lang (name, first_appeared)")
-
-# This is the qmark style:
-cur.execute("insert into lang values (?, ?)", ("C", 1972))
-
-# The qmark style used with executemany():
-lang_list = [
- ("Fortran", 1957),
- ("Python", 1991),
- ("Go", 2009),
-]
-cur.executemany("insert into lang values (?, ?)", lang_list)
-
-# And this is the named style:
-cur.execute("select * from lang where first_appeared=:year", {"year": 1972})
-print(cur.fetchall())
-
-con.close()
+++ /dev/null
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-
-# enable extension loading
-con.enable_load_extension(True)
-
-# Load the fulltext search extension
-con.execute("select load_extension('./fts3.so')")
-
-# alternatively you can load the extension using an API call:
-# con.load_extension("./fts3.so")
-
-# disable extension loading again
-con.enable_load_extension(False)
-
-# example from SQLite wiki
-con.execute("create virtual table recipe using fts3(name, ingredients)")
-con.executescript("""
- insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
- insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
- insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
- insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
- """)
-for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
- print(row)
-
-con.close()
+++ /dev/null
-import sqlite3
-import hashlib
-
-def md5sum(t):
- return hashlib.md5(t).hexdigest()
-
-con = sqlite3.connect(":memory:")
-con.create_function("md5", 1, md5sum)
-cur = con.cursor()
-cur.execute("select md5(?)", (b"foo",))
-print(cur.fetchone()[0])
-
-con.close()
+++ /dev/null
-import sqlite3
-
-class MySum:
- def __init__(self):
- self.count = 0
-
- def step(self, value):
- self.count += value
-
- def finalize(self):
- return self.count
-
-con = sqlite3.connect(":memory:")
-con.create_aggregate("mysum", 1, MySum)
-cur = con.cursor()
-cur.execute("create table test(i)")
-cur.execute("insert into test(i) values (1)")
-cur.execute("insert into test(i) values (2)")
-cur.execute("select mysum(i) from test")
-print(cur.fetchone()[0])
-
-con.close()
+++ /dev/null
-import sqlite3
-
-def dict_factory(cursor, row):
- d = {}
- for idx, col in enumerate(cursor.description):
- d[col[0]] = row[idx]
- return d
-
-con = sqlite3.connect(":memory:")
-con.row_factory = dict_factory
-cur = con.cursor()
-cur.execute("select 1 as a")
-print(cur.fetchone()["a"])
-
-con.close()
+++ /dev/null
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-con.row_factory = sqlite3.Row
-
-cur = con.cursor()
-cur.execute("select 'John' as name, 42 as age")
-for row in cur:
- assert row[0] == row["name"]
- assert row["name"] == row["nAmE"]
- assert row[1] == row["age"]
- assert row[1] == row["AgE"]
-
-con.close()
+++ /dev/null
-import sqlite3
-
-langs = [
- ("C++", 1985),
- ("Objective-C", 1984),
-]
-
-con = sqlite3.connect(":memory:")
-
-# Create the table
-con.execute("create table lang(name, first_appeared)")
-
-# Fill the table
-con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs)
-
-# Print the table contents
-for row in con.execute("select name, first_appeared from lang"):
- print(row)
-
-print("I just deleted", con.execute("delete from lang").rowcount, "rows")
-
-# close is not a shortcut method and it's not called automatically,
-# so the connection object should be closed manually
-con.close()
+++ /dev/null
-import sqlite3
-
-con = sqlite3.connect(":memory:")
-cur = con.cursor()
-
-AUSTRIA = "Österreich"
-
-# by default, rows are returned as str
-cur.execute("select ?", (AUSTRIA,))
-row = cur.fetchone()
-assert row[0] == AUSTRIA
-
-# but we can make sqlite3 always return bytestrings ...
-con.text_factory = bytes
-cur.execute("select ?", (AUSTRIA,))
-row = cur.fetchone()
-assert type(row[0]) is bytes
-# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
-# database ...
-assert row[0] == AUSTRIA.encode("utf-8")
-
-# we can also implement a custom text_factory ...
-# here we implement one that appends "foo" to all strings
-con.text_factory = lambda x: x.decode("utf-8") + "foo"
-cur.execute("select ?", ("bar",))
-row = cur.fetchone()
-assert row[0] == "barfoo"
-
-con.close()
.. seealso::
- `Building Python modules on MS Windows platform with MinGW <http://old.zope.org/Members/als/tips/win32_mingw_modules>`_
+ `Building Python modules on MS Windows platform with MinGW <https://old.zope.dev/Members/als/tips/win32_mingw_modules>`_
Information about building the required libraries for the MinGW environment.
.. method:: loop.create_task(coro, *, name=None)
- Schedule the execution of a :ref:`coroutine`.
+ Schedule the execution of :ref:`coroutine <coroutine>` *coro*.
Return a :class:`Task` object.
Third-party event loops can use their own subclass of :class:`Task`
The :mod:`bdb` module also defines two classes:
-.. class:: Breakpoint(self, file, line, temporary=0, cond=None, funcname=None)
+.. class:: Breakpoint(self, file, line, temporary=False, cond=None, funcname=None)
This class implements temporary breakpoints, ignore counts, disabling and
(re-)enabling, and conditionals.
Breakpoints are indexed by number through a list called :attr:`bpbynumber`
- and by ``(file, line)`` pairs through :attr:`bplist`. The former points to a
- single instance of class :class:`Breakpoint`. The latter points to a list of
- such instances since there may be more than one breakpoint per line.
+ and by ``(file, line)`` pairs through :attr:`bplist`. The former points to
+ a single instance of class :class:`Breakpoint`. The latter points to a list
+ of such instances since there may be more than one breakpoint per line.
- When creating a breakpoint, its associated filename should be in canonical
- form. If a *funcname* is defined, a breakpoint hit will be counted when the
- first line of that function is executed. A conditional breakpoint always
- counts a hit.
+ When creating a breakpoint, its associated :attr:`file name <file>` should
+ be in canonical form. If a :attr:`funcname` is defined, a breakpoint
+ :attr:`hit <hits>` will be counted when the first line of that function is
+ executed. A :attr:`conditional <cond>` breakpoint always counts a
+ :attr:`hit <hits>`.
:class:`Breakpoint` instances have the following methods:
Return a string with all the information about the breakpoint, nicely
formatted:
- * The breakpoint number.
- * If it is temporary or not.
- * Its file,line position.
- * The condition that causes a break.
- * If it must be ignored the next N times.
- * The breakpoint hit count.
+ * Breakpoint number.
+ * Temporary status (del or keep).
+ * File/line position.
+ * Break condition.
+ * Number of times to ignore.
+ * Number of times hit.
.. versionadded:: 3.2
Print the output of :meth:`bpformat` to the file *out*, or if it is
``None``, to standard output.
+ :class:`Breakpoint` instances have the following attributes:
+
+ .. attribute:: file
+
+ File name of the :class:`Breakpoint`.
+
+ .. attribute:: line
+
+ Line number of the :class:`Breakpoint` within :attr:`file`.
+
+ .. attribute:: temporary
+
+ True if a :class:`Breakpoint` at (file, line) is temporary.
+
+ .. attribute:: cond
+
+ Condition for evaluating a :class:`Breakpoint` at (file, line).
+
+ .. attribute:: funcname
+
+ Function name that defines whether a :class:`Breakpoint` is hit upon
+ entering the function.
+
+ .. attribute:: enabled
+
+ True if :class:`Breakpoint` is enabled.
+
+ .. attribute:: bpbynumber
+
+ Numeric index for a single instance of a :class:`Breakpoint`.
+
+ .. attribute:: bplist
+
+ Dictionary of :class:`Breakpoint` instances indexed by
+ (:attr:`file`, :attr:`line`) tuples.
+
+ .. attribute:: ignore
+
+ Number of times to ignore a :class:`Breakpoint`.
+
+ .. attribute:: hits
+
+ Count of the number of times a :class:`Breakpoint` has been hit.
.. class:: Bdb(skip=None)
.. method:: canonic(filename)
- Auxiliary method for getting a filename in a canonical form, that is, as a
- case-normalized (on case-insensitive filesystems) absolute path, stripped
- of surrounding angle brackets.
+ Return canonical form of *filename*.
+
+ For real file names, the canonical form is an operating-system-dependent,
+ :func:`case-normalized <os.path.normcase>` :func:`absolute path
+ <os.path.abspath>`. A *filename* with angle brackets, such as `"<stdin>"`
+ generated in interactive mode, is returned unchanged.
.. method:: reset()
Normally derived classes don't override the following methods, but they may
if they want to redefine the definition of stopping and breakpoints.
+ .. method:: is_skipped_line(module_name)
+
+ Return True if *module_name* matches any skip pattern.
+
.. method:: stop_here(frame)
- This method checks if the *frame* is somewhere below :attr:`botframe` in
- the call stack. :attr:`botframe` is the frame in which debugging started.
+ Return True if *frame* is below the starting frame in the stack.
.. method:: break_here(frame)
- This method checks if there is a breakpoint in the filename and line
- belonging to *frame* or, at least, in the current function. If the
- breakpoint is a temporary one, this method deletes it.
+ Return True if there is an effective breakpoint for this line.
+
+ Check whether a line or function breakpoint exists and is in effect. Delete temporary
+ breakpoints based on information from :func:`effective`.
.. method:: break_anywhere(frame)
- This method checks if there is a breakpoint in the filename of the current
- frame.
+ Return True if any breakpoint exists for *frame*'s filename.
Derived classes should override these methods to gain control over debugger
operation.
.. method:: user_call(frame, argument_list)
- This method is called from :meth:`dispatch_call` when there is the
- possibility that a break might be necessary anywhere inside the called
- function.
+ Called from :meth:`dispatch_call` if a break might stop inside the
+ called function.
.. method:: user_line(frame)
- This method is called from :meth:`dispatch_line` when either
- :meth:`stop_here` or :meth:`break_here` yields ``True``.
+ Called from :meth:`dispatch_line` when either :meth:`stop_here` or
+ :meth:`break_here` returns ``True``.
.. method:: user_return(frame, return_value)
- This method is called from :meth:`dispatch_return` when :meth:`stop_here`
- yields ``True``.
+ Called from :meth:`dispatch_return` when :meth:`stop_here` returns ``True``.
.. method:: user_exception(frame, exc_info)
- This method is called from :meth:`dispatch_exception` when
- :meth:`stop_here` yields ``True``.
+ Called from :meth:`dispatch_exception` when :meth:`stop_here`
+ returns ``True``.
.. method:: do_clear(arg)
Stop when returning from the given frame.
- .. method:: set_until(frame)
+ .. method:: set_until(frame, lineno=None)
- Stop when the line with the line no greater than the current one is
+ Stop when the line with the *lineno* greater than the current one is
reached or when returning from current frame.
.. method:: set_trace([frame])
breakpoints. These methods return a string containing an error message if
something went wrong, or ``None`` if all is well.
- .. method:: set_break(filename, lineno, temporary=0, cond, funcname)
+ .. method:: set_break(filename, lineno, temporary=False, cond=None, funcname=None)
Set a new breakpoint. If the *lineno* line doesn't exist for the
*filename* passed as argument, return an error message. The *filename*
.. method:: clear_break(filename, lineno)
- Delete the breakpoints in *filename* and *lineno*. If none were set, an
- error message is returned.
+ Delete the breakpoints in *filename* and *lineno*. If none were set,
+ return an error message.
.. method:: clear_bpbynumber(arg)
.. method:: clear_all_file_breaks(filename)
- Delete all breakpoints in *filename*. If none were set, an error message
- is returned.
+ Delete all breakpoints in *filename*. If none were set, return an error
+ message.
.. method:: clear_all_breaks()
- Delete all existing breakpoints.
+ Delete all existing breakpoints. If none were set, return an error
+ message.
.. method:: get_bpbynumber(arg)
.. method:: get_break(filename, lineno)
- Check if there is a breakpoint for *lineno* of *filename*.
+ Return True if there is a breakpoint for *lineno* in *filename*.
.. method:: get_breaks(filename, lineno)
.. method:: get_stack(f, t)
- Get a list of records for a frame and all higher (calling) and lower
- frames, and the size of the higher part.
+ Return a list of (frame, lineno) tuples in a stack trace, and a size.
+
+ The most recently called frame is last in the list. The size is the number
+ of frames below the frame where the debugger was invoked.
.. method:: format_stack_entry(frame_lineno, lprefix=': ')
- Return a string with information about a stack entry, identified by a
- ``(frame, lineno)`` tuple:
+ Return a string with information about a stack entry, which is a
+ ``(frame, lineno)`` tuple. The return string contains:
- * The canonical form of the filename which contains the frame.
- * The function name, or ``"<lambda>"``.
+ * The canonical filename which contains the frame.
+ * The function name or ``"<lambda>"``.
* The input arguments.
* The return value.
* The line of code (if it exists).
.. function:: checkfuncname(b, frame)
- Check whether we should break here, depending on the way the breakpoint *b*
- was set.
+ Return True if we should break here, depending on the way the
+ :class:`Breakpoint` *b* was set.
- If it was set via line number, it checks if ``b.line`` is the same as the one
- in the frame also passed as argument. If the breakpoint was set via function
- name, we have to check we are in the right frame (the right function) and if
- we are in its first executable line.
+ If it was set via line number, it checks if
+ :attr:`b.line <bdb.Breakpoint.line>` is the same as the one in *frame*.
+ If the breakpoint was set via
+ :attr:`function name <bdb.Breakpoint.funcname>`, we have to check we are in
+ the right *frame* (the right function) and if we are on its first executable
+ line.
.. function:: effective(file, line, frame)
- Determine if there is an effective (active) breakpoint at this line of code.
- Return a tuple of the breakpoint and a boolean that indicates if it is ok
- to delete a temporary breakpoint. Return ``(None, None)`` if there is no
- matching breakpoint.
+ Return ``(active breakpoint, delete temporary flag)`` or ``(None, None)`` as the
+ breakpoint to act upon.
+
+ The *active breakpoint* is the first entry in
+ :attr:`bplist <bdb.Breakpoint.bplist>` for the
+ (:attr:`file <bdb.Breakpoint.file>`, :attr:`line <bdb.Breakpoint.line>`)
+ (which must exist) that is :attr:`enabled <bdb.Breakpoint.enabled>`, for
+ which :func:`checkfuncname` is True, and that has neither a False
+ :attr:`condition <bdb.Breakpoint.cond>` nor positive
+ :attr:`ignore <bdb.Breakpoint.ignore>` count. The *flag*, meaning that a
+ temporary breakpoint should be deleted, is False only when the
+ :attr:`cond <bdb.Breakpoint.cond>` cannot be evaluated (in which case,
+ :attr:`ignore <bdb.Breakpoint.ignore>` count is ignored).
+
+ If no such entry exists, then (None, None) is returned.
+
.. function:: set_trace()
... Movie('Aliens', 1986, 'Scott')
... ]
- >>> # Find the first movie released on or after 1960
+ >>> # Find the first movie released after 1960
>>> by_year = attrgetter('released')
>>> movies.sort(key=by_year)
>>> movies[bisect(movies, 1960, key=by_year)]
def moving_average(iterable, n=3):
# moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
- # http://en.wikipedia.org/wiki/Moving_average
+ # https://en.wikipedia.org/wiki/Moving_average
it = iter(iterable)
d = deque(itertools.islice(it, n-1))
d.appendleft(0)
.. seealso::
- `Pattern Matching: The Gestalt Approach <http://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_
+ `Pattern Matching: The Gestalt Approach <https://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_
Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This
- was published in `Dr. Dobb's Journal <http://www.drdobbs.com/>`_ in July, 1988.
+ was published in `Dr. Dobb's Journal <https://www.drdobbs.com/>`_ in July, 1988.
.. _sequence-matcher:
:func:`sys.breakpointhook` can be set to some other function and
:func:`breakpoint` will automatically call that, allowing you to drop into
the debugger of choice.
+ If :func:`sys.breakpointhook` is not accessible, this function will
+ raise :exc:`RuntimeError`.
.. audit-event:: builtins.breakpoint breakpointhook breakpoint
.. versionchanged:: 3.8
Falls back to :meth:`__index__` if :meth:`__int__` is not defined.
+ .. versionchanged:: 3.10.7
+ :class:`int` string inputs and string representations can be limited to
+ help avoid denial of service attacks. A :exc:`ValueError` is raised when
+ the limit is exceeded while converting a string *x* to an :class:`int` or
+ when converting an :class:`int` into a string would exceed the limit.
+ See the :ref:`integer string conversion length limitation
+ <int_max_str_digits>` documentation.
+
.. function:: isinstance(object, classinfo)
of the type of the object together with additional information often
including the name and address of the object. A class can control what this
function returns for its instances by defining a :meth:`__repr__` method.
+ If :func:`sys.displayhook` is not accessible, this function will raise
+ :exc:`RuntimeError`.
.. function:: reversed(seq)
tool for programs being converted from Python 2 which supported the use of
comparison functions.
- A comparison function is any callable that accept two arguments, compares them,
+ A comparison function is any callable that accepts two arguments, compares them,
and returns a negative number for less-than, zero for equality, or a positive
number for greater-than. A key function is a callable that accepts one
argument and returns another value to be used as the sort key.
The original GNU :program:`gettext` only supported C or C++ source
code but its extended version :program:`xgettext` scans code written
in a number of languages, including Python, to find strings marked as
-translatable. `Babel <http://babel.pocoo.org/>`__ is a Python
+translatable. `Babel <https://babel.pocoo.org/>`__ is a Python
internationalization library that includes a :file:`pybabel` script to
extract and compile message catalogs. François Pinard's program
called :program:`xpot` does a similar job and is available as part of
It defines the following items:
-.. function:: getgrgid(gid)
+.. function:: getgrgid(id)
Return the group database entry for the given numeric group ID. :exc:`KeyError`
is raised if the entry asked for cannot be found.
- .. deprecated:: 3.6
- Since Python 3.6 the support of non-integer arguments like floats or
- strings in :func:`getgrgid` is deprecated.
+ .. versionchanged:: 3.10
+ :exc:`TypeError` is raised for non-integer arguments like floats or strings.
.. function:: getgrnam(name)
302 Found
>>> data = response.read()
>>> data
- b'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>'
+ b'Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>'
>>> conn.close()
Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The
respectively), the :mailheader:`Cookie2` header is also added when appropriate.
The *request* object (usually a :class:`urllib.request.Request` instance)
- must support the methods :meth:`get_full_url`, :meth:`get_host`,
- :meth:`get_type`, :meth:`unverifiable`, :meth:`has_header`,
+ must support the methods :meth:`get_full_url`, :meth:`has_header`,
:meth:`get_header`, :meth:`header_items`, :meth:`add_unredirected_header`
- and :attr:`origin_req_host` attribute as documented by
- :mod:`urllib.request`.
+ and the attributes :attr:`host`, :attr:`!type`, :attr:`unverifiable`
+ and :attr:`origin_req_host` as documented by :mod:`urllib.request`.
.. versionchanged:: 3.3
method, which returns an :class:`email.message.Message` instance.
The *request* object (usually a :class:`urllib.request.Request` instance)
- must support the methods :meth:`get_full_url`, :meth:`get_host`,
- :meth:`unverifiable`, and :attr:`origin_req_host` attribute, as documented
- by :mod:`urllib.request`. The request is used to set default values for
- cookie-attributes as well as for checking that the cookie is allowed to be
- set.
+ must support the method :meth:`get_full_url` and the attributes
+ :attr:`host`, :attr:`unverifiable` and :attr:`origin_req_host`,
+ as documented by :mod:`urllib.request`. The request is used to set
+ default values for cookie-attributes as well as for checking that the
+ cookie is allowed to be set.
.. versionchanged:: 3.3
Open...
Open an existing file with an Open dialog.
-Recent Files
- Open a list of recent files. Click one to open it.
-
Open Module...
Open an existing module (searches sys.path).
+Recent Files
+ Open a list of recent files. Click one to open it.
+
.. index::
- single: Class browser
+ single: Module browser
single: Path browser
-Class Browser
+Module Browser
Show functions, classes, and methods in the current Editor file in a
tree structure. In the shell, open a module first.
Save As...
Save the current window with a Save As dialog. The file saved becomes the
- new associated file for the window.
+ new associated file for the window. (If your file namager is set to hide
+ extensions, the current extension will be omitted in the file name box.
+ If the new filename has no '.', '.py' and '.txt' will be added for Python
+ and text files, except that on macOS Aqua,'.py' is added for all files.)
Save Copy As...
Save the current window to different file without changing the associated
- file.
+ file. (See Save As note above about filename extensions.)
Print Window
Print the current window to the default printer.
Redo
Redo the last undone change to the current window.
+Select All
+ Select the entire contents of the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
The clipboard functions are also available in context menus.
-Select All
- Select the entire contents of the current window.
-
Find...
Open a search dialog with many options
Expand a prefix you have typed to match a full word in the same window;
repeat to get a different expansion.
-Show call tip
+Show Call Tip
After an unclosed parenthesis for a function, open a small window with
function parameter hints. See :ref:`Calltips <calltips>` in the
Editing and navigation section below.
-Show surrounding parens
+Show Surrounding Parens
Highlight the surrounding parenthesis.
.. _format-menu:
Format menu (Editor window only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Format Paragraph
+ Reformat the current blank-line-delimited paragraph in comment block or
+ multiline string or selected line in a string. All lines in the
+ paragraph will be formatted to less than N columns, where N defaults to 72.
+
Indent Region
Shift selected lines right by the indent width (default 4 spaces).
Open a dialog to change indent width. The accepted default by the Python
community is 4 spaces.
-Format Paragraph
- Reformat the current blank-line-delimited paragraph in comment block or
- multiline string or selected line in a string. All lines in the
- paragraph will be formatted to less than N columns, where N defaults to 72.
-
-Strip trailing whitespace
+Strip Trailing Chitespace
Remove trailing space and other whitespace characters after the last
non-whitespace character of a line by applying str.rstrip to each line,
including lines within multiline strings. Except for Shell windows,
See also the indent/dedent region commands on the
:ref:`Format menu <format-menu>`.
+Search and Replace
+^^^^^^^^^^^^^^^^^^
+
+Any selection becomes a search target. However, only selections within
+a line work because searches are only performed within lines with the
+terminal newline removed. If ``[x] Regular expresion`` is checked, the
+target is interpreted according to the Python re module.
+
.. _completions:
Completions
beginning of config-extensions.def in the idlelib directory for further
information. The only current default extension is zzdummy, an example
also used for testing.
+
+
+idlelib
+-------
+
+.. module:: idlelib
+ :synopsis: Implementation package for the IDLE shell/editor.
+
+**Source code:** :source:`Lib/idlelib`
+
+--------------
+
+The Lib/idlelib package implements the IDLE application. See the rest
+of this page for how to use IDLE.
+
+The files in idlelib are described in idlelib/README.txt. Access it
+either in idlelib or click Help => About IDLE on the IDLE menu. This
+file also maps IDLE menu items to the code that implements the item.
+Except for files listed under 'Startup', the idlelib code is 'private' in
+sense that feature changes can be backported (see :pep:`434`).
`JavaScript <https://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax
(although it is not a strict subset of JavaScript [#rfc-errata]_ ).
+.. warning::
+ Be cautious when parsing JSON data from untrusted sources. A malicious
+ JSON string may cause the decoder to consume considerable CPU and memory
+ resources. Limiting the size of data to be parsed is recommended.
+
:mod:`json` exposes an API familiar to users of the standard library
:mod:`marshal` and :mod:`pickle` modules.
*object_hook* is an optional function that will be called with the result of
any object literal decoded (a :class:`dict`). The return value of
*object_hook* will be used instead of the :class:`dict`. This feature can be used
- to implement custom decoders (e.g. `JSON-RPC <http://www.jsonrpc.org>`_
+ to implement custom decoders (e.g. `JSON-RPC <https://www.jsonrpc.org>`_
class hinting).
*object_pairs_hook* is an optional function that will be called with the
be used to use another datatype or parser for JSON integers
(e.g. :class:`float`).
+ .. versionchanged:: 3.10.7
+ The default *parse_int* of :func:`int` now limits the maximum length of
+ the integer string via the interpreter's :ref:`integer string
+ conversion length limitation <int_max_str_digits>` to help avoid denial
+ of service attacks.
+
*parse_constant*, if specified, will be called with one of the following
strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``.
This can be used to raise an exception if invalid JSON numbers
*object_hook*, if specified, will be called with the result of every JSON
object decoded and its return value will be used in place of the given
:class:`dict`. This can be used to provide custom deserializations (e.g. to
- support `JSON-RPC <http://www.jsonrpc.org>`_ class hinting).
+ support `JSON-RPC <https://www.jsonrpc.org>`_ class hinting).
*object_pairs_hook*, if specified will be called with the result of every
JSON object decoded with an ordered list of pairs. The return value of
the keyword arguments used in the call. The ``'()'`` also serves as a
mnemonic that the corresponding value is a callable.
+You can also specify a special key ``'.'`` whose value is a dictionary is a
+mapping of attribute names to values. If found, the specified attributes will
+be set on the user-defined object before it is returned. Thus, with the
+following configuration::
+
+ {
+ '()' : 'my.package.customFormatterFactory',
+ 'bar' : 'baz',
+ 'spam' : 99.9,
+ 'answer' : 42,
+ '.' {
+ 'foo': 'bar',
+ 'baz': 'bozz'
+ }
+ }
+
+the returned formatter will have attribute ``foo`` set to ``'bar'`` and
+attribute ``baz`` set to ``'bozz'``.
+
.. _logging-config-dict-externalobj:
[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
- style='%'
+ style=%
validate=True
class=logging.Formatter
Returns a new instance of the :class:`DatagramHandler` class intended to
communicate with a remote machine whose address is given by *host* and *port*.
+ .. note:: As UDP is not a streaming protocol, there is no persistent connection
+ between an instance of this handler and *host*. For this reason, when using a
+ network socket, a DNS lookup might have to be made each time an event is
+ logged, which can introduce some latency into the system. If this affects you,
+ you can do a lookup yourself and initialize this handler using the looked-up IP
+ address rather than the hostname.
+
.. versionchanged:: 3.4
If ``port`` is specified as ``None``, a Unix domain socket is created
using the value in ``host`` - otherwise, a UDP socket is created.
application needs to run on several platforms). On Windows, you pretty
much have to use the UDP option.
+ .. note:: On macOS 12.x (Monterey), Apple has changed the behaviour of their
+ syslog daemon - it no longer listens on a domain socket. Therefore, you cannot
+ expect :class:`SysLogHandler` to work on this system.
+
+ See :gh:`91070` for more information.
+
.. versionchanged:: 3.2
*socktype* was added.
the record to a dict or JSON string, or send a modified copy
of the record while leaving the original intact.
+ .. note:: The base implementation formats the message with arguments, sets
+ the ``message`` and ``msg`` attributes to the formatted message and
+ sets the ``args`` and ``exc_text`` attributes to ``None`` to allow
+ pickling and to prevent further attempts at formatting. This means
+ that a handler on the :class:`QueueListener` side won't have the
+ information to do custom formatting, e.g. of exceptions. You may wish
+ to subclass ``QueueHandler`` and override this method to e.g. avoid
+ setting ``exc_text`` to ``None``. Note that the ``message`` / ``msg``
+ / ``args`` changes are related to ensuring the record is pickleable,
+ and you might or might not be able to avoid doing that depending on
+ whether your ``args`` are pickleable. (Note that you may have to
+ consider not only your own code but also code in any libraries that
+ you use.)
+
.. method:: enqueue(record)
Enqueues the record on the queue using ``put_nowait()``; you may
to be done with some care, but it does allow the injection of contextual
information into logs (see :ref:`filters-contextual`).
+
.. _log-record:
LogRecord Objects
Contains all the information pertinent to the event being logged.
- The primary information is passed in :attr:`msg` and :attr:`args`, which
- are combined using ``msg % args`` to create the :attr:`message` field of the
- record.
-
- :param name: The name of the logger used to log the event represented by
- this LogRecord. Note that this name will always have this
- value, even though it may be emitted by a handler attached to
- a different (ancestor) logger.
- :param level: The numeric level of the logging event (one of DEBUG, INFO etc.)
- Note that this is converted to *two* attributes of the LogRecord:
- ``levelno`` for the numeric value and ``levelname`` for the
- corresponding level name.
- :param pathname: The full pathname of the source file where the logging call
- was made.
- :param lineno: The line number in the source file where the logging call was
- made.
- :param msg: The event description message, possibly a format string with
- placeholders for variable data.
- :param args: Variable data to merge into the *msg* argument to obtain the
- event description.
+ The primary information is passed in *msg* and *args*,
+ which are combined using ``msg % args`` to create
+ the :attr:`!message` attribute of the record.
+
+ :param name: The name of the logger used to log the event
+ represented by this :class:`!LogRecord`.
+ Note that the logger name in the :class:`!LogRecord`
+ will always have this value,
+ even though it may be emitted by a handler
+ attached to a different (ancestor) logger.
+ :type name: str
+
+ :param level: The :ref:`numeric level <levels>` of the logging event
+ (such as ``10`` for ``DEBUG``, ``20`` for ``INFO``, etc).
+ Note that this is converted to *two* attributes of the LogRecord:
+ :attr:`!levelno` for the numeric value
+ and :attr:`!levelname` for the corresponding level name.
+ :type level: int
+
+ :param pathname: The full string path of the source file
+ where the logging call was made.
+ :type pathname: str
+
+ :param lineno: The line number in the source file
+ where the logging call was made.
+ :type lineno: int
+
+ :param msg: The event description message,
+ which can be a %-format string with placeholders for variable data.
+ :type msg: str
+
+ :param args: Variable data to merge into the *msg* argument
+ to obtain the event description.
+ :type args: tuple | dict[str, typing.Any]
+
:param exc_info: An exception tuple with the current exception information,
- or ``None`` if no exception information is available.
- :param func: The name of the function or method from which the logging call
- was invoked.
- :param sinfo: A text string representing stack information from the base of
- the stack in the current thread, up to the logging call.
+ as returned by :func:`sys.exc_info`,
+ or ``None`` if no exception information is available.
+ :type exc_info: tuple[type[BaseException], BaseException, types.TracebackType] | None
+
+ :param func: The name of the function or method
+ from which the logging call was invoked.
+ :type func: str | None
+
+ :param sinfo: A text string representing stack information
+ from the base of the stack in the current thread,
+ up to the logging call.
+ :type sinfo: str | None
.. method:: getMessage()
[1, 4, 9]
+.. seealso::
+
+ :class:`concurrent.futures.ProcessPoolExecutor` offers a higher level interface
+ to push tasks to a background process without blocking execution of the
+ calling process. Compared to using the :class:`~multiprocessing.pool.Pool`
+ interface directly, the :mod:`concurrent.futures` API more readily allows
+ the submission of work to the underlying process pool to be separated from
+ waiting for the results.
+
+
The :class:`Process` class
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. class:: Rational
- Subtypes :class:`Real` and adds
- :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which
- should be in lowest terms. With these, it provides a default for
+ Subtypes :class:`Real` and adds :attr:`~Rational.numerator` and
+ :attr:`~Rational.denominator` properties. It also provides a default for
:func:`float`.
+ The :attr:`~Rational.numerator` and :attr:`~Rational.denominator` values
+ should be instances of :class:`Integral` and should be in lowest terms with
+ :attr:`~Rational.denominator` positive.
+
.. attribute:: numerator
Abstract.
.. note::
On POSIX systems, in accordance with `IEEE Std 1003.1 2013 Edition; 4.13
- Pathname Resolution <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_,
+ Pathname Resolution <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_,
if a pathname begins with exactly two slashes, the first component
following the leading characters may be interpreted in an implementation-defined
manner, although more than two leading characters shall be treated as a
.. note::
On Unix-based systems, :func:`scandir` uses the system's
- `opendir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_
+ `opendir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_
and
- `readdir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_
+ `readdir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_
functions. On Windows, it uses the Win32
`FindFirstFileW <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_
and
:py:data:`GRND_NONBLOCK`.
See also the `Linux getrandom() manual page
- <http://man7.org/linux/man-pages/man2/getrandom.2.html>`_.
+ <https://man7.org/linux/man-pages/man2/getrandom.2.html>`_.
.. availability:: Linux 3.17 and newer.
<https://en.wikipedia.org/wiki/Bootstrapping_(statistics)>`_ using resampling
with replacement to estimate a confidence interval for the mean of a sample::
- # http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm
+ # https://www.thoughtco.com/example-of-bootstrapping-3126155
from statistics import fmean as mean
from random import choices
.. note::
Applications should not
- `store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_,
+ `store passwords in a recoverable format <https://cwe.mitre.org/data/definitions/257.html>`_,
whether plain text or encrypted. They should be salted and hashed
using a cryptographically strong one-way (irreversible) hash function.
http://www.manpagez.com/man/3/copyfile/
.. _`Other Environment Variables`:
- http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003
+ https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003
.. seealso::
- `Secure File Descriptor Handling <http://udrepper.livejournal.com/20407.html>`_
+ `Secure File Descriptor Handling <https://udrepper.livejournal.com/20407.html>`_
for a more thorough explanation.
.. availability:: Linux >= 2.6.27.
**Source code:** :source:`Lib/sqlite3/`
+.. Make sure we always doctest the tutorial with an empty database.
-.. _sqlite3-intro:
+.. testsetup::
-Introduction
-------------
+ import sqlite3
+ src = sqlite3.connect(":memory:", isolation_level=None)
+ dst = sqlite3.connect("tutorial.db", isolation_level=None)
+ src.backup(dst)
+ del src, dst
+
+.. _sqlite3-intro:
SQLite is a C library that provides a lightweight disk-based database that
doesn't require a separate server process and allows accessing the database
application using SQLite and then port the code to a larger database such as
PostgreSQL or Oracle.
-The sqlite3 module was written by Gerhard Häring. It provides an SQL interface
+The :mod:`!sqlite3` module was written by Gerhard Häring. It provides an SQL interface
compliant with the DB-API 2.0 specification described by :pep:`249`, and
requires SQLite 3.7.15 or newer.
This document includes four main sections:
-* :ref:`sqlite3-tutorial` teaches how to use the sqlite3 module.
+* :ref:`sqlite3-tutorial` teaches how to use the :mod:`!sqlite3` module.
* :ref:`sqlite3-reference` describes the classes and functions this module
defines.
* :ref:`sqlite3-howtos` details how to handle specific tasks.
* :ref:`sqlite3-explanation` provides in-depth background on
transaction control.
-
-.. _sqlite3-tutorial:
-
-Tutorial
---------
-
-To use the module, start by creating a :class:`Connection` object that
-represents the database. Here the data will be stored in the
-:file:`example.db` file::
-
- import sqlite3
- con = sqlite3.connect('example.db')
-
-The special path name ``:memory:`` can be provided to create a temporary
-database in RAM.
-
-Once a :class:`Connection` has been established, create a :class:`Cursor` object
-and call its :meth:`~Cursor.execute` method to perform SQL commands::
-
- cur = con.cursor()
-
- # Create table
- cur.execute('''CREATE TABLE stocks
- (date text, trans text, symbol text, qty real, price real)''')
-
- # Insert a row of data
- cur.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")
-
- # Save (commit) the changes
- con.commit()
-
- # We can also close the connection if we are done with it.
- # Just be sure any changes have been committed or they will be lost.
- con.close()
-
-The saved data is persistent: it can be reloaded in a subsequent session even
-after restarting the Python interpreter::
-
- import sqlite3
- con = sqlite3.connect('example.db')
- cur = con.cursor()
-
-At this point, our database only contains one row::
-
- >>> res = cur.execute('SELECT count(rowid) FROM stocks')
- >>> print(res.fetchone())
- (1,)
-
-The result is a one-item :class:`tuple`:
-one row, with one column.
-Now, let us insert three more rows of data,
-using :meth:`~Cursor.executemany`::
-
- >>> data = [
- ... ('2006-03-28', 'BUY', 'IBM', 1000, 45.0),
- ... ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0),
- ... ('2006-04-06', 'SELL', 'IBM', 500, 53.0),
- ... ]
- >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data)
-
-Then, retrieve the data by iterating over the result of a ``SELECT`` statement::
-
- >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'):
- ... print(row)
-
- ('2006-01-05', 'BUY', 'RHAT', 100, 35.14)
- ('2006-03-28', 'BUY', 'IBM', 1000, 45.0)
- ('2006-04-06', 'SELL', 'IBM', 500, 53.0)
- ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)
-
-
-.. _sqlite3-placeholders:
-
-SQL operations usually need to use values from Python variables. However,
-beware of using Python's string operations to assemble queries, as they
-are vulnerable to SQL injection attacks (see the `xkcd webcomic
-<https://xkcd.com/327/>`_ for a humorous example of what can go wrong)::
-
- # Never do this -- insecure!
- symbol = 'RHAT'
- cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
-
-Instead, use the DB-API's parameter substitution. To insert a variable into a
-query string, use a placeholder in the string, and substitute the actual values
-into the query by providing them as a :class:`tuple` of values to the second
-argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may
-use one of two kinds of placeholders: question marks (qmark style) or named
-placeholders (named style). For the qmark style, ``parameters`` must be a
-:term:`sequence <sequence>`. For the named style, it can be either a
-:term:`sequence <sequence>` or :class:`dict` instance. The length of the
-:term:`sequence <sequence>` must match the number of placeholders, or a
-:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain
-keys for all named parameters. Any extra items are ignored. Here's an example of
-both styles:
-
-.. literalinclude:: ../includes/sqlite3/execute_1.py
-
-
.. seealso::
https://www.sqlite.org
PEP written by Marc-André Lemburg.
-.. _sqlite3-reference:
+.. We use the following practises for SQL code:
+ - UPPERCASE for keywords
+ - snake_case for schema
+ - single quotes for string literals
+ - singular for table names
+ - if needed, use double quotes for table and column names
-Reference
----------
+.. _sqlite3-tutorial:
-.. _sqlite3-module-contents:
+Tutorial
+--------
-Module functions and constants
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In this tutorial, you will create a database of Monty Python movies
+using basic :mod:`!sqlite3` functionality.
+It assumes a fundamental understanding of database concepts,
+including `cursors`_ and `transactions`_.
+First, we need to create a new database and open
+a database connection to allow :mod:`!sqlite3` to work with it.
+Call :func:`sqlite3.connect` to to create a connection to
+the database :file:`tutorial.db` in the current working directory,
+implicitly creating it if it does not exist:
-.. data:: apilevel
+.. testcode::
- String constant stating the supported DB-API level. Required by the DB-API.
- Hard-coded to ``"2.0"``.
+ import sqlite3
+ con = sqlite3.connect("tutorial.db")
-.. data:: paramstyle
+The returned :class:`Connection` object ``con``
+represents the connection to the on-disk database.
- String constant stating the type of parameter marker formatting expected by
- the :mod:`sqlite3` module. Required by the DB-API. Hard-coded to
- ``"qmark"``.
+In order to execute SQL statements and fetch results from SQL queries,
+we will need to use a database cursor.
+Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:
- .. note::
+.. testcode::
- The :mod:`sqlite3` module supports both ``qmark`` and ``numeric`` DB-API
- parameter styles, because that is what the underlying SQLite library
- supports. However, the DB-API does not allow multiple values for
- the ``paramstyle`` attribute.
+ cur = con.cursor()
-.. data:: version
+Now that we've got a database connection and a cursor,
+we can create a database table ``movie`` with columns for title,
+release year, and review score.
+For simplicity, we can just use column names in the table declaration --
+thanks to the `flexible typing`_ feature of SQLite,
+specifying the data types is optional.
+Execute the ``CREATE TABLE`` statement
+by calling :meth:`cur.execute(...) <Cursor.execute>`:
- Version number of this module as a :class:`string <str>`.
- This is not the version of the SQLite library.
+.. testcode::
+ cur.execute("CREATE TABLE movie(title, year, score)")
-.. data:: version_info
+.. Ideally, we'd use sqlite_schema instead of sqlite_master below,
+ but SQLite versions older than 3.33.0 do not recognise that variant.
- Version number of this module as a :class:`tuple` of :class:`integers <int>`.
- This is not the version of the SQLite library.
+We can verify that the new table has been created by querying
+the ``sqlite_master`` table built-in to SQLite,
+which should now contain an entry for the ``movie`` table definition
+(see `The Schema Table`_ for details).
+Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`,
+assign the result to ``res``,
+and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:
+.. doctest::
-.. data:: sqlite_version
+ >>> res = cur.execute("SELECT name FROM sqlite_master")
+ >>> res.fetchone()
+ ('movie',)
- Version number of the runtime SQLite library as a :class:`string <str>`.
+We can see that the table has been created,
+as the query returns a :class:`tuple` containing the table's name.
+If we query ``sqlite_master`` for a non-existent table ``spam``,
+:meth:`!res.fetchone()` will return ``None``:
+.. doctest::
-.. data:: sqlite_version_info
+ >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'")
+ >>> res.fetchone() is None
+ True
- Version number of the runtime SQLite library as a :class:`tuple` of
- :class:`integers <int>`.
+Now, add two rows of data supplied as SQL literals
+by executing an ``INSERT`` statement,
+once again by calling :meth:`cur.execute(...) <Cursor.execute>`:
+.. testcode::
-.. data:: threadsafety
+ cur.execute("""
+ INSERT INTO movie VALUES
+ ('Monty Python and the Holy Grail', 1975, 8.2),
+ ('And Now for Something Completely Different', 1971, 7.5)
+ """)
- Integer constant required by the DB-API, stating the level of thread safety
- the :mod:`sqlite3` module supports. Currently hard-coded to ``1``, meaning
- *"Threads may share the module, but not connections."* However, this may not
- always be true. You can check the underlying SQLite library's compile-time
- threaded mode using the following query::
+The ``INSERT`` statement implicitly opens a transaction,
+which needs to be committed before changes are saved in the database
+(see :ref:`sqlite3-controlling-transactions` for details).
+Call :meth:`con.commit() <Connection.commit>` on the connection object
+to commit the transaction:
- import sqlite3
- con = sqlite3.connect(":memory:")
- con.execute("""
- select * from pragma_compile_options
- where compile_options like 'THREADSAFE=%'
- """).fetchall()
+.. testcode::
- Note that the `SQLITE_THREADSAFE levels
- <https://sqlite.org/compile.html#threadsafe>`_ do not match the DB-API 2.0
- ``threadsafety`` levels.
+ con.commit()
+We can verify that the data was inserted correctly
+by executing a ``SELECT`` query.
+Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to
+assign the result to ``res``,
+and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:
-.. data:: PARSE_DECLTYPES
+.. doctest::
- Pass this flag value to the *detect_types* parameter of
- :func:`connect` to look up a converter function using
- the declared types for each column.
- The types are declared when the database table is created.
- ``sqlite3`` will look up a converter function using the first word of the
- declared type as the converter dictionary key.
- For example:
+ >>> res = cur.execute("SELECT score FROM movie")
+ >>> res.fetchall()
+ [(8.2,), (7.5,)]
+The result is a :class:`list` of two :class:`!tuple`\s, one per row,
+each containing that row's ``score`` value.
- .. code-block:: sql
+Now, insert three more rows by calling
+:meth:`cur.executemany(...) <Cursor.executemany>`:
- CREATE TABLE test(
- i integer primary key, ! will look up a converter named "integer"
- p point, ! will look up a converter named "point"
- n number(10) ! will look up a converter named "number"
- )
+.. testcode::
- This flag may be combined with :const:`PARSE_COLNAMES` using the ``|``
- (bitwise or) operator.
+ data = [
+ ("Monty Python Live at the Hollywood Bowl", 1982, 7.9),
+ ("Monty Python's The Meaning of Life", 1983, 7.5),
+ ("Monty Python's Life of Brian", 1979, 8.0),
+ ]
+ cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data)
+ con.commit() # Remember to commit the transaction after executing INSERT.
+Notice that ``?`` placeholders are used to bind ``data`` to the query.
+Always use placeholders instead of :ref:`string formatting <tut-formatting>`
+to bind Python values to SQL statements,
+to avoid `SQL injection attacks`_
+(see :ref:`sqlite3-placeholders` for more details).
-.. data:: PARSE_COLNAMES
+We can verify that the new rows were inserted
+by executing a ``SELECT`` query,
+this time iterating over the results of the query:
- Pass this flag value to the *detect_types* parameter of
- :func:`connect` to look up a converter function by
- using the type name, parsed from the query column name,
- as the converter dictionary key.
- The type name must be wrapped in square brackets (``[]``).
+.. doctest::
- .. code-block:: sql
+ >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"):
+ ... print(row)
+ (1971, 'And Now for Something Completely Different')
+ (1975, 'Monty Python and the Holy Grail')
+ (1979, "Monty Python's Life of Brian")
+ (1982, 'Monty Python Live at the Hollywood Bowl')
+ (1983, "Monty Python's The Meaning of Life")
+
+Each row is a two-item :class:`tuple` of ``(year, title)``,
+matching the columns selected in the query.
+
+Finally, verify that the database has been written to disk
+by calling :meth:`con.close() <Connection.close>`
+to close the existing connection, opening a new one,
+creating a new cursor, then querying the database:
+
+.. doctest::
+
+ >>> con.close()
+ >>> new_con = sqlite3.connect("tutorial.db")
+ >>> new_cur = new_con.cursor()
+ >>> res = new_cur.execute("SELECT title, year FROM movie ORDER BY score DESC")
+ >>> title, year = res.fetchone()
+ >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}')
+ The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975
+
+You've now created an SQLite database using the :mod:`!sqlite3` module,
+inserted data and retrieved values from it in multiple ways.
+
+.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection
+.. _The Schema Table: https://www.sqlite.org/schematab.html
+.. _cursors: https://en.wikipedia.org/wiki/Cursor_(databases)
+.. _flexible typing: https://www.sqlite.org/flextypegood.html
+.. _sqlite_master: https://www.sqlite.org/schematab.html
+.. _transactions: https://en.wikipedia.org/wiki/Database_transaction
- SELECT p as "p [point]" FROM test; ! will look up converter "point"
+.. seealso::
- This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|``
- (bitwise or) operator.
+ * :ref:`sqlite3-howtos` for further reading:
+ * :ref:`sqlite3-placeholders`
+ * :ref:`sqlite3-adapters`
+ * :ref:`sqlite3-converters`
+ * :ref:`sqlite3-connection-context-manager`
+
+ * :ref:`sqlite3-explanation` for in-depth background on transaction control.
+
+.. _sqlite3-reference:
+
+Reference
+---------
+
+.. We keep the old sqlite3-module-contents ref to prevent breaking links.
+.. _sqlite3-module-contents:
+
+.. _sqlite3-module-functions:
+Module functions
+^^^^^^^^^^^^^^^^
-.. function:: connect(database, timeout=5.0, detect_types=0, isolation_level="DEFERRED", check_same_thread=True, factory=sqlite3.Connection, cached_statements=128, uri=False)
+.. function:: connect(database, timeout=5.0, detect_types=0, \
+ isolation_level="DEFERRED", check_same_thread=True, \
+ factory=sqlite3.Connection, cached_statements=128, \
+ uri=False)
Open a connection to an SQLite database.
in RAM instead of on disk.
:type database: :term:`path-like object`
- :param timeout:
+ :param float timeout:
How many seconds the connection should wait before raising
an exception, if the database is locked by another connection.
If another connection opens a transaction to modify the database,
it will be locked until that transaction is committed.
Default five seconds.
- :type timeout: float
- :param detect_types:
+ :param int detect_types:
Control whether and how data types not
:ref:`natively supported by SQLite <sqlite3-types>`
are looked up to be converted to Python types,
even when the *detect_types* parameter is set; :class:`str` will be
returned instead.
By default (``0``), type detection is disabled.
- :type detect_types: int
:param isolation_level:
The :attr:`~Connection.isolation_level` of the connection,
controlling whether and how transactions are implicitly opened.
Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``;
- or :const:`None` to disable opening transactions implicitly.
+ or ``None`` to disable opening transactions implicitly.
See :ref:`sqlite3-controlling-transactions` for more.
- :type isolation_level: str | :const:`None`
+ :type isolation_level: str | None
- :param check_same_thread:
- If :const:`True` (default), only the creating thread may use the connection.
- If :const:`False`, the connection may be shared across multiple threads;
+ :param bool check_same_thread:
+ If ``True`` (default), only the creating thread may use the connection.
+ If ``False``, the connection may be shared across multiple threads;
if so, write operations should be serialized by the user to avoid data
corruption.
- :type check_same_thread: bool
- :param factory:
+ :param Connection factory:
A custom subclass of :class:`Connection` to create the connection with,
if not the default :class:`Connection` class.
- :type factory: :class:`Connection`
- :param cached_statements:
- The number of statements that ``sqlite3``
+ :param int cached_statements:
+ The number of statements that :mod:`!sqlite3`
should internally cache for this connection, to avoid parsing overhead.
By default, 100 statements.
- :type cached_statements: int
- :param uri:
- If set to :const:`True`, *database* is interpreted as a
+ :param bool uri:
+ If set to ``True``, *database* is interpreted as a
:abbr:`URI (Uniform Resource Identifier)` with a file path
and an optional query string.
The scheme part *must* be ``"file:"``,
and the path can be relative or absolute.
The query string allows passing parameters to SQLite,
enabling various :ref:`sqlite3-uri-tricks`.
- :type uri: bool
:rtype: Connection
.. versionadded:: 3.10
The ``sqlite3.connect/handle`` auditing event.
+.. function:: complete_statement(statement)
+
+ Return ``True`` if the string *statement* appears to contain
+ one or more complete SQL statements.
+ No syntactic verification or parsing of any kind is performed,
+ other than checking that there are no unclosed string literals
+ and the statement is terminated by a semicolon.
+
+ For example:
+
+ .. doctest::
+
+ >>> sqlite3.complete_statement("SELECT foo FROM bar;")
+ True
+ >>> sqlite3.complete_statement("SELECT foo")
+ False
+
+ This function may be useful during command-line input
+ to determine if the entered text seems to form a complete SQL statement,
+ or if additional input is needed before calling :meth:`~Cursor.execute`.
+
+.. function:: enable_callback_tracebacks(flag, /)
+
+ Enable or disable callback tracebacks.
+ By default you will not get any tracebacks in user-defined functions,
+ aggregates, converters, authorizer callbacks etc. If you want to debug them,
+ you can call this function with *flag* set to ``True``. Afterwards, you will
+ get tracebacks from callbacks on ``sys.stderr``. Use ``False`` to
+ disable the feature again.
+
+.. function:: register_adapter(type, adapter, /)
+
+ Register an *adapter* callable to adapt the Python type *type* into an
+ SQLite type.
+ The adapter is called with a Python object of type *type* as its sole
+ argument, and must return a value of a
+ :ref:`type that SQLite natively understands <sqlite3-types>`.
.. function:: register_converter(typename, converter, /)
case-insensitively.
-.. function:: register_adapter(type, adapter, /)
+.. _sqlite3-module-constants:
- Register an *adapter* callable to adapt the Python type *type* into an
- SQLite type.
- The adapter is called with a Python object of type *type* as its sole
- argument, and must return a value of a
- :ref:`type that SQLite natively understands<sqlite3-types>`.
+Module constants
+^^^^^^^^^^^^^^^^
+.. data:: PARSE_COLNAMES
-.. function:: complete_statement(statement)
+ Pass this flag value to the *detect_types* parameter of
+ :func:`connect` to look up a converter function by
+ using the type name, parsed from the query column name,
+ as the converter dictionary key.
+ The type name must be wrapped in square brackets (``[]``).
- Returns :const:`True` if the string *statement* contains one or more complete SQL
- statements terminated by semicolons. It does not verify that the SQL is
- syntactically correct, only that there are no unclosed string literals and the
- statement is terminated by a semicolon.
+ .. code-block:: sql
- This can be used to build a shell for SQLite, as in the following example:
+ SELECT p as "p [point]" FROM test; ! will look up converter "point"
+ This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|``
+ (bitwise or) operator.
- .. literalinclude:: ../includes/sqlite3/complete_statement.py
+.. data:: PARSE_DECLTYPES
+ Pass this flag value to the *detect_types* parameter of
+ :func:`connect` to look up a converter function using
+ the declared types for each column.
+ The types are declared when the database table is created.
+ :mod:`!sqlite3` will look up a converter function using the first word of the
+ declared type as the converter dictionary key.
+ For example:
-.. function:: enable_callback_tracebacks(flag, /)
+ .. code-block:: sql
- Enable or disable callback tracebacks.
- By default you will not get any tracebacks in user-defined functions,
- aggregates, converters, authorizer callbacks etc. If you want to debug them,
- you can call this function with *flag* set to ``True``. Afterwards, you will
- get tracebacks from callbacks on ``sys.stderr``. Use :const:`False` to
- disable the feature again.
+ CREATE TABLE test(
+ i integer primary key, ! will look up a converter named "integer"
+ p point, ! will look up a converter named "point"
+ n number(10) ! will look up a converter named "number"
+ )
+
+ This flag may be combined with :const:`PARSE_COLNAMES` using the ``|``
+ (bitwise or) operator.
+
+.. data:: SQLITE_OK
+ SQLITE_DENY
+ SQLITE_IGNORE
+
+ Flags that should be returned by the *authorizer_callback* callable
+ passed to :meth:`Connection.set_authorizer`, to indicate whether:
+
+ * Access is allowed (:const:`!SQLITE_OK`),
+ * The SQL statement should be aborted with an error (:const:`!SQLITE_DENY`)
+ * The column should be treated as a ``NULL`` value (:const:`!SQLITE_IGNORE`)
+
+.. data:: apilevel
+
+ String constant stating the supported DB-API level. Required by the DB-API.
+ Hard-coded to ``"2.0"``.
+
+.. data:: paramstyle
+
+ String constant stating the type of parameter marker formatting expected by
+ the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to
+ ``"qmark"``.
+
+ .. note::
+
+ The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API
+ parameter styles, because that is what the underlying SQLite library
+ supports. However, the DB-API does not allow multiple values for
+ the ``paramstyle`` attribute.
+
+.. data:: sqlite_version
+
+ Version number of the runtime SQLite library as a :class:`string <str>`.
+
+.. data:: sqlite_version_info
+
+ Version number of the runtime SQLite library as a :class:`tuple` of
+ :class:`integers <int>`.
+
+.. data:: threadsafety
+
+ Integer constant required by the DB-API, stating the level of thread safety
+ the :mod:`!sqlite3` module supports. Currently hard-coded to ``1``, meaning
+ *"Threads may share the module, but not connections."* However, this may not
+ always be true. You can check the underlying SQLite library's compile-time
+ threaded mode using the following query::
+
+ import sqlite3
+ con = sqlite3.connect(":memory:")
+ con.execute("""
+ select * from pragma_compile_options
+ where compile_options like 'THREADSAFE=%'
+ """).fetchall()
+
+ Note that the `SQLITE_THREADSAFE levels
+ <https://sqlite.org/compile.html#threadsafe>`_ do not match the DB-API 2.0
+ ``threadsafety`` levels.
+
+.. data:: version
+
+ Version number of this module as a :class:`string <str>`.
+ This is not the version of the SQLite library.
+
+.. data:: version_info
+
+ Version number of this module as a :class:`tuple` of :class:`integers <int>`.
+ This is not the version of the SQLite library.
.. _sqlite3-connection-objects:
.. attribute:: isolation_level
This attribute controls the :ref:`transaction handling
- <sqlite3-controlling-transactions>` performed by ``sqlite3``.
- If set to :const:`None`, transactions are never implicitly opened.
+ <sqlite3-controlling-transactions>` performed by :mod:`!sqlite3`.
+ If set to ``None``, transactions are never implicitly opened.
If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``,
corresponding to the underlying `SQLite transaction behaviour`_,
implicit :ref:`transaction management
This read-only attribute corresponds to the low-level SQLite
`autocommit mode`_.
- :const:`True` if a transaction is active (there are uncommitted changes),
- :const:`False` otherwise.
+ ``True`` if a transaction is active (there are uncommitted changes),
+ ``False`` otherwise.
+
+ .. versionadded:: 3.2
+
+ .. attribute:: row_factory
+
+ A callable that accepts two arguments,
+ a :class:`Cursor` object and the raw row results as a :class:`tuple`,
+ and returns a custom object representing an SQLite row.
+
+ Example:
+
+ .. doctest::
+
+ >>> def dict_factory(cursor, row):
+ ... col_names = [col[0] for col in cursor.description]
+ ... return {key: value for key, value in zip(col_names, row)}
+ >>> con = sqlite3.connect(":memory:")
+ >>> con.row_factory = dict_factory
+ >>> for row in con.execute("SELECT 1 AS a, 2 AS b"):
+ ... print(row)
+ {'a': 1, 'b': 2}
+
+ If returning a tuple doesn't suffice and you want name-based access to
+ columns, you should consider setting :attr:`row_factory` to the
+ highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both
+ index-based and case-insensitive name-based access to columns with almost no
+ memory overhead. It will probably be better than your own custom
+ dictionary-based approach or even a db_row based solution.
+
+ .. XXX what's a db_row-based solution?
+
+ .. attribute:: text_factory
+
+ A callable that accepts a :class:`bytes` parameter and returns a text
+ representation of it.
+ The callable is invoked for SQLite values with the ``TEXT`` data type.
+ By default, this attribute is set to :class:`str`.
+ If you want to return ``bytes`` instead, set *text_factory* to ``bytes``.
+
+ Example:
+
+ .. testcode::
+
+ con = sqlite3.connect(":memory:")
+ cur = con.cursor()
+
+ AUSTRIA = "Österreich"
+
+ # by default, rows are returned as str
+ cur.execute("SELECT ?", (AUSTRIA,))
+ row = cur.fetchone()
+ assert row[0] == AUSTRIA
+
+ # but we can make sqlite3 always return bytestrings ...
+ con.text_factory = bytes
+ cur.execute("SELECT ?", (AUSTRIA,))
+ row = cur.fetchone()
+ assert type(row[0]) is bytes
+ # the bytestrings will be encoded in UTF-8, unless you stored garbage in the
+ # database ...
+ assert row[0] == AUSTRIA.encode("utf-8")
+
+ # we can also implement a custom text_factory ...
+ # here we implement one that appends "foo" to all strings
+ con.text_factory = lambda x: x.decode("utf-8") + "foo"
+ cur.execute("SELECT ?", ("bar",))
+ row = cur.fetchone()
+ assert row[0] == "barfoo"
+
+ con.close()
+
+ .. attribute:: total_changes
+
+ Return the total number of database rows that have been modified, inserted, or
+ deleted since the database connection was opened.
- .. versionadded:: 3.2
.. method:: cursor(factory=Cursor)
:meth:`~Cursor.executescript` on it with the given *sql_script*.
Return the new cursor object.
- .. method:: create_function(name, narg, func, *, deterministic=False)
+ .. method:: create_function(name, narg, func, \*, deterministic=False)
Create or remove a user-defined SQL function.
- :param name:
+ :param str name:
The name of the SQL function.
- :type name: str
- :param narg:
+ :param int narg:
The number of arguments the SQL function can accept.
If ``-1``, it may take any number of arguments.
- :type narg: int
:param func:
A callable that is called when the SQL function is invoked.
The callable must return :ref:`a type natively supported by SQLite
<sqlite3-types>`.
- Set to :const:`None` to remove an existing SQL function.
- :type func: :term:`callback` | :const:`None`
+ Set to ``None`` to remove an existing SQL function.
+ :type func: :term:`callback` | None
- :param deterministic:
- If :const:`True`, the created SQL function is marked as
+ :param bool deterministic:
+ If ``True``, the created SQL function is marked as
`deterministic <https://sqlite.org/deterministic.html>`_,
which allows SQLite to perform additional optimizations.
- :type deterministic: bool
:raises NotSupportedError:
If *deterministic* is used with SQLite versions older than 3.8.3.
Example:
- .. literalinclude:: ../includes/sqlite3/md5func.py
+ .. doctest::
+
+ >>> import hashlib
+ >>> def md5sum(t):
+ ... return hashlib.md5(t).hexdigest()
+ >>> con = sqlite3.connect(":memory:")
+ >>> con.create_function("md5", 1, md5sum)
+ >>> for row in con.execute("SELECT md5(?)", (b"foo",)):
+ ... print(row)
+ ('acbd18db4cc2f85cedef654fccc4a4d8',)
.. method:: create_aggregate(name, /, n_arg, aggregate_class)
Create or remove a user-defined SQL aggregate function.
- :param name:
+ :param str name:
The name of the SQL aggregate function.
- :type name: str
- :param n_arg:
+ :param int n_arg:
The number of arguments the SQL aggregate function can accept.
If ``-1``, it may take any number of arguments.
- :type n_arg: int
:param aggregate_class:
A class must implement the following methods:
The number of arguments that the ``step()`` method must accept
is controlled by *n_arg*.
- Set to :const:`None` to remove an existing SQL aggregate function.
- :type aggregate_class: :term:`class` | :const:`None`
+ Set to ``None`` to remove an existing SQL aggregate function.
+ :type aggregate_class: :term:`class` | None
Example:
- .. literalinclude:: ../includes/sqlite3/mysumaggr.py
+ .. testcode::
+
+ class MySum:
+ def __init__(self):
+ self.count = 0
+
+ def step(self, value):
+ self.count += value
+
+ def finalize(self):
+ return self.count
+
+ con = sqlite3.connect(":memory:")
+ con.create_aggregate("mysum", 1, MySum)
+ cur = con.execute("CREATE TABLE test(i)")
+ cur.execute("INSERT INTO test(i) VALUES(1)")
+ cur.execute("INSERT INTO test(i) VALUES(2)")
+ cur.execute("SELECT mysum(i) FROM test")
+ print(cur.fetchone()[0])
+
+ con.close()
+
+ .. testoutput::
+ :hide:
+
+ 3
.. method:: create_collation(name, callable)
The following example shows a reverse sorting collation:
- .. literalinclude:: ../includes/sqlite3/collation_reverse.py
+ .. testcode::
+
+ def collate_reverse(string1, string2):
+ if string1 == string2:
+ return 0
+ elif string1 < string2:
+ return 1
+ else:
+ return -1
+
+ con = sqlite3.connect(":memory:")
+ con.create_collation("reverse", collate_reverse)
+
+ cur = con.execute("CREATE TABLE test(x)")
+ cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)])
+ cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse")
+ for row in cur:
+ print(row)
+ con.close()
+
+ .. testoutput::
+ :hide:
- Remove a collation function by setting *callable* to :const:`None`.
+ ('b',)
+ ('a',)
+
+ Remove a collation function by setting *callable* to ``None``.
.. method:: interrupt()
Register callable *authorizer_callback* to be invoked for each attempt to
access a column of a table in the database. The callback should return
- :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL
- statement should be aborted with an error and :const:`SQLITE_IGNORE` if the
- column should be treated as a NULL value. These constants are available in the
- :mod:`sqlite3` module.
+ one of :const:`SQLITE_OK`, :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE`
+ to signal how access to the column should be handled
+ by the underlying SQLite library.
The first argument to the callback signifies what kind of operation is to be
- authorized. The second and third argument will be arguments or :const:`None`
+ authorized. The second and third argument will be arguments or ``None``
depending on the first argument. The 4th argument is the name of the database
("main", "temp", etc.) if applicable. The 5th argument is the name of the
inner-most trigger or view that is responsible for the access attempt or
- :const:`None` if this access attempt is directly from input SQL code.
+ ``None`` if this access attempt is directly from input SQL code.
Please consult the SQLite documentation about the possible values for the first
argument and the meaning of the second and third argument depending on the first
- one. All necessary constants are available in the :mod:`sqlite3` module.
+ one. All necessary constants are available in the :mod:`!sqlite3` module.
.. method:: set_progress_handler(progress_handler, n)
a GUI.
If you want to clear any previously installed progress handler, call the
- method with :const:`None` for *progress_handler*.
+ method with ``None`` for *progress_handler*.
Returning a non-zero value from the handler function will terminate the
currently executing query and cause it to raise an :exc:`OperationalError`
ignored. Note that the backend does not only run statements passed to the
:meth:`Cursor.execute` methods. Other sources include the
:ref:`transaction management <sqlite3-controlling-transactions>` of the
- sqlite3 module and the execution of triggers defined in the current
+ :mod:`!sqlite3` module and the execution of triggers defined in the current
database.
- Passing :const:`None` as *trace_callback* will disable the trace callback.
+ Passing ``None`` as *trace_callback* will disable the trace callback.
.. note::
Exceptions raised in the trace callback are not propagated. As a
.. method:: enable_load_extension(enabled, /)
Enable the SQLite engine to load SQLite extensions from shared libraries
- if *enabled* is :const:`True`;
+ if *enabled* is ``True``;
else, disallow loading SQLite extensions.
SQLite extensions can define new functions,
aggregates or whole new virtual table implementations. One well-known
.. note::
- The ``sqlite3`` module is not built with loadable extension support by
+ The :mod:`!sqlite3` module is not built with loadable extension support by
default, because some platforms (notably macOS) have SQLite
libraries which are compiled without this feature.
To get loadable extension support,
.. versionchanged:: 3.10
Added the ``sqlite3.enable_load_extension`` auditing event.
- .. literalinclude:: ../includes/sqlite3/load_extension.py
-
- .. method:: load_extension(path, /)
-
- Load an SQLite extension from a shared library located at *path*.
- Enable extension loading with :meth:`enable_load_extension` before
- calling this method.
-
- .. audit-event:: sqlite3.load_extension connection,path sqlite3.Connection.load_extension
-
- .. versionadded:: 3.2
-
- .. versionchanged:: 3.10
- Added the ``sqlite3.load_extension`` auditing event.
+ .. testsetup:: sqlite3.loadext
- .. attribute:: row_factory
+ import sqlite3
+ con = sqlite3.connect(":memory:")
- A callable that accepts two arguments,
- a :class:`Cursor` object and the raw row results as a :class:`tuple`,
- and returns a custom object representing an SQLite row.
+ .. testcode:: sqlite3.loadext
+ :skipif: True # not testable at the moment
- Example:
+ con.enable_load_extension(True)
- .. literalinclude:: ../includes/sqlite3/row_factory.py
+ # Load the fulltext search extension
+ con.execute("select load_extension('./fts3.so')")
- If returning a tuple doesn't suffice and you want name-based access to
- columns, you should consider setting :attr:`row_factory` to the
- highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both
- index-based and case-insensitive name-based access to columns with almost no
- memory overhead. It will probably be better than your own custom
- dictionary-based approach or even a db_row based solution.
+ # alternatively you can load the extension using an API call:
+ # con.load_extension("./fts3.so")
- .. XXX what's a db_row-based solution?
+ # disable extension loading again
+ con.enable_load_extension(False)
+ # example from SQLite wiki
+ con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)")
+ con.executescript("""
+ INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes');
+ INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery');
+ INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour');
+ INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter');
+ """)
+ for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"):
+ print(row)
- .. attribute:: text_factory
+ con.close()
- A callable that accepts a :class:`bytes` parameter and returns a text
- representation of it.
- The callable is invoked for SQLite values with the ``TEXT`` data type.
- By default, this attribute is set to :class:`str`.
- If you want to return ``bytes`` instead, set *text_factory* to ``bytes``.
+ .. testoutput:: sqlite3.loadext
+ :hide:
- Example:
+ (2, 'broccoli pie', 'broccoli cheese onions flour')
+ (3, 'pumpkin pie', 'pumpkin sugar flour butter')
- .. literalinclude:: ../includes/sqlite3/text_factory.py
+ .. method:: load_extension(path, /)
+ Load an SQLite extension from a shared library located at *path*.
+ Enable extension loading with :meth:`enable_load_extension` before
+ calling this method.
- .. attribute:: total_changes
+ .. audit-event:: sqlite3.load_extension connection,path sqlite3.Connection.load_extension
- Return the total number of database rows that have been modified, inserted, or
- deleted since the database connection was opened.
+ .. versionadded:: 3.2
+ .. versionchanged:: 3.10
+ Added the ``sqlite3.load_extension`` auditing event.
.. method:: iterdump
Useful when saving an in-memory database for later restoration.
Similar to the ``.dump`` command in the :program:`sqlite3` shell.
- Example::
+ Example:
- # Convert file existing_db.db to SQL dump file dump.sql
- import sqlite3
+ .. testcode::
- con = sqlite3.connect('existing_db.db')
+ # Convert file example.db to SQL dump file dump.sql
+ con = sqlite3.connect('example.db')
with open('dump.sql', 'w') as f:
for line in con.iterdump():
f.write('%s\n' % line)
con.close()
- .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250)
+ .. method:: backup(target, \*, pages=-1, progress=None, name="main", sleep=0.250)
Create a backup of an SQLite database.
Works even if the database is being accessed by other clients
or concurrently by the same connection.
- :param target:
+ :param Connection target:
The database connection to save the backup to.
- :type target: Connection
- :param pages:
+ :param int pages:
The number of pages to copy at a time.
If equal to or less than ``0``,
the entire database is copied in a single step.
Defaults to ``-1``.
- :type pages: int
:param progress:
If set to a callable, it is invoked with three integer arguments for
the *status* of the last iteration,
the *remaining* number of pages still to be copied,
and the *total* number of pages.
- Defaults to :const:`None`.
- :type progress: :term:`callback` | :const:`None`
+ Defaults to ``None``.
+ :type progress: :term:`callback` | None
- :param name:
+ :param str name:
The name of the database to back up.
Either ``"main"`` (the default) for the main database,
``"temp"`` for the temporary database,
or the name of a custom database as attached using the
- ``ATTACH DATABASE`` SQL statment.
- :type name: str
+ ``ATTACH DATABASE`` SQL statement.
- :param sleep:
+ :param float sleep:
The number of seconds to sleep between successive attempts
to back up remaining pages.
- :type sleep: float
- Example 1, copy an existing database into another::
+ Example 1, copy an existing database into another:
- import sqlite3
+ .. testcode::
def progress(status, remaining, total):
print(f'Copied {total-remaining} of {total} pages...')
- con = sqlite3.connect('existing_db.db')
- bck = sqlite3.connect('backup.db')
- with bck:
- con.backup(bck, pages=1, progress=progress)
- bck.close()
- con.close()
+ src = sqlite3.connect('example.db')
+ dst = sqlite3.connect('backup.db')
+ with dst:
+ src.backup(dst, pages=1, progress=progress)
+ dst.close()
+ src.close()
- Example 2, copy an existing database into a transient copy::
+ .. testoutput::
+ :hide:
- import sqlite3
+ Copied 0 of 0 pages...
+
+ Example 2, copy an existing database into a transient copy:
- source = sqlite3.connect('existing_db.db')
- dest = sqlite3.connect(':memory:')
- source.backup(dest)
+ .. testcode::
+
+ src = sqlite3.connect('example.db')
+ dst = sqlite3.connect(':memory:')
+ src.backup(dst)
.. versionadded:: 3.7
Cursor objects are :term:`iterators <iterator>`,
meaning that if you :meth:`~Cursor.execute` a ``SELECT`` query,
- you can simply iterate over the cursor to fetch the resulting rows::
+ you can simply iterate over the cursor to fetch the resulting rows:
+
+ .. testsetup:: sqlite3.cursor
+
+ import sqlite3
+ con = sqlite3.connect(":memory:", isolation_level=None)
+ cur = con.execute("CREATE TABLE data(t)")
+ cur.execute("INSERT INTO data VALUES(1)")
+
+ .. testcode:: sqlite3.cursor
- for row in cur.execute("select * from data"):
+ for row in cur.execute("SELECT t FROM data"):
print(row)
+ .. testoutput:: sqlite3.cursor
+ :hide:
+
+ (1,)
+
.. _database cursor: https://en.wikipedia.org/wiki/Cursor_(databases)
.. class:: Cursor
:meth:`executescript` if you want to execute multiple SQL statements with one
call.
- If :attr:`~Connection.isolation_level` is not :const:`None`,
+ If :attr:`~Connection.isolation_level` is not ``None``,
*sql* is an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement,
and there is no open transaction,
a transaction is implicitly opened before executing *sql*.
:term:`iterator` yielding parameters instead of a sequence.
Uses the same implicit transaction handling as :meth:`~Cursor.execute`.
- Example::
+ Example:
+
+ .. testcode:: sqlite3.cursor
- data = [
- ("row1",),
- ("row2",),
- ]
- # cur is an sqlite3.Cursor object
- cur.executemany("insert into t values(?)", data)
+ rows = [
+ ("row1",),
+ ("row2",),
+ ]
+ # cur is an sqlite3.Cursor object
+ cur.executemany("INSERT INTO data VALUES(?)", rows)
.. method:: executescript(sql_script, /)
Execute the SQL statements in *sql_script*.
- If there is a pending transaciton,
+ If there is a pending transaction,
an implicit ``COMMIT`` statement is executed first.
No other implicit transaction control is performed;
any transaction control must be added to *sql_script*.
*sql_script* must be a :class:`string <str>`.
- Example::
+ Example:
+
+ .. testcode:: sqlite3.cursor
# cur is an sqlite3.Cursor object
cur.executescript("""
- begin;
- create table person(firstname, lastname, age);
- create table book(title, author, published);
- create table publisher(name, address);
- commit;
+ BEGIN;
+ CREATE TABLE person(firstname, lastname, age);
+ CREATE TABLE book(title, author, published);
+ CREATE TABLE publisher(name, address);
+ COMMIT;
""")
.. method:: fetchone()
- Fetch the next row of a query result set as a :class:`tuple`.
- Return :const:`None` if no more data is available.
+ Return the next row of a query result set as a :class:`tuple`.
+ Return ``None`` if no more data is available.
.. method:: fetchmany(size=cursor.arraysize)
- Fetch the next set of rows of a query result as a :class:`list`.
+ Return the next set of rows of a query result as a :class:`list`.
Return an empty list if no more rows are available.
The number of rows to fetch per call is specified by the *size* parameter.
.. method:: fetchall()
- Fetch all (remaining) rows of a query result as a :class:`list`.
+ Return all (remaining) rows of a query result as a :class:`list`.
Return an empty list if no rows are available.
Note that the :attr:`arraysize` attribute can affect the performance of
this operation.
.. method:: setinputsizes(sizes, /)
- Required by the DB-API. Does nothing in :mod:`sqlite3`.
+ Required by the DB-API. Does nothing in :mod:`!sqlite3`.
.. method:: setoutputsize(size, column=None, /)
- Required by the DB-API. Does nothing in :mod:`sqlite3`.
+ Required by the DB-API. Does nothing in :mod:`!sqlite3`.
- .. attribute:: rowcount
+ .. attribute:: arraysize
- Read-only attribute that provides the number of modified rows for
- ``INSERT``, ``UPDATE``, ``DELETE``, and ``REPLACE`` statements;
- is ``-1`` for other statements,
- including :abbr:`CTE (Common Table Expression)` queries.
- It is only updated by the :meth:`execute` and :meth:`executemany` methods.
+ Read/write attribute that controls the number of rows returned by :meth:`fetchmany`.
+ The default value is 1 which means a single row would be fetched per call.
+
+ .. attribute:: connection
+
+ Read-only attribute that provides the SQLite database :class:`Connection`
+ belonging to the cursor. A :class:`Cursor` object created by
+ calling :meth:`con.cursor() <Connection.cursor>` will have a
+ :attr:`connection` attribute that refers to *con*:
+
+ .. doctest::
+
+ >>> con = sqlite3.connect(":memory:")
+ >>> cur = con.cursor()
+ >>> cur.connection == con
+ True
+
+ .. attribute:: description
+
+ Read-only attribute that provides the column names of the last query. To
+ remain compatible with the Python DB API, it returns a 7-tuple for each
+ column where the last six items of each tuple are ``None``.
+
+ It is set for ``SELECT`` statements without any matching rows as well.
.. attribute:: lastrowid
using the :meth:`execute` method. For other statements, after
:meth:`executemany` or :meth:`executescript`, or if the insertion failed,
the value of ``lastrowid`` is left unchanged. The initial value of
- ``lastrowid`` is :const:`None`.
+ ``lastrowid`` is ``None``.
.. note::
Inserts into ``WITHOUT ROWID`` tables are not recorded.
.. versionchanged:: 3.6
Added support for the ``REPLACE`` statement.
- .. attribute:: arraysize
-
- Read/write attribute that controls the number of rows returned by :meth:`fetchmany`.
- The default value is 1 which means a single row would be fetched per call.
-
- .. attribute:: description
-
- Read-only attribute that provides the column names of the last query. To
- remain compatible with the Python DB API, it returns a 7-tuple for each
- column where the last six items of each tuple are :const:`None`.
-
- It is set for ``SELECT`` statements without any matching rows as well.
+ .. attribute:: rowcount
- .. attribute:: connection
+ Read-only attribute that provides the number of modified rows for
+ ``INSERT``, ``UPDATE``, ``DELETE``, and ``REPLACE`` statements;
+ is ``-1`` for other statements,
+ including :abbr:`CTE (Common Table Expression)` queries.
+ It is only updated by the :meth:`execute` and :meth:`executemany` methods.
- Read-only attribute that provides the SQLite database :class:`Connection`
- belonging to the cursor. A :class:`Cursor` object created by
- calling :meth:`con.cursor() <Connection.cursor>` will have a
- :attr:`connection` attribute that refers to *con*::
- >>> con = sqlite3.connect(":memory:")
- >>> cur = con.cursor()
- >>> cur.connection == con
- True
+.. The sqlite3.Row example used to be a how-to. It has now been incorporated
+ into the Row reference. We keep the anchor here in order not to break
+ existing links.
+.. _sqlite3-columns-by-name:
.. _sqlite3-row-objects:
Row objects
.. class:: Row
- A :class:`Row` instance serves as a highly optimized
+ A :class:`!Row` instance serves as a highly optimized
:attr:`~Connection.row_factory` for :class:`Connection` objects.
- It tries to mimic a :class:`tuple` in most of its features,
- and supports iteration, :func:`repr`, equality testing, :func:`len`,
+ It supports iteration, equality testing, :func:`len`,
and :term:`mapping` access by column name and index.
Two row objects compare equal if have equal columns and equal members.
.. versionchanged:: 3.5
Added support of slicing.
-Let's assume we initialize a table as in the example given above::
+ Example:
- con = sqlite3.connect(":memory:")
- cur = con.cursor()
- cur.execute('''create table stocks
- (date text, trans text, symbol text,
- qty real, price real)''')
- cur.execute("""insert into stocks
- values ('2006-01-05','BUY','RHAT',100,35.14)""")
- con.commit()
- cur.close()
+ .. doctest::
-Now we plug :class:`Row` in::
-
- >>> con.row_factory = sqlite3.Row
- >>> cur = con.cursor()
- >>> cur.execute('select * from stocks')
- <sqlite3.Cursor object at 0x7f4e7dd8fa80>
- >>> r = cur.fetchone()
- >>> type(r)
- <class 'sqlite3.Row'>
- >>> tuple(r)
- ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)
- >>> len(r)
- 5
- >>> r[2]
- 'RHAT'
- >>> r.keys()
- ['date', 'trans', 'symbol', 'qty', 'price']
- >>> r['qty']
- 100.0
- >>> for member in r:
- ... print(member)
- ...
- 2006-01-05
- BUY
- RHAT
- 100.0
- 35.14
+ >>> con = sqlite3.connect(":memory:")
+ >>> con.row_factory = sqlite3.Row
+ >>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius")
+ >>> row = res.fetchone()
+ >>> row.keys()
+ ['name', 'radius']
+ >>> row[0], row["name"] # Access by index and name.
+ ('Earth', 'Earth')
+ >>> row["RADIUS"] # Column names are case-insensitive.
+ 6378
PrepareProtocol objects
.. exception:: Warning
- This exception is raised by ``sqlite3`` if an SQL query is not a
+ This exception is raised by :mod:`!sqlite3` if an SQL query is not a
:class:`string <str>`, or if multiple statements are passed to
:meth:`~Cursor.execute` or :meth:`~Cursor.executemany`.
``Warning`` is a subclass of :exc:`Exception`.
.. exception:: InterfaceError
- This exception is raised by ``sqlite3`` for fetch across rollback,
- or if ``sqlite3`` is unable to bind parameters.
+ This exception is raised by :mod:`!sqlite3` for fetch across rollback,
+ or if :mod:`!sqlite3` is unable to bind parameters.
``InterfaceError`` is a subclass of :exc:`Error`.
.. exception:: DatabaseError
.. exception:: ProgrammingError
- Exception raised for ``sqlite3`` API programming errors,
+ Exception raised for :mod:`!sqlite3` API programming errors,
for example trying to operate on a closed :class:`Connection`,
or trying to execute non-DML statements with :meth:`~Cursor.executemany`.
``ProgrammingError`` is a subclass of :exc:`DatabaseError`.
Exception raised in case a method or database API is not supported by the
underlying SQLite library. For example, setting *deterministic* to
- :const:`True` in :meth:`~Connection.create_function`, if the underlying SQLite library
+ ``True`` in :meth:`~Connection.create_function`, if the underlying SQLite library
does not support deterministic functions.
``NotSupportedError`` is a subclass of :exc:`DatabaseError`.
+-------------------------------+-------------+
| Python type | SQLite type |
+===============================+=============+
-| :const:`None` | ``NULL`` |
+| ``None`` | ``NULL`` |
+-------------------------------+-------------+
| :class:`int` | ``INTEGER`` |
+-------------------------------+-------------+
+-------------+----------------------------------------------+
| SQLite type | Python type |
+=============+==============================================+
-| ``NULL`` | :const:`None` |
+| ``NULL`` | ``None`` |
+-------------+----------------------------------------------+
| ``INTEGER`` | :class:`int` |
+-------------+----------------------------------------------+
| ``BLOB`` | :class:`bytes` |
+-------------+----------------------------------------------+
-The type system of the :mod:`sqlite3` module is extensible in two ways: you can
+The type system of the :mod:`!sqlite3` module is extensible in two ways: you can
store additional Python types in an SQLite database via
:ref:`object adapters <sqlite3-adapters>`,
-and you can let the ``sqlite3`` module convert SQLite types to
+and you can let the :mod:`!sqlite3` module convert SQLite types to
Python types via :ref:`converters <sqlite3-converters>`.
+.. _sqlite3-default-converters:
+
+Default adapters and converters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are default adapters for the date and datetime types in the datetime
+module. They will be sent as ISO dates/ISO timestamps to SQLite.
+
+The default converters are registered under the name "date" for
+:class:`datetime.date` and under the name "timestamp" for
+:class:`datetime.datetime`.
+
+This way, you can use date/timestamps from Python without any additional
+fiddling in most cases. The format of the adapters is also compatible with the
+experimental SQLite date/time functions.
+
+The following example demonstrates this.
+
+.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py
+
+If a timestamp stored in SQLite has a fractional part longer than 6
+numbers, its value will be truncated to microsecond precision by the
+timestamp converter.
+
+.. note::
+
+ The default "timestamp" converter ignores UTC offsets in the database and
+ always returns a naive :class:`datetime.datetime` object. To preserve UTC
+ offsets in timestamps, either leave converters disabled, or register an
+ offset-aware converter with :func:`register_converter`.
+
+
.. _sqlite3-howtos:
How-to guides
-------------
+.. _sqlite3-placeholders:
+
+How to use placeholders to bind values in SQL queries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+SQL operations usually need to use values from Python variables. However,
+beware of using Python's string operations to assemble queries, as they
+are vulnerable to `SQL injection attacks`_ (see the `xkcd webcomic
+<https://xkcd.com/327/>`_ for a humorous example of what can go wrong)::
+
+ # Never do this -- insecure!
+ symbol = 'RHAT'
+ cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
+
+Instead, use the DB-API's parameter substitution. To insert a variable into a
+query string, use a placeholder in the string, and substitute the actual values
+into the query by providing them as a :class:`tuple` of values to the second
+argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may
+use one of two kinds of placeholders: question marks (qmark style) or named
+placeholders (named style). For the qmark style, ``parameters`` must be a
+:term:`sequence <sequence>`. For the named style, it can be either a
+:term:`sequence <sequence>` or :class:`dict` instance. The length of the
+:term:`sequence <sequence>` must match the number of placeholders, or a
+:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain
+keys for all named parameters. Any extra items are ignored. Here's an example of
+both styles:
+
+.. testcode::
+
+ con = sqlite3.connect(":memory:")
+ cur = con.execute("CREATE TABLE lang(name, first_appeared)")
+
+ # This is the qmark style:
+ cur.execute("INSERT INTO lang VALUES(?, ?)", ("C", 1972))
+
+ # The qmark style used with executemany():
+ lang_list = [
+ ("Fortran", 1957),
+ ("Python", 1991),
+ ("Go", 2009),
+ ]
+ cur.executemany("INSERT INTO lang VALUES(?, ?)", lang_list)
+
+ # And this is the named style:
+ cur.execute("SELECT * FROM lang WHERE first_appeared = :year", {"year": 1972})
+ print(cur.fetchall())
+
+.. testoutput::
+ :hide:
+
+ [('C', 1972)]
+
+
.. _sqlite3-adapters:
-Using adapters to store custom Python types in SQLite databases
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+How to adapt custom Python types to SQLite values
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SQLite supports only a limited set of data types natively.
To store custom Python types in SQLite databases, *adapt* them to one of the
-:ref:`Python types SQLite natively understands<sqlite3-types>`.
+:ref:`Python types SQLite natively understands <sqlite3-types>`.
There are two ways to adapt Python objects to SQLite types:
letting your object adapt itself, or using an *adapter callable*.
.. _sqlite3-conform:
-Letting your object adapt itself
-""""""""""""""""""""""""""""""""
+How to write adaptable objects
+""""""""""""""""""""""""""""""
-Suppose we have a ``Point`` class that represents a pair of coordinates,
+Suppose we have a :class:`!Point` class that represents a pair of coordinates,
``x`` and ``y``, in a Cartesian coordinate system.
The coordinate pair will be stored as a text string in the database,
using a semicolon to separate the coordinates.
method which returns the adapted value.
The object passed to *protocol* will be of type :class:`PrepareProtocol`.
-.. literalinclude:: ../includes/sqlite3/adapter_point_1.py
+.. testcode::
+
+ class Point:
+ def __init__(self, x, y):
+ self.x, self.y = x, y
+
+ def __conform__(self, protocol):
+ if protocol is sqlite3.PrepareProtocol:
+ return f"{self.x};{self.y}"
+
+ con = sqlite3.connect(":memory:")
+ cur = con.cursor()
+
+ cur.execute("SELECT ?", (Point(4.0, -3.2),))
+ print(cur.fetchone()[0])
+
+.. testoutput::
+ :hide:
+ 4.0;-3.2
-Registering an adapter callable
-"""""""""""""""""""""""""""""""
+
+How to register adapter callables
+"""""""""""""""""""""""""""""""""
The other possibility is to create a function that converts the Python object
to an SQLite-compatible type.
This function can then be registered using :func:`register_adapter`.
-.. literalinclude:: ../includes/sqlite3/adapter_point_2.py
+.. testcode::
+
+ class Point:
+ def __init__(self, x, y):
+ self.x, self.y = x, y
+
+ def adapt_point(point):
+ return f"{point.x};{point.y}"
+
+ sqlite3.register_adapter(Point, adapt_point)
+
+ con = sqlite3.connect(":memory:")
+ cur = con.cursor()
+
+ cur.execute("SELECT ?", (Point(1.0, 2.5),))
+ print(cur.fetchone()[0])
+
+.. testoutput::
+ :hide:
+
+ 1.0;2.5
.. _sqlite3-converters:
-Converting SQLite values to custom Python types
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+How to convert SQLite values to custom Python types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Writing an adapter lets you convert *from* custom Python types *to* SQLite
values.
To be able to convert *from* SQLite values *to* custom Python types,
we use *converters*.
-Let's go back to the :class:`Point` class. We stored the x and y coordinates
+Let's go back to the :class:`!Point` class. We stored the x and y coordinates
separated via semicolons as strings in SQLite.
First, we'll define a converter function that accepts the string as a parameter
-and constructs a :class:`Point` object from it.
+and constructs a :class:`!Point` object from it.
.. note::
Converter functions are **always** passed a :class:`bytes` object,
no matter the underlying SQLite data type.
-::
+.. testcode::
def convert_point(s):
x, y = map(float, s.split(b";"))
return Point(x, y)
-We now need to tell ``sqlite3`` when it should convert a given SQLite value.
+We now need to tell :mod:`!sqlite3` when it should convert a given SQLite value.
This is done when connecting to a database, using the *detect_types* parameter
of :func:`connect`. There are three options:
The following example illustrates the implicit and explicit approaches:
-.. literalinclude:: ../includes/sqlite3/converter_point.py
+.. testcode::
+ class Point:
+ def __init__(self, x, y):
+ self.x, self.y = x, y
-Default adapters and converters
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ def __repr__(self):
+ return f"Point({self.x}, {self.y})"
-There are default adapters for the date and datetime types in the datetime
-module. They will be sent as ISO dates/ISO timestamps to SQLite.
+ def adapt_point(point):
+ return f"{point.x};{point.y}".encode("utf-8")
-The default converters are registered under the name "date" for
-:class:`datetime.date` and under the name "timestamp" for
-:class:`datetime.datetime`.
+ def convert_point(s):
+ x, y = list(map(float, s.split(b";")))
+ return Point(x, y)
-This way, you can use date/timestamps from Python without any additional
-fiddling in most cases. The format of the adapters is also compatible with the
-experimental SQLite date/time functions.
+ # Register the adapter and converter
+ sqlite3.register_adapter(Point, adapt_point)
+ sqlite3.register_converter("point", convert_point)
-The following example demonstrates this.
+ # 1) Parse using declared types
+ p = Point(4.0, -3.2)
+ con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
+ cur = con.execute("CREATE TABLE test(p point)")
-.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py
+ cur.execute("INSERT INTO test(p) VALUES(?)", (p,))
+ cur.execute("SELECT p FROM test")
+ print("with declared types:", cur.fetchone()[0])
+ cur.close()
+ con.close()
-If a timestamp stored in SQLite has a fractional part longer than 6
-numbers, its value will be truncated to microsecond precision by the
-timestamp converter.
+ # 2) Parse using column names
+ con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
+ cur = con.execute("CREATE TABLE test(p)")
-.. note::
+ cur.execute("INSERT INTO test(p) VALUES(?)", (p,))
+ cur.execute('SELECT p AS "p [point]" FROM test')
+ print("with column names:", cur.fetchone()[0])
- The default "timestamp" converter ignores UTC offsets in the database and
- always returns a naive :class:`datetime.datetime` object. To preserve UTC
- offsets in timestamps, either leave converters disabled, or register an
- offset-aware converter with :func:`register_converter`.
+.. testoutput::
+ :hide:
+
+ with declared types: Point(4.0, -3.2)
+ with column names: Point(4.0, -3.2)
.. _sqlite3-adapter-converter-recipes:
This section shows recipes for common adapters and converters.
-.. code-block::
+.. testcode::
import datetime
import sqlite3
"""Adapt datetime.datetime to timezone-naive ISO 8601 date."""
return val.isoformat()
- def adapt_datetime_epoch(val)
+ def adapt_datetime_epoch(val):
"""Adapt datetime.datetime to Unix timestamp."""
return int(val.timestamp())
.. _sqlite3-connection-shortcuts:
-Using connection shortcut methods
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+How to use connection shortcut methods
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using the :meth:`~Connection.execute`,
:meth:`~Connection.executemany`, and :meth:`~Connection.executescript`
objects. This way, you can execute a ``SELECT`` statement and iterate over it
directly using only a single call on the :class:`Connection` object.
-.. literalinclude:: ../includes/sqlite3/shortcut_methods.py
+.. testcode::
+ # Create and fill the table.
+ con = sqlite3.connect(":memory:")
+ con.execute("CREATE TABLE lang(name, first_appeared)")
+ data = [
+ ("C++", 1985),
+ ("Objective-C", 1984),
+ ]
+ con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data)
-.. _sqlite3-columns-by-name:
+ # Print the table contents
+ for row in con.execute("SELECT name, first_appeared FROM lang"):
+ print(row)
-Accessing columns by name instead of by index
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows")
-One useful feature of the :mod:`sqlite3` module is the built-in
-:class:`sqlite3.Row` class designed to be used as a row factory.
+ # close() is not a shortcut method and it's not called automatically;
+ # the connection object should be closed manually
+ con.close()
-Rows wrapped with this class can be accessed both by index (like tuples) and
-case-insensitively by name:
+.. testoutput::
+ :hide:
-.. literalinclude:: ../includes/sqlite3/rowclass.py
+ ('C++', 1985)
+ ('Objective-C', 1984)
+ I just deleted 2 rows
.. _sqlite3-connection-context-manager:
-Using the connection as a context manager
+How to use the connection context manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A :class:`Connection` object can be used as a context manager that
The context manager neither implicitly opens a new transaction
nor closes the connection.
-.. literalinclude:: ../includes/sqlite3/ctx_manager.py
+.. testcode::
+
+ con = sqlite3.connect(":memory:")
+ con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)")
+
+ # Successful, con.commit() is called automatically afterwards
+ with con:
+ con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",))
+
+ # con.rollback() is called after the with block finishes with an exception,
+ # the exception is still raised and must be caught
+ try:
+ with con:
+ con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",))
+ except sqlite3.IntegrityError:
+ print("couldn't add Python twice")
+
+ # Connection object used as context manager only commits or rollbacks transactions,
+ # so the connection object should be closed manually
+ con.close()
+
+.. testoutput::
+ :hide:
+
+ couldn't add Python twice
.. _sqlite3-uri-tricks:
-Working with SQLite URIs
-^^^^^^^^^^^^^^^^^^^^^^^^
+How to work with SQLite URIs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some useful URI tricks include:
-* Open a database in read-only mode::
+* Open a database in read-only mode:
+
+.. doctest::
- con = sqlite3.connect("file:template.db?mode=ro", uri=True)
+ >>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True)
+ >>> con.execute("CREATE TABLE readonly(data)")
+ Traceback (most recent call last):
+ OperationalError: attempt to write a readonly database
* Do not implicitly create a new database file if it does not already exist;
- will raise :exc:`~sqlite3.OperationalError` if unable to create a new file::
+ will raise :exc:`~sqlite3.OperationalError` if unable to create a new file:
+
+.. doctest::
+
+ >>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True)
+ Traceback (most recent call last):
+ OperationalError: unable to open database file
+
+
+* Create a shared named in-memory database:
- con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True)
+.. testcode::
-* Create a shared named in-memory database::
+ db = "file:mem1?mode=memory&cache=shared"
+ con1 = sqlite3.connect(db, uri=True)
+ con2 = sqlite3.connect(db, uri=True)
+ with con1:
+ con1.execute("CREATE TABLE shared(data)")
+ con1.execute("INSERT INTO shared VALUES(28)")
+ res = con2.execute("SELECT data FROM shared")
+ assert res.fetchone() == (28,)
- con1 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True)
- con2 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True)
- con1.execute("create table t(t)")
- con1.execute("insert into t values(28)")
- con1.commit()
- rows = con2.execute("select * from t").fetchall()
More information about this feature, including a list of parameters,
can be found in the `SQLite URI documentation`_.
Transaction control
^^^^^^^^^^^^^^^^^^^
-The ``sqlite3`` module does not adhere to the transaction handling recommended
+The :mod:`!sqlite3` module does not adhere to the transaction handling recommended
by :pep:`249`.
If the connection attribute :attr:`~Connection.isolation_level`
-is not :const:`None`,
+is not ``None``,
new transactions are implicitly opened before
:meth:`~Cursor.execute` and :meth:`~Cursor.executemany` executes
``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statements.
Use the :meth:`~Connection.commit` and :meth:`~Connection.rollback` methods
to respectively commit and roll back pending transactions.
You can choose the underlying `SQLite transaction behaviour`_ —
-that is, whether and what type of ``BEGIN`` statements ``sqlite3``
+that is, whether and what type of ``BEGIN`` statements :mod:`!sqlite3`
implicitly executes –
via the :attr:`~Connection.isolation_level` attribute.
-If :attr:`~Connection.isolation_level` is set to :const:`None`,
+If :attr:`~Connection.isolation_level` is set to ``None``,
no transactions are implicitly opened at all.
This leaves the underlying SQLite library in `autocommit mode`_,
but also allows the user to perform their own transaction handling
regardless of the value of :attr:`~Connection.isolation_level`.
.. versionchanged:: 3.6
- :mod:`sqlite3` used to implicitly commit an open transaction before DDL
+ :mod:`!sqlite3` used to implicitly commit an open transaction before DDL
statements. This is no longer the case.
.. _autocommit mode:
[1.4591308524824727, 1.8035946855390597, 2.175091447274739]
Normal distributions can be used to approximate `Binomial
-distributions <http://mathworld.wolfram.com/BinomialDistribution.html>`_
+distributions <https://mathworld.wolfram.com/BinomialDistribution.html>`_
when the sample size is large and when the probability of a successful
trial is near 50%.
.. seealso::
- * The `linspace recipe <http://code.activestate.com/recipes/579000/>`_
+ * The `linspace recipe <https://code.activestate.com/recipes/579000/>`_
shows how to implement a lazy version of range suitable for floating
point applications.
If you want to make the hex string easier to read, you can specify a
single character separator *sep* parameter to include in the output.
- By default between each byte. A second optional *bytes_per_sep*
- parameter controls the spacing. Positive values calculate the
- separator position from the right, negative values from the left.
+ By default, this separator will be included between each byte.
+ A second optional *bytes_per_sep* parameter controls the spacing.
+ Positive values calculate the separator position from the right,
+ negative values from the left.
>>> value = b'\xf0\xf1\xf2'
>>> value.hex('-')
[<class 'bool'>]
+.. _int_max_str_digits:
+
+Integer string conversion length limitation
+===========================================
+
+CPython has a global limit for converting between :class:`int` and :class:`str`
+to mitigate denial of service attacks. This limit *only* applies to decimal or
+other non-power-of-two number bases. Hexadecimal, octal, and binary conversions
+are unlimited. The limit can be configured.
+
+The :class:`int` type in CPython is an abitrary length number stored in binary
+form (commonly known as a "bignum"). There exists no algorithm that can convert
+a string to a binary integer or a binary integer to a string in linear time,
+*unless* the base is a power of 2. Even the best known algorithms for base 10
+have sub-quadratic complexity. Converting a large value such as ``int('1' *
+500_000)`` can take over a second on a fast CPU.
+
+Limiting conversion size offers a practical way to avoid `CVE-2020-10735
+<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735>`_.
+
+The limit is applied to the number of digit characters in the input or output
+string when a non-linear conversion algorithm would be involved. Underscores
+and the sign are not counted towards the limit.
+
+When an operation would exceed the limit, a :exc:`ValueError` is raised:
+
+.. doctest::
+
+ >>> import sys
+ >>> sys.set_int_max_str_digits(4300) # Illustrative, this is the default.
+ >>> _ = int('2' * 5432)
+ Traceback (most recent call last):
+ ...
+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits.
+ >>> i = int('2' * 4300)
+ >>> len(str(i))
+ 4300
+ >>> i_squared = i*i
+ >>> len(str(i_squared))
+ Traceback (most recent call last):
+ ...
+ ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits.
+ >>> len(hex(i_squared))
+ 7144
+ >>> assert int(hex(i_squared), base=16) == i*i # Hexadecimal is unlimited.
+
+The default limit is 4300 digits as provided in
+:data:`sys.int_info.default_max_str_digits <sys.int_info>`.
+The lowest limit that can be configured is 640 digits as provided in
+:data:`sys.int_info.str_digits_check_threshold <sys.int_info>`.
+
+Verification:
+
+.. doctest::
+
+ >>> import sys
+ >>> assert sys.int_info.default_max_str_digits == 4300, sys.int_info
+ >>> assert sys.int_info.str_digits_check_threshold == 640, sys.int_info
+ >>> msg = int('578966293710682886880994035146873798396722250538762761564'
+ ... '9252925514383915483333812743580549779436104706260696366600'
+ ... '571186405732').to_bytes(53, 'big')
+ ...
+
+.. versionadded:: 3.10.7
+
+Affected APIs
+-------------
+
+The limitation only applies to potentially slow conversions between :class:`int`
+and :class:`str` or :class:`bytes`:
+
+* ``int(string)`` with default base 10.
+* ``int(string, base)`` for all bases that are not a power of 2.
+* ``str(integer)``.
+* ``repr(integer)``
+* any other string conversion to base 10, for example ``f"{integer}"``,
+ ``"{}".format(integer)``, or ``b"%d" % integer``.
+
+The limitations do not apply to functions with a linear algorithm:
+
+* ``int(string, base)`` with base 2, 4, 8, 16, or 32.
+* :func:`int.from_bytes` and :func:`int.to_bytes`.
+* :func:`hex`, :func:`oct`, :func:`bin`.
+* :ref:`formatspec` for hex, octal, and binary numbers.
+* :class:`str` to :class:`float`.
+* :class:`str` to :class:`decimal.Decimal`.
+
+Configuring the limit
+---------------------
+
+Before Python starts up you can use an environment variable or an interpreter
+command line flag to configure the limit:
+
+* :envvar:`PYTHONINTMAXSTRDIGITS`, e.g.
+ ``PYTHONINTMAXSTRDIGITS=640 python3`` to set the limit to 640 or
+ ``PYTHONINTMAXSTRDIGITS=0 python3`` to disable the limitation.
+* :option:`-X int_max_str_digits <-X>`, e.g.
+ ``python3 -X int_max_str_digits=640``
+* :data:`sys.flags.int_max_str_digits` contains the value of
+ :envvar:`PYTHONINTMAXSTRDIGITS` or :option:`-X int_max_str_digits <-X>`.
+ If both the env var and the ``-X`` option are set, the ``-X`` option takes
+ precedence. A value of *-1* indicates that both were unset, thus a value of
+ :data:`sys.int_info.default_max_str_digits` was used during initilization.
+
+From code, you can inspect the current limit and set a new one using these
+:mod:`sys` APIs:
+
+* :func:`sys.get_int_max_str_digits` and :func:`sys.set_int_max_str_digits` are
+ a getter and setter for the interpreter-wide limit. Subinterpreters have
+ their own limit.
+
+Information about the default and minimum can be found in :attr:`sys.int_info`:
+
+* :data:`sys.int_info.default_max_str_digits <sys.int_info>` is the compiled-in
+ default limit.
+* :data:`sys.int_info.str_digits_check_threshold <sys.int_info>` is the lowest
+ accepted value for the limit (other than 0 which disables it).
+
+.. versionadded:: 3.10.7
+
+.. caution::
+
+ Setting a low limit *can* lead to problems. While rare, code exists that
+ contains integer constants in decimal in their source that exceed the
+ minimum threshold. A consequence of setting the limit is that Python source
+ code containing decimal integer literals longer than the limit will
+ encounter an error during parsing, usually at startup time or import time or
+ even at installation time - anytime an up to date ``.pyc`` does not already
+ exist for the code. A workaround for source that contains such large
+ constants is to convert them to ``0x`` hexadecimal form as it has no limit.
+
+ Test your application thoroughly if you use a low limit. Ensure your tests
+ run with the limit set early via the environment or flag so that it applies
+ during startup and even during any installation step that may invoke Python
+ to precompile ``.py`` sources to ``.pyc`` files.
+
+Recommended configuration
+-------------------------
+
+The default :data:`sys.int_info.default_max_str_digits` is expected to be
+reasonable for most applications. If your application requires a different
+limit, set it from your main entry point using Python version agnostic code as
+these APIs were added in security patch releases in versions before 3.11.
+
+Example::
+
+ >>> import sys
+ >>> if hasattr(sys, "set_int_max_str_digits"):
+ ... upper_bound = 68000
+ ... lower_bound = 4004
+ ... current_limit = sys.get_int_max_str_digits()
+ ... if current_limit == 0 or current_limit > upper_bound:
+ ... sys.set_int_max_str_digits(upper_bound)
+ ... elif current_limit < lower_bound:
+ ... sys.set_int_max_str_digits(lower_bound)
+
+If you need to disable it entirely, set it to ``0``.
+
+
.. rubric:: Footnotes
.. [1] Additional information on these special methods may be found in the Python
--------------
+
.. seealso::
:ref:`textseq`
functionality makes it easier to translate than other built-in string
formatting facilities in Python. As an example of a library built on template
strings for i18n, see the
-`flufl.i18n <http://flufli18n.readthedocs.io/en/latest/>`_ package.
+`flufl.i18n <https://flufli18n.readthedocs.io/en/latest/>`_ package.
.. index:: single: $ (dollar); in template strings
The :term:`named tuple` *flags* exposes the status of command line
flags. The attributes are read only.
- ============================= ================================================================
+ ============================= ==============================================================================================================
attribute flag
- ============================= ================================================================
+ ============================= ==============================================================================================================
:const:`debug` :option:`-d`
:const:`inspect` :option:`-i`
:const:`interactive` :option:`-i`
:const:`hash_randomization` :option:`-R`
:const:`dev_mode` :option:`-X dev <-X>` (:ref:`Python Development Mode <devmode>`)
:const:`utf8_mode` :option:`-X utf8 <-X>`
- ============================= ================================================================
+ :const:`int_max_str_digits` :option:`-X int_max_str_digits <-X>` (:ref:`integer string conversion length limitation <int_max_str_digits>`)
+ ============================= ==============================================================================================================
.. versionchanged:: 3.2
Added ``quiet`` attribute for the new :option:`-q` flag.
Mode <devmode>` and the ``utf8_mode`` attribute for the new :option:`-X`
``utf8`` flag.
+ .. versionchanged:: 3.10.7
+ Added the ``int_max_str_digits`` attribute.
+
.. data:: float_info
.. versionadded:: 3.6
+.. function:: get_int_max_str_digits()
+
+ Returns the current value for the :ref:`integer string conversion length
+ limitation <int_max_str_digits>`. See also :func:`set_int_max_str_digits`.
+
+ .. versionadded:: 3.10.7
+
.. function:: getrefcount(object)
Return the reference count of the *object*. The count returned is generally one
.. tabularcolumns:: |l|L|
- +-------------------------+----------------------------------------------+
- | Attribute | Explanation |
- +=========================+==============================================+
- | :const:`bits_per_digit` | number of bits held in each digit. Python |
- | | integers are stored internally in base |
- | | ``2**int_info.bits_per_digit`` |
- +-------------------------+----------------------------------------------+
- | :const:`sizeof_digit` | size in bytes of the C type used to |
- | | represent a digit |
- +-------------------------+----------------------------------------------+
+ +----------------------------------------+-----------------------------------------------+
+ | Attribute | Explanation |
+ +========================================+===============================================+
+ | :const:`bits_per_digit` | number of bits held in each digit. Python |
+ | | integers are stored internally in base |
+ | | ``2**int_info.bits_per_digit`` |
+ +----------------------------------------+-----------------------------------------------+
+ | :const:`sizeof_digit` | size in bytes of the C type used to |
+ | | represent a digit |
+ +----------------------------------------+-----------------------------------------------+
+ | :const:`default_max_str_digits` | default value for |
+ | | :func:`sys.get_int_max_str_digits` when it |
+ | | is not otherwise explicitly configured. |
+ +----------------------------------------+-----------------------------------------------+
+ | :const:`str_digits_check_threshold` | minimum non-zero value for |
+ | | :func:`sys.set_int_max_str_digits`, |
+ | | :envvar:`PYTHONINTMAXSTRDIGITS`, or |
+ | | :option:`-X int_max_str_digits <-X>`. |
+ +----------------------------------------+-----------------------------------------------+
.. versionadded:: 3.1
+ .. versionchanged:: 3.10.7
+ Added ``default_max_str_digits`` and ``str_digits_check_threshold``.
+
.. data:: __interactivehook__
.. availability:: Unix.
+.. function:: set_int_max_str_digits(n)
+
+ Set the :ref:`integer string conversion length limitation
+ <int_max_str_digits>` used by this interpreter. See also
+ :func:`get_int_max_str_digits`.
+
+ .. versionadded:: 3.10.7
+
.. function:: setprofile(profilefunc)
.. index::
.. rubric:: Citations
-.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ .
+.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ .
value given in the :func:`openlog` call is used.
If :func:`openlog` has not been called prior to the call to :func:`syslog`,
- ``openlog()`` will be called with no arguments.
+ :func:`openlog` will be called with no arguments.
.. audit-event:: syslog.syslog priority,message syslog.syslog
+ .. versionchanged:: 3.2
+ In previous versions, :func:`openlog` would not be called automatically if
+ it wasn't called prior to the call to :func:`syslog`, deferring to the syslog
+ implementation to call ``openlog()``.
+
.. function:: openlog([ident[, logoption[, facility]]])
.. versionchanged:: 3.2
In previous versions, keyword arguments were not allowed, and *ident* was
- required. The default for *ident* was dependent on the system libraries,
- and often was ``python`` instead of the name of the Python program file.
+ required.
.. function:: closelog()
.. versionadded:: 3.10
+.. function:: adjust_int_max_str_digits(max_digits)
+
+ This function returns a context manager that will change the global
+ :func:`sys.set_int_max_str_digits` setting for the duration of the
+ context to allow execution of test code that needs a different limit
+ on the number of digits when converting between an integer and string.
+
+ .. versionadded:: 3.10.7
+
+
The :mod:`test.support` module defines the following classes:
--------------
This module constructs higher-level threading interfaces on top of the lower
-level :mod:`_thread` module. See also the :mod:`queue` module.
+level :mod:`_thread` module.
.. versionchanged:: 3.7
This module used to be optional, it is now always available.
+.. seealso::
+
+ :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface
+ to push tasks to a background thread without blocking execution of the
+ calling thread, while still being able to retrieve their results when needed.
+
+ :mod:`queue` provides a thread-safe interface for exchanging data between
+ running threads.
+
+ :mod:`asyncio` offers an alternative approach to achieving task level
+ concurrency without requiring the use of multiple operating system threads.
+
.. note::
In the Python 2.x series, this module contained ``camelCase`` names
* `Python and Tkinter Programming <https://www.packtpub.com/product/python-gui-programming-with-tkinter/9781788835886>`_
By Alan Moore. (ISBN 978-1788835886)
- * `Programming Python <http://learning-python.com/about-pp4e.html>`_
+ * `Programming Python <https://learning-python.com/about-pp4e.html>`_
By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101)
* `Tcl and the Tk Toolkit (2nd edition) <https://www.amazon.com/exec/obidos/ASIN/032133633X>`_
(see `Threading model`_ for details).
Tk
- Tk is a `Tcl package <http://wiki.tcl.tk/37432>`_ implemented in C
+ Tk is a `Tcl package <https://wiki.tcl-lang.org/37432>`_ implemented in C
that adds custom commands to create and manipulate GUI widgets. Each
:class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into
it. Tk's widgets are very customizable, though at the cost of a dated appearance.
.. seealso::
- The `Pillow <http://python-pillow.org/>`_ package adds support for
+ The `Pillow <https://python-pillow.org/>`_ package adds support for
formats such as BMP, JPEG, TIFF, and WebP, among others.
.. _tkinter-file-handlers:
True
.. attribute:: __required_keys__
+
+ .. versionadded:: 3.9
+
.. attribute:: __optional_keys__
``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return
>>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
True
+ .. versionadded:: 3.9
+
See :pep:`589` for more examples and detailed rules of using ``TypedDict``.
.. versionadded:: 3.8
Deletes the specified key.
- .. note::
- The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx
- Windows API function, which is specific to 64-bit versions of Windows.
- See the `RegDeleteKeyEx documentation
- <https://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__.
-
*key* is an already open key, or one of the predefined
:ref:`HKEY_* constants <hkey-constants>`.
*reserved* is a reserved integer, and must be zero. The default is zero.
- *access* is an integer that specifies an access mask that describes the desired
- security access for the key. Default is :const:`KEY_WOW64_64KEY`. See
- :ref:`Access Rights <access-rights>` for other allowed values.
+ *access* is an integer that specifies an access mask that describes the
+ desired security access for the key. Default is :const:`KEY_WOW64_64KEY`.
+ On 32-bit Windows, the WOW64 constants are ignored.
+ See :ref:`Access Rights <access-rights>` for other allowed values.
*This method can not delete keys with subkeys.*
.. data:: KEY_WOW64_64KEY
Indicates that an application on 64-bit Windows should operate on
- the 64-bit registry view.
+ the 64-bit registry view. On 32-bit Windows, this constant is ignored.
.. data:: KEY_WOW64_32KEY
Indicates that an application on 64-bit Windows should operate on
- the 32-bit registry view.
-
+ the 32-bit registry view. On 32-bit Windows, this constant is ignored.
.. _value-types:
Added support of unmarshalling additional types used by Apache XML-RPC
implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``,
``float`` and ``bigdecimal``.
- See http://ws.apache.org/xmlrpc/types.html for a description.
+ See https://ws.apache.org/xmlrpc/types.html for a description.
.. seealso::
- `XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_
+ `XML-RPC HOWTO <https://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_
A good description of XML-RPC operation and client software in several languages.
Contains pretty much everything an XML-RPC client developer needs to know.
The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and
:func:`getnameinfo`, which are coded in separate source files from the WIDE
-Project, http://www.wide.ad.jp/. ::
+Project, https://www.wide.ad.jp/. ::
Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
All rights reserved.
These classes accept a single positional argument, and the pattern there is matched
against the whole object rather than an attribute. For example ``int(0|1)`` matches
- the value ``0``, but not the values ``0.0`` or ``False``.
+ the value ``0``, but not the value ``0.0``.
In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens:
Python implemented in Java. This implementation can be used as a scripting
language for Java applications, or can be used to create applications using the
Java class libraries. It is also often used to create tests for Java libraries.
- More information can be found at `the Jython website <http://www.jython.org/>`_.
+ More information can be found at `the Jython website <https://www.jython.org/>`_.
Python for .NET
This implementation actually uses the CPython implementation, but is a managed
An alternate Python for .NET. Unlike Python.NET, this is a complete Python
implementation that generates IL, and compiles Python code directly to .NET
assemblies. It was created by Jim Hugunin, the original creator of Jython. For
- more information, see `the IronPython website <http://ironpython.net/>`_.
+ more information, see `the IronPython website <https://ironpython.net/>`_.
PyPy
An implementation of Python written completely in Python. It supports several
and a Just in Time compiler. One of the goals of the project is to encourage
experimentation with the language itself by making it easier to modify the
interpreter (since it is written in Python). Additional information is
- available on `the PyPy project's home page <http://pypy.org/>`_.
+ available on `the PyPy project's home page <https://pypy.org/>`_.
Each of these implementations varies in some way from the language as documented
in this manual, or introduces specific information beyond what's covered in the
+-----------------+---------------------------------+-------+
| Escape Sequence | Meaning | Notes |
+=================+=================================+=======+
-| ``\newline`` | Backslash and newline ignored | |
+| ``\``\ <newline>| Backslash and newline ignored | \(1) |
+-----------------+---------------------------------+-------+
| ``\\`` | Backslash (``\``) | |
+-----------------+---------------------------------+-------+
+-----------------+---------------------------------+-------+
| ``\v`` | ASCII Vertical Tab (VT) | |
+-----------------+---------------------------------+-------+
-| ``\ooo`` | Character with octal value | (1,3) |
+| ``\ooo`` | Character with octal value | (2,4) |
| | *ooo* | |
+-----------------+---------------------------------+-------+
-| ``\xhh`` | Character with hex value *hh* | (2,3) |
+| ``\xhh`` | Character with hex value *hh* | (3,4) |
+-----------------+---------------------------------+-------+
Escape sequences only recognized in string literals are:
+-----------------+---------------------------------+-------+
| Escape Sequence | Meaning | Notes |
+=================+=================================+=======+
-| ``\N{name}`` | Character named *name* in the | \(4) |
+| ``\N{name}`` | Character named *name* in the | \(5) |
| | Unicode database | |
+-----------------+---------------------------------+-------+
-| ``\uxxxx`` | Character with 16-bit hex value | \(5) |
+| ``\uxxxx`` | Character with 16-bit hex value | \(6) |
| | *xxxx* | |
+-----------------+---------------------------------+-------+
-| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(6) |
+| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) |
| | *xxxxxxxx* | |
+-----------------+---------------------------------+-------+
Notes:
(1)
- As in Standard C, up to three octal digits are accepted.
+ A backslash can be added at the end of a line to ignore the newline::
+
+ >>> 'This string will not include \
+ ... backslashes or newline characters.'
+ 'This string will not include backslashes or newline characters.'
+
+ The same result can be achieved using :ref:`triple-quoted strings <strings>`,
+ or parentheses and :ref:`string literal concatenation <string-concatenation>`.
(2)
- Unlike in Standard C, exactly two hex digits are required.
+ As in Standard C, up to three octal digits are accepted.
(3)
+ Unlike in Standard C, exactly two hex digits are required.
+
+(4)
In a bytes literal, hexadecimal and octal escapes denote the byte with the
given value. In a string literal, these escapes denote a Unicode character
with the given value.
-(4)
+(5)
.. versionchanged:: 3.3
Support for name aliases [#]_ has been added.
-(5)
+(6)
Exactly four hex digits are required.
-(6)
+(7)
Any Unicode character can be encoded this way. Exactly eight hex digits
are required.
'type': 'type',
'macro': 'macro',
'type': 'type',
+ 'member': 'member',
}
# Stable ABI annotation. These have two forms:
# Part of the [Stable ABI](link).
# Part of the [Stable ABI](link) since version X.Y.
+ # For structs, there's some more info in the message:
+ # Part of the [Limited API](link) (as an opaque struct).
+ # Part of the [Stable ABI](link) (including all members).
+ # Part of the [Limited API](link) (Only some members are part
+ # of the stable ABI.).
+ # ... all of which can have "since version X.Y" appended.
record = self.stable_abi_data.get(name)
if record:
if record['role'] != objtype:
ref_node = addnodes.pending_xref(
'Stable ABI', refdomain="std", reftarget='stable',
reftype='ref', refexplicit="False")
- ref_node += nodes.Text('Stable ABI')
+ struct_abi_kind = record['struct_abi_kind']
+ if struct_abi_kind in {'opaque', 'members'}:
+ ref_node += nodes.Text('Limited API')
+ else:
+ ref_node += nodes.Text('Stable ABI')
emph_node += ref_node
+ if struct_abi_kind == 'opaque':
+ emph_node += nodes.Text(' (as an opaque struct)')
+ elif struct_abi_kind == 'full-abi':
+ emph_node += nodes.Text(' (including all members)')
if record['ifdef_note']:
emph_node += nodes.Text(' ' + record['ifdef_note'])
if stable_added == '3.2':
# Stable ABI was introduced in 3.2.
- emph_node += nodes.Text('.')
+ pass
else:
- emph_node += nodes.Text(f' since version {stable_added}.')
+ emph_node += nodes.Text(f' since version {stable_added}')
+ emph_node += nodes.Text('.')
+ if struct_abi_kind == 'members':
+ emph_node += nodes.Text(
+ ' (Only some members are part of the stable ABI.)')
node.insert(0, emph_node)
# Return value annotation
library/socket,,::,'5aef:2b::8'
library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])"
library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
-library/sqlite3,,:year,"cur.execute(""select * from lang where first_appeared=:year"", {""year"": 1972})"
+library/sqlite3,,:year,"cur.execute(""SELECT * FROM lang WHERE first_appeared = :year"", {""year"": 1972})"
library/sqlite3,,:memory,
-library/sqlite3,,:template,"con = sqlite3.connect(""file:template.db?mode=ro"", uri=True)"
-library/sqlite3,,:nosuchdb,"con = sqlite3.connect(""file:nosuchdb.db?mode=rw"", uri=True)"
-library/sqlite3,,:mem1,"con1 = sqlite3.connect(""file:mem1?mode=memory&cache=shared"", uri=True)"
-library/sqlite3,,:mem1,"con2 = sqlite3.connect(""file:mem1?mode=memory&cache=shared"", uri=True)"
+library/sqlite3,,:mem1,"db = ""file:mem1?mode=memory&cache=shared"""
+library/sqlite3,,:nosuchdb,">>> con = sqlite3.connect(""file:nosuchdb.db?mode=rw"", uri=True)"
+library/sqlite3,,:tutorial,">>> con = sqlite3.connect(""file:tutorial.db?mode=ro"", uri=True)"
library/ssl,,:My,"Organizational Unit Name (eg, section) []:My Group"
library/ssl,,:My,"Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc."
library/ssl,,:myserver,"Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com"
stored in a traceback of a trace. Use ``-X tracemalloc=NFRAME`` to start
tracing with a traceback limit of *NFRAME* frames. See the
:func:`tracemalloc.start` for more information.
+ * ``-X int_max_str_digits`` configures the :ref:`integer string conversion
+ length limitation <int_max_str_digits>`. See also
+ :envvar:`PYTHONINTMAXSTRDIGITS`.
* ``-X importtime`` to show how long each import takes. It shows module
name, cumulative time (including nested imports) and self time (excluding
nested imports). Note that its output may be broken in multi-threaded
.. versionadded:: 3.10
The ``-X warn_default_encoding`` option.
+ .. versionadded:: 3.10.7
+ The ``-X int_max_str_digits`` option.
+
.. deprecated-removed:: 3.9 3.10
The ``-X oldparser`` option.
Reserved for use by Jython_.
-.. _Jython: http://www.jython.org/
-
+.. _Jython: https://www.jython.org/
.. _using-on-envvars:
.. versionadded:: 3.2.3
+.. envvar:: PYTHONINTMAXSTRDIGITS
+
+ If this variable is set to an integer, it is used to configure the
+ interpreter's global :ref:`integer string conversion length limitation
+ <int_max_str_digits>`.
+
+ .. versionadded:: 3.10.7
.. envvar:: PYTHONIOENCODING
Getting and Installing MacPython
================================
-macOS since version 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you
-are invited to install the most recent version of Python 3 from the Python
+macOS used to come with Python 2.7 pre-installed between versions
+10.8 and `12.3 <https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes#Python>`_.
+You are invited to install the most recent version of Python 3 from the Python
website (https://www.python.org). A current "universal binary" build of Python,
which runs natively on the Mac's new Intel and legacy PPC CPU's, is available
there.
What you get after installing is a number of things:
-* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here
+* A :file:`Python 3.12` folder in your :file:`Applications` folder. In here
you find IDLE, the development environment that is a standard part of official
Python distributions; and PythonLauncher, which handles double-clicking Python
scripts from the Finder.
:program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see
http://www.barebones.com/products/bbedit/index.html) are good choices, as is
:program:`TextMate` (see https://macromates.com/). Other editors include
-:program:`Gvim` (http://macvim-dev.github.io/macvim/) and :program:`Aquamacs`
+:program:`Gvim` (https://macvim-dev.github.io/macvim/) and :program:`Aquamacs`
(http://aquamacs.org/).
To run your script from the Terminal window you must make sure that
| Include_debug | Install debug binaries | 0 |
+---------------------------+--------------------------------------+--------------------------+
| Include_dev | Install developer headers and | 1 |
-| | libraries | |
+| | libraries. Omitting this may lead to | |
+| | an unusable installation. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_exe | Install :file:`python.exe` and | 1 |
-| | related files | |
+| | related files. Omitting this may | |
+| | lead to an unusable installation. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_launcher | Install :ref:`launcher`. | 1 |
+---------------------------+--------------------------------------+--------------------------+
-| InstallLauncherAllUsers | Installs :ref:`launcher` for all | 1 |
-| | users. | |
+| InstallLauncherAllUsers | Installs the launcher for all | 1 |
+| | users. Also requires | |
+| | ``Include_launcher`` to be set to 1 | |
+---------------------------+--------------------------------------+--------------------------+
| Include_lib | Install standard library and | 1 |
-| | extension modules | |
+| | extension modules. Omitting this may | |
+| | lead to an unusable installation. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_pip | Install bundled pip and setuptools | 1 |
+---------------------------+--------------------------------------+--------------------------+
hierarchy. Classic classes are unaffected by this change. Python 2.2
originally used a topological sort of a class's ancestors, but 2.3 now uses the
C3 algorithm as described in the paper `"A Monotonic Superclass Linearization
- for Dylan" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To
+ for Dylan" <https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To
understand the motivation for this change, read Michele Simionato's article
`"Python 2.3 Method Resolution Order" <http://www.phyast.pitt.edu/~micheles/mro.html>`_, or
read the thread on python-dev starting with the message at
:c:type:`int` as a 32-bit type, so that meant that lists could only hold up to
``2**31 - 1`` = 2147483647 items. (There are actually a few different
programming models that 64-bit C compilers can use -- see
-http://www.unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the
+https://unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the
most commonly available model leaves :c:type:`int` as 32 bits.)
A limit of 2147483647 items doesn't really matter on a 32-bit platform because
The sqlite3 package
-------------------
-The pysqlite module (http://www.pysqlite.org), a wrapper for the SQLite embedded
+The pysqlite module (https://www.pysqlite.org), a wrapper for the SQLite embedded
database, has been added to the standard library under the package name
:mod:`sqlite3`.
.. seealso::
- http://www.pysqlite.org
+ https://www.pysqlite.org
The pysqlite web page.
https://www.sqlite.org
SourceForge. Four different trackers were examined: `Jira
<https://www.atlassian.com/software/jira/>`__,
`Launchpad <https://launchpad.net/>`__,
-`Roundup <http://roundup.sourceforge.net/>`__, and
+`Roundup <https://roundup.sourceforge.io/>`__, and
`Trac <https://trac.edgewall.org/>`__.
The committee eventually settled on Jira
and Roundup as the two candidates. Jira is a commercial product that
of Stellenbosch, South Africa. Martin von Löwis put a
lot of effort into importing existing bugs and patches from
SourceForge; his scripts for this import operation are at
-``http://svn.python.org/view/tracker/importer/`` and may be useful to
+``https://svn.python.org/view/tracker/importer/`` and may be useful to
other projects wishing to move from SourceForge to Roundup.
.. seealso::
https://bugs.python.org
The Python bug tracker.
- http://bugs.jython.org:
+ https://bugs.jython.org:
The Jython bug tracker.
- http://roundup.sourceforge.net/
+ https://roundup.sourceforge.io/
Roundup downloads and documentation.
- http://svn.python.org/view/tracker/importer/
+ https://svn.python.org/view/tracker/importer/
Martin von Löwis's conversion scripts.
New Documentation Format: reStructuredText Using Sphinx
`Sphinx <http://sphinx-doc.org/>`__
Documentation and code for the Sphinx toolchain.
- `Docutils <http://docutils.sourceforge.net>`__
+ `Docutils <https://docutils.sourceforge.io>`__
The underlying reStructuredText parser and toolset.
`Scheme's numerical tower <https://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual.
- `Scheme's number datatypes <http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification.
+ `Scheme's number datatypes <https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification.
The :mod:`fractions` Module
constructor was extended with an *object_pairs_hook* parameter to
allow :class:`OrderedDict` instances to be built by the decoder.
Support was also added for third-party tools like
- `PyYAML <http://pyyaml.org/>`_.
+ `PyYAML <https://pyyaml.org/>`_.
.. seealso::
The new version features better Python 3.x compatibility, various bug fixes,
and adds several new BerkeleyDB flags and methods.
(Updated by Jesús Cea Avión; :issue:`8156`. The pybsddb
- changelog can be read at http://hg.jcea.es/pybsddb/file/tip/ChangeLog.)
+ changelog can be read at https://hg.jcea.es/pybsddb/file/tip/ChangeLog.)
* The :mod:`bz2` module's :class:`~bz2.BZ2File` now supports the context
management protocol, so you can write ``with bz2.BZ2File(...) as f:``.
https://pypi.org/project/unittest2.
When used from the command line, the module can automatically discover
-tests. It's not as fancy as `py.test <http://pytest.org>`__ or
+tests. It's not as fancy as `py.test <https://pytest.org>`__ or
`nose <https://nose.readthedocs.io/>`__, but provides a
simple way to run tests kept within a set of package directories. For example,
the following command will search the :file:`test/` subdirectory for
completely redesigned as short getting started and FAQ documents. Most
packaging documentation has now been moved out to the Python Packaging
Authority maintained `Python Packaging User Guide
-<http://packaging.python.org>`__ and the documentation of the individual
+<https://packaging.python.org>`__ and the documentation of the individual
projects.
However, as this migration is currently still incomplete, the legacy
returns an ordered dictionary with the values appearing in the same order as
the underlying tuple indices. The :mod:`json` module is being built-out with
an *object_pairs_hook* to allow OrderedDicts to be built by the decoder.
-Support was also added for third-party tools like `PyYAML <http://pyyaml.org/>`_.
+Support was also added for third-party tools like `PyYAML <https://pyyaml.org/>`_.
.. seealso::
Apply syntax highlighting to `.pyi` files. (Contributed by Alex
Waygood and Terry Jan Reedy in :issue:`45447`.)
+Include prompts when saving Shell with inputs and outputs.
+(Contributed by Terry Jan Reedy in :gh:`95191`.)
+
importlib.metadata
------------------
* The ``PyThreadState.use_tracing`` member has been removed to optimize Python.
(Contributed by Mark Shannon in :issue:`43760`.)
+
+
+Notable security feature in 3.10.7
+==================================
+
+Converting between :class:`int` and :class:`str` in bases other than 2
+(binary), 4, 8 (octal), 16 (hexadecimal), or 32 such as base 10 (decimal)
+now raises a :exc:`ValueError` if the number of digits in string form is
+above a limit to avoid potential denial of service attacks due to the
+algorithmic complexity. This is a mitigation for `CVE-2020-10735
+<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735>`_.
+This limit can be configured or disabled by environment variable, command
+line flag, or :mod:`sys` APIs. See the :ref:`integer string conversion
+length limitation <int_max_str_digits>` documentation. The default limit
+is 4300 digits in string form.
+
Code Repository
===============
-In addition to the existing Subversion code repository at http://svn.python.org
+In addition to the existing Subversion code repository at https://svn.python.org
there is now a `Mercurial <https://www.mercurial-scm.org/>`_ repository at
https://hg.python.org/\ .
in integer bignum arithmetic the differences can be significantly higher.
The following table is meant as an illustration. Benchmarks are available
-at http://www.bytereef.org/mpdecimal/quickstart.html.
+at https://www.bytereef.org/mpdecimal/quickstart.html.
+---------+-------------+--------------+-------------+
| | decimal.py | _decimal | speedup |
------
The :func:`~imghdr.what` function now recognizes the
-`OpenEXR <http://www.openexr.com>`_ format
+`OpenEXR <https://www.openexr.com>`_ format
(contributed by Martin Vignali and Claudiu Popa in :issue:`20295`),
and the `WebP <https://en.wikipedia.org/wiki/WebP>`_ format
(contributed by Fabrice Aneche and Claudiu Popa in :issue:`20197`.)
.. seealso::
- `importlib_resources <http://importlib-resources.readthedocs.io/en/latest/>`_
+ `importlib_resources <https://importlib-resources.readthedocs.io/en/latest/>`_
-- a PyPI backport for earlier Python versions.
parameters[arguments_ty]:
| a=slash_no_default b[asdl_arg_seq*]=param_no_default* c=param_with_default* d=[star_etc] {
- _PyPegen_make_arguments(p, a, NULL, b, c, d) }
+ CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, a, NULL, b, c, d)) }
| a=slash_with_default b=param_with_default* c=[star_etc] {
- _PyPegen_make_arguments(p, NULL, a, NULL, b, c) }
+ CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) }
| a[asdl_arg_seq*]=param_no_default+ b=param_with_default* c=[star_etc] {
_PyPegen_make_arguments(p, NULL, NULL, a, b, c) }
| a=param_with_default+ b=[star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)}
#
lambda_parameters[arguments_ty]:
| a=lambda_slash_no_default b[asdl_arg_seq*]=lambda_param_no_default* c=lambda_param_with_default* d=[lambda_star_etc] {
- _PyPegen_make_arguments(p, a, NULL, b, c, d) }
+ CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, a, NULL, b, c, d)) }
| a=lambda_slash_with_default b=lambda_param_with_default* c=[lambda_star_etc] {
- _PyPegen_make_arguments(p, NULL, a, NULL, b, c) }
+ CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) }
| a[asdl_arg_seq*]=lambda_param_no_default+ b=lambda_param_with_default* c=[lambda_star_etc] {
_PyPegen_make_arguments(p, NULL, NULL, a, b, c) }
| a=lambda_param_with_default+ b=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)}
in hardware they will fall back to a full memory barrier as well.
This might affect performance but likely only in some very specific and
- hard to meassure scenario.
+ hard to measure scenario.
*/
#if defined(_M_IX86) || defined(_M_X64)
typedef enum _Py_memory_order {
PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config);
PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict);
+extern int _Py_global_config_int_max_str_digits;
+
/* --- Function used for testing ---------------------------------- */
struct ast_state ast;
struct type_cache type_cache;
+
+ int int_max_str_digits;
};
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
#include "pycore_interp.h" // PyInterpreterState.small_ints
#include "pycore_pystate.h" // _PyThreadState_GET()
+/*
+ * Default int base conversion size limitation: Denial of Service prevention.
+ *
+ * Chosen such that this isn't wildly slow on modern hardware and so that
+ * everyone's existing deployed numpy test suite passes before
+ * https://github.com/numpy/numpy/issues/22098 is widely available.
+ *
+ * $ python -m timeit -s 's = "1"*4300' 'int(s)'
+ * 2000 loops, best of 5: 125 usec per loop
+ * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)'
+ * 1000 loops, best of 5: 311 usec per loop
+ * (zen2 cloud VM)
+ *
+ * 4300 decimal digits fits a ~14284 bit number.
+ */
+#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
+/*
+ * Threshold for max digits check. For performance reasons int() and
+ * int.__str__() don't checks values that are smaller than this
+ * threshold. Acts as a guaranteed minimum size limit for bignums that
+ * applications can expect from CPython.
+ *
+ * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))'
+ * 20000 loops, best of 5: 12 usec per loop
+ *
+ * "640 digits should be enough for anyone." - gps
+ * fits a ~2126 bit decimal number.
+ */
+#define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
+
+#if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
+ (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD))
+# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
+#endif
+
// Don't call this function but _PyLong_GetZero() and _PyLong_GetOne()
static inline PyObject* __PyLong_GetSmallInt_internal(int value)
{
/*--start constants--*/
#define PY_MAJOR_VERSION 3
#define PY_MINOR_VERSION 10
-#define PY_MICRO_VERSION 6
+#define PY_MICRO_VERSION 7
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "3.10.6"
+#define PY_VERSION "3.10.7"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
return True
-# Determines if there is an effective (active) breakpoint at this
-# line of code. Returns breakpoint number or 0 if none
def effective(file, line, frame):
- """Determine which breakpoint for this file:line is to be acted upon.
+ """Return (active breakpoint, delete temporary flag) or (None, None) as
+ breakpoint to act upon.
- Called only if we know there is a breakpoint at this location. Return
- the breakpoint that was triggered and a boolean that indicates if it is
- ok to delete a temporary breakpoint. Return (None, None) if there is no
- matching breakpoint.
+ The "active breakpoint" is the first entry in bplist[line, file] (which
+ must exist) that is enabled, for which checkfuncname is True, and that
+ has neither a False condition nor a positive ignore count. The flag,
+ meaning that a temporary breakpoint should be deleted, is False only
+ when the condiion cannot be evaluated (in which case, ignore count is
+ ignored).
+
+ If no such entry exists, then (None, None) is returned.
"""
possibles = Breakpoint.bplist[file, line]
for b in possibles:
result = crypt('', salt)
except OSError as e:
# Not all libc libraries support all encryption methods.
- if e.errno == errno.EINVAL:
+ if e.errno in {errno.EINVAL, errno.EPERM, errno.ENOSYS}:
return False
raise
if result and len(result) == method.total_size:
__all__ = ["version", "bootstrap"]
_PACKAGE_NAMES = ('setuptools', 'pip')
_SETUPTOOLS_VERSION = "63.2.0"
-_PIP_VERSION = "22.2.1"
+_PIP_VERSION = "22.2.2"
_PROJECTS = [
("setuptools", _SETUPTOOLS_VERSION, "py3"),
("pip", _PIP_VERSION, "py3"),
original creator of IDLE. Other contributors prior to Version 0.8 include
Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka.
-IDLE's recent development was carried out in the SF IDLEfork project. The
+Until Python 2.3, IDLE's development was carried out in the SF IDLEfork project. The
objective was to develop a version of IDLE which had an execution environment
which could be initialized prior to each run of user code.
+IDLefork was merged into the Python code base in 2003.
The IDLEfork project was initiated by David Scherer, with some help from Peter
Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC
Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful
patches. Thanks, guys!
+Major contributors since 2005:
+
+- 2005: Tal Einat
+- 2010: Terry Jan Reedy (current maintainer)
+- 2013: Roger Serwys
+- 2014: Saimadhav Heblikar
+- 2015: Mark Roseman
+- 2017: Louie Lu, Cheryl Sabella, and Serhiy Storchaka
+
For additional details refer to NEWS.txt and Changelog.
Please contact the IDLE maintainer (kbk@shore.net) to have yourself included
=========================
+gh-65802: Document handling of extensions in Save As dialogs.
+
+gh-95191: Include prompts when saving Shell (interactive input/output).
+
gh-95511: Fix the Shell context menu copy-with-prompts bug of copying
an extra line when one selects whole lines.
IDLELIB FILES
+=============
+
Implementation files not in IDLE MENU are marked (nim).
-Deprecated files and objects are listed separately as the end.
Startup
-------
autocomplete_w.py # Display completions.
autoexpand.py # Expand word with previous word in file.
browser.py # Create module browser window.
+calltip.py # Create calltip text.
calltip_w.py # Display calltip.
-calltips.py # Create calltip text.
codecontext.py # Show compound statement headers otherwise not visible.
-colorizer.py # Colorize text (nim)
+colorizer.py # Colorize text (nim).
config.py # Load, fetch, and save configuration (nim).
configdialog.py # Display user configuration dialogs.
-config_help.py # Specify help source in configdialog.
config_key.py # Change keybindings.
-dynoption.py # Define mutable OptionMenu widget (nim).
-debugobj.py # Define class used in stackviewer.
-debugobj_r.py # Communicate objects between processes with rpc (nim).
debugger.py # Debug code run from shell or editor; show window.
debugger_r.py # Debug code run in remote process.
+debugobj.py # Define class used in stackviewer.
+debugobj_r.py # Communicate objects between processes with rpc (nim).
delegator.py # Define base class for delegators (nim).
+dynoption.py # Define mutable OptionMenu widget (nim)
editor.py # Define most of editor and utility functions.
filelist.py # Open files and manage list of open windows (nim).
+format.py # Define format menu options.
grep.py # Find all occurrences of pattern in multiple files.
help.py # Display IDLE's html doc.
help_about.py # Display About IDLE dialog.
mainmenu.py # Define most of IDLE menu.
multicall.py # Wrap tk widget to allow multiple calls per event (nim).
outwin.py # Create window for grep output.
-paragraph.py # Re-wrap multiline strings and comments.
parenmatch.py # Match fenceposts: (), [], and {}.
pathbrowser.py # Create path browser window.
percolator.py # Manage delegator stack (nim).
redirector.py # Intercept widget subcommands (for percolator) (nim).
replace.py # Search and replace pattern in text.
rpc.py # Communicate between idle and user processes (nim).
-rstrip.py # Strip trailing whitespace.
run.py # Manage user code execution subprocess.
runscript.py # Check and run user code.
scrolledlist.py # Define scrolledlist widget for IDLE (nim).
search.py # Search for pattern in text.
searchbase.py # Define base for search, replace, and grep dialogs.
searchengine.py # Define engine for all 3 search dialogs.
+sidebar.py # Define line number and shell prompt sidebars.
+squeezer.py # Squeeze long shell output (nim).
stackviewer.py # View stack after exception.
statusbar.py # Define status bar for windows (nim).
tabbedpages.py # Define tabbed pages widget (nim).
textview.py # Define read-only text widget (nim).
+tooltip.py # Define popups for calltips, squeezer (nim).
tree.py # Define tree widget, used in browsers (nim).
undo.py # Manage undo stack.
-util.py # Define objects imported elsewhere with no dependencies (nim)
+util.py # Define common objects imported elsewhere (nim).
windows.py # Manage window list and define listed top level.
zoomheight.py # Zoom window to full height of screen.
+zzdummy.py # Example extension.
Configuration
-------------
CREDITS.txt # not maintained, displayed by About IDLE
HISTORY.txt # NEWS up to July 2001
NEWS.txt # commits, displayed by About IDLE
+NEWS2.txt # commits to Python2
README.txt # this file, displayed by About IDLE
TODO.txt # needs review
extend.txt # about writing extensions
Icons # small image files
idle_test # files for human test and automated unit tests
-Unused and Deprecated files and objects (nim)
----------------------------------------------
-tooltip.py # unused
-
-
IDLE MENUS
+==========
+
Top level items and most submenu items are defined in mainmenu.
Extensions add submenu items when active. The names given are
found, quoted, in one of these modules, paired with a '<<pseudoevent>>'.
Show call tip # Calltips extension and CalltipWindow (& Hyperparser)
Show surrounding parens # parenmatch (& Hyperparser)
+Format (Editor only) [fFR = format.FormatRegion]
+ Format Paragraph # format.FormatParagraph.format_paragraph_event
+ Indent Region # fFR.indent_region_event
+ Dedent Region # fFR.dedent_region_event
+ Comment Out Reg. # fFR.comment_region_event
+ Uncomment Region # fFR.uncomment_region_event
+ Tabify Region # fFR.tabify_region_event
+ Untabify Region # fFR.untabify_region_event
+ Toggle Tabs # format.Indents.toggle_tabs_event
+ New Indent Width # format.Indents.change_indentwidth_event
+ Strip tailing whitespace # format.rstrip
+ Zin # zzdummy
+ Zout # zzdummy
+
+Run (Editor only)
+ Run Module # runscript.ScriptBinding.run_module_event
+ Run... Customized # runscript.ScriptBinding.run_custom_event
+ Check Module # runscript.ScriptBinding.check_module_event
+ Python Shell # pyshell.Pyshell, pyshell.ModifiedInterpreter
+
Shell # pyshell
View Last Restart # pyshell.PyShell.view_restart_mark
Restart Shell # pyshell.PyShell.restart_shell
+ Previous History # history.History.history_prev
+ Next History # history.History.history_next
Interrupt Execution # pyshell.PyShell.cancel_callback
Debug (Shell only)
- Go to File/Line
+ Go to File/Line # outwin.OutputWindow.goto_file_line
debugger # debugger, debugger_r, PyShell.toggle_debugger
Stack Viewer # stackviewer, PyShell.open_stack_viewer
Auto-open Stack Viewer # stackviewer
-Format (Editor only)
- Indent Region # eEW.indent_region_event
- Dedent Region # eEW.dedent_region_event
- Comment Out Reg. # eEW.comment_region_event
- Uncomment Region # eEW.uncomment_region_event
- Tabify Region # eEW.tabify_region_event
- Untabify Region # eEW.untabify_region_event
- Toggle Tabs # eEW.toggle_tabs_event
- New Indent Width # eEW.change_indentwidth_event
- Format Paragraph # paragraph extension
- ---
- Strip tailing whitespace # rstrip extension
-
-Run (Editor only)
- Python Shell # pyshell
- ---
- Check Module # runscript
- Run Module # runscript
-
Options
- Configure IDLE # eEW.config_dialog, configdialog
- (tabs in the dialog)
- Font tab # config-main.def
- Highlight tab # query, config-highlight.def
- Keys tab # query, config_key, config_keys.def
- General tab # config_help, config-main.def
- Extensions tab # config-extensions.def, corresponding .py
+ Configure IDLE # eEW.config_dialog, config, configdialog (cd)
+ (Parts of the dialog)
+ Buttons # cd.ConfigDialog
+ Font tab # cd.FontPage, config-main.def
+ Highlight tab # cd.HighPage, query, config-highlight.def
+ Keys tab # cd.KeysPage, query, config_key, config_keys.def
+ Windows tab # cd.WinPage, config_main.def
+ Shell/Ed tab # cd.ShedPage, config-main.def
+ Extensions tab # config-extensions.def, corresponding .py files
---
- Code Context (ed)# codecontext extension
+ ... Code Context # codecontext
+ ... Line Numbers # sidebar
+ Zoomheight # zoomheight
Window
- Zoomheight # zoomheight extension
- ---
<open windows> # windows
Help
About IDLE # eEW.about_dialog, help_about.AboutDialog
---
- IDLE Help # eEW.help_dialog, helpshow_idlehelp
- Python Doc # eEW.python_docs
+ IDLE Help # eEW.help_dialog, help.show_idlehelp
+ Python Docs # eEW.python_docs
Turtle Demo # eEW.open_turtle_demo
---
<other help sources>
<Context Menu> (right click)
- Defined in editor, PyShelpyshellut
+ Defined in editor, PyShell.pyshell
Cut
Copy
Paste
Center Insert # eEW.center_insert_event
-CODE STYLE -- Generally PEP 8.
+OTHER TOPICS
+============
+
+Generally use PEP 8.
-import
-------
-Put import at the top, unless there is a good reason otherwise.
+import statements
+-----------------
+Put imports at the top, unless there is a good reason otherwise.
PEP 8 says to group stdlib, 3rd-party dependencies, and package imports.
For idlelib, the groups are general stdlib, tkinter, and idlelib.
Sort modules within each group, except that tkinter.ttk follows tkinter.
Within module imports like "from idlelib.mod import class" may cause
circular imports to deadlock. Even without this, circular imports may
require at least one of the imports to be delayed until a function call.
+
+What's New entries
+------------------
+
+Repository directory Doc/whatsnew/ has a file 3.n.rst for each 3.n
+Python version. For the first entry in each file, add subsection
+'IDLE and idlelib', in alphabetical position, to the 'Improved Modules'
+section. For the rest of cpython, entries to 3.(n+1).rst begin with
+the release of 3.n.0b1. For IDLE, entries for features backported from
+'main' to '3.n' during its beta period do not got in 3.(n+1).rst. The
+latter usually gets its first entry during the 3.n.0 candidate period
+or after the 3.n.0 release.
+
+When, as per PEP 434, feature changes are backported, entries are placed
+in the 3.n.rst file *in the main branch* for each Python version n that
+gets the backport. (Note: the format of entries have varied between
+versions.) Add a line "New in 3.n maintenance releases." before the
+first back-ported feature after 3.n.0 is released. Since each older
+version file gets a different number of backports, it is easiest to
+make a separate PR for each file and label it with the backports
+needed.
+
+Github repository and issues
+----------------------------
+
+The CPython repository is https://github.com/python/cpython. The
+IDLE Issues listing is https://github.com/orgs/python/projects/31.
+The main classification is by Topic, based on the IDLE menu. View the
+topics list by clicking the [<]] button in the upper right.
# If obj.name != key, it has already been suffixed.
supers = []
for sup in obj.super:
- if type(sup) is type(''):
+ if isinstance(sup, str):
sname = sup
else:
sname = sup.name
"""
return ('<<'+virtualEvent+'>>') in self.GetCoreKeys()
-# TODO make keyBindins a file or class attribute used for test above
+# TODO make keyBindings a file or class attribute used for test above
# and copied in function below.
former_extension_events = { # Those with user-configurable keys.
self.winpage = WinPage(note)
self.shedpage = ShedPage(note)
- note.add(self.fontpage, text='Fonts/Tabs')
+ note.add(self.fontpage, text=' Fonts ')
note.add(self.highpage, text='Highlights')
note.add(self.keyspage, text=' Keys ')
note.add(self.winpage, text=' Windows ')
dochome = os.path.join(basepath, pyver,
'Doc', 'index.html')
elif sys.platform[:3] == 'win':
- chmfile = os.path.join(sys.base_prefix, 'Doc',
- 'Python%s.chm' % _sphinx_version())
- if os.path.isfile(chmfile):
- dochome = chmfile
+ import winreg # Windows only, block only executed once.
+ docfile = ''
+ KEY = (rf"Software\Python\PythonCore\{sys.winver}"
+ r"\Help\Main Python Documentation")
+ try:
+ docfile = winreg.QueryValue(winreg.HKEY_CURRENT_USER, KEY)
+ except FileNotFoundError:
+ try:
+ docfile = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE,
+ KEY)
+ except FileNotFoundError:
+ pass
+ if os.path.isfile(docfile):
+ dochome = docfile
elif sys.platform == 'darwin':
# documentation may be stored inside a python framework
dochome = os.path.join(sys.base_prefix,
<li><a class="reference internal" href="#editor-windows">Editor windows</a></li>
<li><a class="reference internal" href="#key-bindings">Key bindings</a></li>
<li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li>
+<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li>
<li><a class="reference internal" href="#completions">Completions</a></li>
<li><a class="reference internal" href="#calltips">Calltips</a></li>
<li><a class="reference internal" href="#code-context">Code Context</a></li>
<li><a class="reference internal" href="#extensions">Extensions</a></li>
</ul>
</li>
+<li><a class="reference internal" href="#module-idlelib">idlelib</a></li>
</ul>
</li>
</ul>
</dd>
<dt>Open…</dt><dd><p>Open an existing file with an Open dialog.</p>
</dd>
-<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p>
-</dd>
<dt>Open Module…</dt><dd><p>Open an existing module (searches sys.path).</p>
</dd>
+<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p>
+</dd>
</dl>
<dl class="simple" id="index-1">
-<dt>Class Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a
+<dt>Module Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a
tree structure. In the shell, open a module first.</p>
</dd>
<dt>Path Browser</dt><dd><p>Show sys.path directories, modules, functions, classes and methods in a
do Save As instead.</p>
</dd>
<dt>Save As…</dt><dd><p>Save the current window with a Save As dialog. The file saved becomes the
-new associated file for the window.</p>
+new associated file for the window. (If your file namager is set to hide
+extensions, the current extension will be omitted in the file name box.
+If the new filename has no ‘.’, ‘.py’ and ‘.txt’ will be added for Python
+and text files, except that on macOS Aqua,’.py’ is added for all files.)</p>
</dd>
<dt>Save Copy As…</dt><dd><p>Save the current window to different file without changing the associated
-file.</p>
+file. (See Save As note above about filename extensions.)</p>
</dd>
<dt>Print Window</dt><dd><p>Print the current window to the default printer.</p>
</dd>
</dd>
<dt>Redo</dt><dd><p>Redo the last undone change to the current window.</p>
</dd>
+<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p>
+</dd>
<dt>Cut</dt><dd><p>Copy selection into the system-wide clipboard; then delete the selection.</p>
</dd>
<dt>Copy</dt><dd><p>Copy selection into the system-wide clipboard.</p>
</dl>
<p>The clipboard functions are also available in context menus.</p>
<dl class="simple">
-<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p>
-</dd>
<dt>Find…</dt><dd><p>Open a search dialog with many options</p>
</dd>
<dt>Find Again</dt><dd><p>Repeat the last search, if there is one.</p>
<dt>Expand Word</dt><dd><p>Expand a prefix you have typed to match a full word in the same window;
repeat to get a different expansion.</p>
</dd>
-<dt>Show call tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with
+<dt>Show Call Tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with
function parameter hints. See <a class="reference internal" href="#calltips"><span class="std std-ref">Calltips</span></a> in the
Editing and navigation section below.</p>
</dd>
-<dt>Show surrounding parens</dt><dd><p>Highlight the surrounding parenthesis.</p>
+<dt>Show Surrounding Parens</dt><dd><p>Highlight the surrounding parenthesis.</p>
</dd>
</dl>
</section>
<section id="format-menu-editor-window-only">
<span id="format-menu"></span><h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this heading">¶</a></h3>
<dl class="simple">
+<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or
+multiline string or selected line in a string. All lines in the
+paragraph will be formatted to less than N columns, where N defaults to 72.</p>
+</dd>
<dt>Indent Region</dt><dd><p>Shift selected lines right by the indent width (default 4 spaces).</p>
</dd>
<dt>Dedent Region</dt><dd><p>Shift selected lines left by the indent width (default 4 spaces).</p>
<dt>New Indent Width</dt><dd><p>Open a dialog to change indent width. The accepted default by the Python
community is 4 spaces.</p>
</dd>
-<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or
-multiline string or selected line in a string. All lines in the
-paragraph will be formatted to less than N columns, where N defaults to 72.</p>
-</dd>
-<dt>Strip trailing whitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last
+<dt>Strip Trailing Chitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last
non-whitespace character of a line by applying str.rstrip to each line,
including lines within multiline strings. Except for Shell windows,
remove extra newlines at the end of the file.</p>
<p>See also the indent/dedent region commands on the
<a class="reference internal" href="#format-menu"><span class="std std-ref">Format menu</span></a>.</p>
</section>
+<section id="search-and-replace">
+<h3>Search and Replace<a class="headerlink" href="#search-and-replace" title="Permalink to this heading">¶</a></h3>
+<p>Any selection becomes a search target. However, only selections within
+a line work because searches are only performed within lines with the
+terminal newline removed. If <code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">Regular</span> <span class="pre">expresion</span></code> is checked, the
+target is interpreted according to the Python re module.</p>
+</section>
<section id="completions">
<span id="id3"></span><h3>Completions<a class="headerlink" href="#completions" title="Permalink to this heading">¶</a></h3>
<p>Completions are supplied, when requested and available, for module
also used for testing.</p>
</section>
</section>
+<section id="module-idlelib">
+<span id="idlelib"></span><h2>idlelib<a class="headerlink" href="#module-idlelib" title="Permalink to this heading">¶</a></h2>
+<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/main/Lib/idlelib">Lib/idlelib</a></p>
+<hr class="docutils" />
+<p>The Lib/idlelib package implements the IDLE application. See the rest
+of this page for how to use IDLE.</p>
+<p>The files in idlelib are described in idlelib/README.txt. Access it
+either in idlelib or click Help => About IDLE on the IDLE menu. This
+file also maps IDLE menu items to the code that implements the item.
+Except for files listed under ‘Startup’, the idlelib code is ‘private’ in
+sense that feature changes can be backported (see <span class="target" id="index-7"></span><a class="pep reference external" href="https://peps.python.org/pep-0434/"><strong>PEP 434</strong></a>).</p>
+</section>
</section>
<li><a class="reference internal" href="#editor-windows">Editor windows</a></li>
<li><a class="reference internal" href="#key-bindings">Key bindings</a></li>
<li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li>
+<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li>
<li><a class="reference internal" href="#completions">Completions</a></li>
<li><a class="reference internal" href="#calltips">Calltips</a></li>
<li><a class="reference internal" href="#code-context">Code Context</a></li>
<li><a class="reference internal" href="#extensions">Extensions</a></li>
</ul>
</li>
+<li><a class="reference internal" href="#module-idlelib">idlelib</a></li>
</ul>
</li>
</ul>
<br />
<br />
- Last updated on Jul 03, 2022.
+ Last updated on Sep 03, 2022.
<a href="/bugs.html">Found a bug</a>?
<br />
"Test , coverage 17%."
-from idlelib import iomenu, util
+from idlelib import iomenu
import unittest
from test.support import requires
from tkinter import Tk
from idlelib.editor import EditorWindow
+from idlelib import util
+from idlelib.idle_test.mock_idle import Func
class IOBindingTest(unittest.TestCase):
io = self.io
fix = io.fixnewlines
text = io.editwin.text
+
+ # Make the editor temporarily look like Shell.
self.editwin.interp = None
- eq(fix(), '')
- del self.editwin.interp
+ shelltext = '>>> if 1'
+ self.editwin.get_prompt_text = Func(result=shelltext)
+ eq(fix(), shelltext) # Get... call and '\n' not added.
+ del self.editwin.interp, self.editwin.get_prompt_text
+
text.insert(1.0, 'a')
eq(fix(), 'a'+io.eol_convention)
eq(text.get('1.0', 'end-1c'), 'a\n')
import unittest
import unittest.mock
from test.support import requires, swap_attr
+from test import support
import tkinter as tk
from idlelib.idle_test.tkinter_testing_utils import run_in_tk_mainloop
@run_in_tk_mainloop()
def test_very_long_wrapped_line(self):
- with swap_attr(self.shell, 'squeezer', None):
+ with support.adjust_int_max_str_digits(11_111), \
+ swap_attr(self.shell, 'squeezer', None):
self.do_input('x = ' + '1'*10_000 + '\n')
yield
self.assertEqual(self.get_sidebar_lines(), ['>>>'])
return False
def fixnewlines(self):
- "Return text with final \n if needed and os eols."
- if (self.text.get("end-2c") != '\n'
- and not hasattr(self.editwin, "interp")): # Not shell.
- self.text.insert("end-1c", "\n")
- text = self.text.get("1.0", "end-1c")
+ """Return text with os eols.
+
+ Add prompts if shell else final \n if missing.
+ """
+
+ if hasattr(self.editwin, "interp"): # Saving shell.
+ text = self.editwin.get_prompt_text('1.0', self.text.index('end-1c'))
+ else:
+ if self.text.get("end-2c") != '\n':
+ self.text.insert("end-1c", "\n") # Changes 'end-1c' value.
+ text = self.text.get('1.0', "end-1c")
if self.eol_convention != "\n":
text = text.replace("\n", self.eol_convention)
return text
('help', [
('_About IDLE', '<<about-idle>>'),
None,
- ('_IDLE Help', '<<help>>'),
+ ('_IDLE Doc', '<<help>>'),
('Python _Docs', '<<python-docs>>'),
]),
]
def get_standard_extension_names(self):
return idleConf.GetExtensions(shell_only=True)
+ def get_prompt_text(self, first, last):
+ """Return text between first and last with prompts added."""
+ text = self.text.get(first, last)
+ lineno_range = range(
+ int(float(first)),
+ int(float(last))
+ )
+ prompts = [
+ self.shell_sidebar.line_prompts.get(lineno)
+ for lineno in lineno_range
+ ]
+ return "\n".join(
+ line if prompt is None else f"{prompt} {line}"
+ for prompt, line in zip(prompts, text.splitlines())
+ ) + "\n"
+
+
def copy_with_prompts_callback(self, event=None):
"""Copy selected lines to the clipboard, with prompts.
sellast = text.index('sel.last')
if sellast[-1] != '0':
sellast = text.index("sel.last+1line linestart")
-
- selected_text = self.text.get(selfirst, sellast)
- selection_lineno_range = range(
- int(float(selfirst)),
- int(float(sellast))
- )
- prompts = [
- self.shell_sidebar.line_prompts.get(lineno)
- for lineno in selection_lineno_range
- ]
- selected_text_with_prompts = "\n".join(
- line if prompt is None else f"{prompt} {line}"
- for prompt, line in zip(prompts, selected_text.splitlines())
- ) + "\n"
-
text.clipboard_clear()
- text.clipboard_append(selected_text_with_prompts)
+ prompt_text = self.get_prompt_text(selfirst, sellast)
+ text.clipboard_append(prompt_text)
reading = False
executing = False
self.lineno = lineno
self.funcName = func
self.created = ct
- self.msecs = (ct - int(ct)) * 1000
+ self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047
self.relativeCreated = (self.created - _startTime) * 1000
if logThreads:
self.thread = threading.get_ident()
"""Configure a non-root logger from a dictionary."""
logger = logging.getLogger(name)
self.common_logger_config(logger, config, incremental)
+ logger.disabled = False
propagate = config.get('propagate', None)
if propagate is not None:
logger.propagate = propagate
record is not used, as we are just comparing times, but it is needed so
the method signatures are the same
"""
- # See bpo-45401: Never rollover anything other than regular files
- if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
- return False
t = int(time.time())
if t >= self.rolloverAt:
+ # See #89564: Never rollover anything other than regular files
+ if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
+ # The file is not a regular file, so do not rollover, but do
+ # set the next rollover time to avoid repeated checks.
+ self.rolloverAt = self.computeRollover(t)
+ return False
+
return True
return False
dllname = os.path.join(dllname[0], r'win32service.pyd')
self.dllname = dllname
self.logtype = logtype
- self._welu.AddSourceToRegistry(appname, dllname, logtype)
+ # Administrative privileges are required to add a source to the registry.
+ # This may not be available for a user that just wants to add to an
+ # existing source - handle this specific case.
+ try:
+ self._welu.AddSourceToRegistry(appname, dllname, logtype)
+ except Exception as e:
+ # This will probably be a pywintypes.error. Only raise if it's not
+ # an "access denied" error, else let it pass
+ if getattr(e, 'winerror', None) != 5: # not access denied
+ raise
self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE
self.typemap = {
logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE,
so that ratios of huge integers convert without overflowing.
"""
- return self.numerator / self.denominator
+ return int(self.numerator) / int(self.denominator)
class Integral(Rational):
initial_slashes = path.startswith(sep)
# POSIX allows one or two initial slashes, but treats three or more
# as single slash.
- # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
+ # (see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
if (initial_slashes and
path.startswith(sep*2) and not path.startswith(sep*3)):
initial_slashes = 2
# -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Mon Aug 1 21:23:42 2022
+# Autogenerated by Sphinx on Mon Sep 5 13:02:42 2022
topics = {'assert': 'The "assert" statement\n'
'**********************\n'
'\n'
' there is matched against the whole object rather than an '
'attribute.\n'
' For example "int(0|1)" matches the value "0", but not the '
- 'values\n'
- ' "0.0" or "False".\n'
+ 'value\n'
+ ' "0.0".\n'
'\n'
'In simple terms "CLS(P1, attr=P2)" matches only if the '
'following\n'
' still alive. The list is in definition order. Example:\n'
'\n'
' >>> int.__subclasses__()\n'
- " [<class 'bool'>]\n"
- '\n'
- '-[ Footnotes ]-\n'
- '\n'
- '[1] Additional information on these special methods may be '
- 'found in\n'
- ' the Python Reference Manual (Basic customization).\n'
- '\n'
- '[2] As a consequence, the list "[1, 2]" is considered equal '
- 'to "[1.0,\n'
- ' 2.0]", and similarly for tuples.\n'
- '\n'
- '[3] They must have since the parser can’t tell the type of '
- 'the\n'
- ' operands.\n'
- '\n'
- '[4] Cased characters are those with general category '
- 'property being\n'
- ' one of “Lu” (Letter, uppercase), “Ll” (Letter, '
- 'lowercase), or “Lt”\n'
- ' (Letter, titlecase).\n'
- '\n'
- '[5] To format only a tuple you should therefore provide a '
- 'singleton\n'
- ' tuple whose only element is the tuple to be formatted.\n',
+ " [<class 'bool'>]\n",
'specialnames': 'Special method names\n'
'********************\n'
'\n'
'| Escape Sequence | Meaning | Notes '
'|\n'
'|===================|===================================|=========|\n'
- '| "\\newline" | Backslash and newline ignored '
- '| |\n'
+ '| "\\"<newline> | Backslash and newline ignored | '
+ '(1) |\n'
'+-------------------+-----------------------------------+---------+\n'
'| "\\\\" | Backslash ("\\") '
'| |\n'
'| |\n'
'+-------------------+-----------------------------------+---------+\n'
'| "\\ooo" | Character with octal value *ooo* | '
- '(1,3) |\n'
+ '(2,4) |\n'
'+-------------------+-----------------------------------+---------+\n'
'| "\\xhh" | Character with hex value *hh* | '
- '(2,3) |\n'
+ '(3,4) |\n'
'+-------------------+-----------------------------------+---------+\n'
'\n'
'Escape sequences only recognized in string literals are:\n'
'|\n'
'|===================|===================================|=========|\n'
'| "\\N{name}" | Character named *name* in the | '
- '(4) |\n'
+ '(5) |\n'
'| | Unicode database | '
'|\n'
'+-------------------+-----------------------------------+---------+\n'
'| "\\uxxxx" | Character with 16-bit hex value | '
- '(5) |\n'
+ '(6) |\n'
'| | *xxxx* | '
'|\n'
'+-------------------+-----------------------------------+---------+\n'
'| "\\Uxxxxxxxx" | Character with 32-bit hex value | '
- '(6) |\n'
+ '(7) |\n'
'| | *xxxxxxxx* | '
'|\n'
'+-------------------+-----------------------------------+---------+\n'
'\n'
'Notes:\n'
'\n'
- '1. As in Standard C, up to three octal digits are accepted.\n'
+ '1. A backslash can be added at the end of a line to ignore the\n'
+ ' newline:\n'
+ '\n'
+ " >>> 'This string will not include \\\n"
+ " ... backslashes or newline characters.'\n"
+ " 'This string will not include backslashes or newline "
+ "characters.'\n"
+ '\n'
+ ' The same result can be achieved using triple-quoted strings, '
+ 'or\n'
+ ' parentheses and string literal concatenation.\n'
+ '\n'
+ '2. As in Standard C, up to three octal digits are accepted.\n'
'\n'
- '2. Unlike in Standard C, exactly two hex digits are required.\n'
+ '3. Unlike in Standard C, exactly two hex digits are required.\n'
'\n'
- '3. In a bytes literal, hexadecimal and octal escapes denote the '
+ '4. In a bytes literal, hexadecimal and octal escapes denote the '
'byte\n'
' with the given value. In a string literal, these escapes '
'denote a\n'
' Unicode character with the given value.\n'
'\n'
- '4. Changed in version 3.3: Support for name aliases [1] has been\n'
+ '5. Changed in version 3.3: Support for name aliases [1] has been\n'
' added.\n'
'\n'
- '5. Exactly four hex digits are required.\n'
+ '6. Exactly four hex digits are required.\n'
'\n'
- '6. Any Unicode character can be encoded this way. Exactly eight '
+ '7. Any Unicode character can be encoded this way. Exactly eight '
'hex\n'
' digits are required.\n'
'\n'
"""Test date/time type.
-See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
+See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases
"""
import io
import itertools
if warnings.filters != new_filters:
warnings.filters[:] = new_filters
warnings._filters_mutated()
+
+
+@contextlib.contextmanager
+def adjust_int_max_str_digits(max_digits):
+ """Temporarily change the integer string conversion length limit."""
+ current = sys.get_int_max_str_digits()
+ try:
+ sys.set_int_max_str_digits(max_digits)
+ yield
+ finally:
+ sys.set_int_max_str_digits(current)
expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
+ def test_positional_only_feature_version(self):
+ ast.parse('def foo(x, /): ...', feature_version=(3, 8))
+ ast.parse('def bar(x=1, /): ...', feature_version=(3, 8))
+ with self.assertRaises(SyntaxError):
+ ast.parse('def foo(x, /): ...', feature_version=(3, 7))
+ with self.assertRaises(SyntaxError):
+ ast.parse('def bar(x=1, /): ...', feature_version=(3, 7))
+
+ ast.parse('lambda x, /: ...', feature_version=(3, 8))
+ ast.parse('lambda x=1, /: ...', feature_version=(3, 8))
+ with self.assertRaises(SyntaxError):
+ ast.parse('lambda x, /: ...', feature_version=(3, 7))
+ with self.assertRaises(SyntaxError):
+ ast.parse('lambda x=1, /: ...', feature_version=(3, 7))
+
def test_parenthesized_with_feature_version(self):
ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10))
# While advertised as a feature in Python 3.10, this was allowed starting 3.9
ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8))
ast.parse('with CtxManager() as example: ...', feature_version=(3, 8))
- def test_issue40614_feature_version(self):
+ def test_debug_f_string_feature_version(self):
ast.parse('f"{x=}"', feature_version=(3, 8))
with self.assertRaises(SyntaxError):
ast.parse('f"{x=}"', feature_version=(3, 7))
self.assertRaises(ValueError, ast.literal_eval, '+True')
self.assertRaises(ValueError, ast.literal_eval, '2+3')
+ def test_literal_eval_str_int_limit(self):
+ with support.adjust_int_max_str_digits(4000):
+ ast.literal_eval('3'*4000) # no error
+ with self.assertRaises(SyntaxError) as err_ctx:
+ ast.literal_eval('3'*4001)
+ self.assertIn('Exceeds the limit ', str(err_ctx.exception))
+ self.assertIn(' Consider hexadecimal ', str(err_ctx.exception))
+
def test_literal_eval_complex(self):
# Issue #4907
self.assertEqual(ast.literal_eval('6j'), 6j)
self.watcher._sig_chld()
if isinstance(self.watcher, asyncio.FastChildWatcher):
- # here the FastChildWatche enters a deadlock
+ # here the FastChildWatcher enters a deadlock
# (there is no way to prevent it)
self.assertFalse(callback.called)
else:
t.start()
t.join()
+ @threading_helper.reap_threads
+ def test_gilstate_ensure_no_deadlock(self):
+ # See https://github.com/python/cpython/issues/96071
+ code = textwrap.dedent(f"""
+ import _testcapi
+
+ def callback():
+ print('callback called')
+
+ _testcapi._test_thread_state(callback)
+ """)
+ ret = assert_python_ok('-X', 'tracemalloc', '-c', code)
+ self.assertIn(b'callback called', ret.out)
+
class Test_testcapi(unittest.TestCase):
locals().update((name, getattr(_testcapi, name))
import unittest
import test.test_tools
+from test.support.warnings_helper import save_restore_warnings_filters
test.test_tools.skip_if_missing('c-analyzer')
with test.test_tools.imports_under_tool('c-analyzer'):
- from cpython.__main__ import main
+ # gh-95349: Save/restore warnings filters to leave them unchanged.
+ # Importing the c-analyzer imports docutils which imports pkg_resources
+ # which adds a warnings filter.
+ with save_restore_warnings_filters():
+ from cpython.__main__ import main
class ActualChecks(unittest.TestCase):
self.assertTrue(proc.stderr.startswith(err_msg), proc.stderr)
self.assertNotEqual(proc.returncode, 0)
+ def test_int_max_str_digits(self):
+ code = "import sys; print(sys.flags.int_max_str_digits, sys.get_int_max_str_digits())"
+
+ assert_python_failure('-X', 'int_max_str_digits', '-c', code)
+ assert_python_failure('-X', 'int_max_str_digits=foo', '-c', code)
+ assert_python_failure('-X', 'int_max_str_digits=100', '-c', code)
+
+ assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='foo')
+ assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='100')
+
+ def res2int(res):
+ out = res.out.strip().decode("utf-8")
+ return tuple(int(i) for i in out.split())
+
+ res = assert_python_ok('-c', code)
+ self.assertEqual(res2int(res), (-1, sys.get_int_max_str_digits()))
+ res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code)
+ self.assertEqual(res2int(res), (0, 0))
+ res = assert_python_ok('-X', 'int_max_str_digits=4000', '-c', code)
+ self.assertEqual(res2int(res), (4000, 4000))
+ res = assert_python_ok('-X', 'int_max_str_digits=100000', '-c', code)
+ self.assertEqual(res2int(res), (100000, 100000))
+
+ res = assert_python_ok('-c', code, PYTHONINTMAXSTRDIGITS='0')
+ self.assertEqual(res2int(res), (0, 0))
+ res = assert_python_ok('-c', code, PYTHONINTMAXSTRDIGITS='4000')
+ self.assertEqual(res2int(res), (4000, 4000))
+ res = assert_python_ok(
+ '-X', 'int_max_str_digits=6000', '-c', code,
+ PYTHONINTMAXSTRDIGITS='4000'
+ )
+ self.assertEqual(res2int(res), (6000, 6000))
+
@unittest.skipIf(interpreter_requires_environment(),
'Cannot run -I tests when PYTHON env vars are required.')
self.assertEqual(eval("0o777"), 511)
self.assertEqual(eval("-0o0000010"), -8)
+ def test_int_literals_too_long(self):
+ n = 3000
+ source = f"a = 1\nb = 2\nc = {'3'*n}\nd = 4"
+ with support.adjust_int_max_str_digits(n):
+ compile(source, "<long_int_pass>", "exec") # no errors.
+ with support.adjust_int_max_str_digits(n-1):
+ with self.assertRaises(SyntaxError) as err_ctx:
+ compile(source, "<long_int_fail>", "exec")
+ exc = err_ctx.exception
+ self.assertEqual(exc.lineno, 3)
+ self.assertIn('Exceeds the limit ', str(exc))
+ self.assertIn(' Consider hexadecimal ', str(exc))
+
def test_unary_minus(self):
# Verify treatment of unary minus on negative numbers SF bug #660455
if sys.maxsize == 2147483647:
import pickle
import sys
import types
+import traceback
import unittest
import warnings
from test import support
return 'end'
self.assertEqual(run_async(run_gen()), ([], 'end'))
+ def test_stack_in_coroutine_throw(self):
+ # Regression test for https://github.com/python/cpython/issues/93592
+ async def a():
+ return await b()
+
+ async def b():
+ return await c()
+
+ @types.coroutine
+ def c():
+ try:
+ # traceback.print_stack()
+ yield len(traceback.extract_stack())
+ except ZeroDivisionError:
+ # traceback.print_stack()
+ yield len(traceback.extract_stack())
+
+ coro = a()
+ len_send = coro.send(None)
+ len_throw = coro.throw(ZeroDivisionError)
+ # before fixing, visible stack from throw would be shorter than from send.
+ self.assertEqual(len_send, len_throw)
+
class CoroAsyncIOCompatTest(unittest.TestCase):
self.assertEqual(csv.get_dialect(name).delimiter, ';')
self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name)))
+ def test_register_kwargs_override(self):
+ class mydialect(csv.Dialect):
+ delimiter = "\t"
+ quotechar = '"'
+ doublequote = True
+ skipinitialspace = False
+ lineterminator = '\r\n'
+ quoting = csv.QUOTE_MINIMAL
+
+ name = 'test_dialect'
+ csv.register_dialect(name, mydialect,
+ delimiter=';',
+ quotechar="'",
+ doublequote=False,
+ skipinitialspace=True,
+ lineterminator='\n',
+ quoting=csv.QUOTE_ALL)
+ self.addCleanup(csv.unregister_dialect, name)
+
+ # Ensure that kwargs do override attributes of a dialect class:
+ dialect = csv.get_dialect(name)
+ self.assertEqual(dialect.delimiter, ';')
+ self.assertEqual(dialect.quotechar, "'")
+ self.assertEqual(dialect.doublequote, False)
+ self.assertEqual(dialect.skipinitialspace, True)
+ self.assertEqual(dialect.lineterminator, '\n')
+ self.assertEqual(dialect.quoting, csv.QUOTE_ALL)
+
def test_incomplete_dialect(self):
class myexceltsv(csv.Dialect):
delimiter = "\t"
self.assertEqual(c.z, 100)
def test_no_init(self):
- dataclass(init=False)
+ @dataclass(init=False)
class C:
i: int = 0
self.assertEqual(C().i, 0)
- dataclass(init=False)
+ @dataclass(init=False)
class C:
i: int = 2
def __init__(self):
class PyUsabilityTest(UsabilityTest):
decimal = P
+ def setUp(self):
+ super().setUp()
+ self._previous_int_limit = sys.get_int_max_str_digits()
+ sys.set_int_max_str_digits(7000)
+
+ def tearDown(self):
+ sys.set_int_max_str_digits(self._previous_int_limit)
+ super().tearDown()
+
class PythonAPItests(unittest.TestCase):
def test_abc(self):
class PyCoverage(Coverage):
decimal = P
+ def setUp(self):
+ super().setUp()
+ self._previous_int_limit = sys.get_int_max_str_digits()
+ sys.set_int_max_str_digits(7000)
+
+ def tearDown(self):
+ sys.set_int_max_str_digits(self._previous_int_limit)
+ super().tearDown()
+
class PyFunctionality(unittest.TestCase):
"""Extra functionality in decimal.py"""
# This contains most of the executable examples from Guido's descr
# tutorial, once at
#
-# http://www.python.org/2.2/descrintro.html
+# https://www.python.org/download/releases/2.2.3/descrintro/
#
# A few examples left implicit in the writeup were fleshed out, a few were
# skipped due to lack of interest (e.g., faking super() by hand isn't
check('123\xbd')
check(' 123 456 ')
check(b' 123 456 ')
+ # all whitespace (cf. https://github.com/python/cpython/issues/95605)
+ check('')
+ check(' ')
+ check('\t \n')
# non-ascii digits (error came from non-digit '!')
check('\u0663\u0661\u0664!')
def test_errors(self):
self.assertRaises(TypeError, grp.getgrgid)
+ self.assertRaises(TypeError, grp.getgrgid, 3.14)
self.assertRaises(TypeError, grp.getgrnam)
+ self.assertRaises(TypeError, grp.getgrnam, 42)
self.assertRaises(TypeError, grp.getgrall, 42)
# embedded null character
- self.assertRaises(ValueError, grp.getgrnam, 'a\x00b')
+ self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b')
# try to get some errors
bynames = {}
import sys
+import time
import unittest
from test import support
self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807)
+class IntStrDigitLimitsTests(unittest.TestCase):
+
+ int_class = int # Override this in subclasses to reuse the suite.
+
+ def setUp(self):
+ super().setUp()
+ self._previous_limit = sys.get_int_max_str_digits()
+ sys.set_int_max_str_digits(2048)
+
+ def tearDown(self):
+ sys.set_int_max_str_digits(self._previous_limit)
+ super().tearDown()
+
+ def test_disabled_limit(self):
+ self.assertGreater(sys.get_int_max_str_digits(), 0)
+ self.assertLess(sys.get_int_max_str_digits(), 20_000)
+ with support.adjust_int_max_str_digits(0):
+ self.assertEqual(sys.get_int_max_str_digits(), 0)
+ i = self.int_class('1' * 20_000)
+ str(i)
+ self.assertGreater(sys.get_int_max_str_digits(), 0)
+
+ def test_max_str_digits_edge_cases(self):
+ """Ignore the +/- sign and space padding."""
+ int_class = self.int_class
+ maxdigits = sys.get_int_max_str_digits()
+
+ int_class('1' * maxdigits)
+ int_class(' ' + '1' * maxdigits)
+ int_class('1' * maxdigits + ' ')
+ int_class('+' + '1' * maxdigits)
+ int_class('-' + '1' * maxdigits)
+ self.assertEqual(len(str(10 ** (maxdigits - 1))), maxdigits)
+
+ def check(self, i, base=None):
+ with self.assertRaises(ValueError):
+ if base is None:
+ self.int_class(i)
+ else:
+ self.int_class(i, base)
+
+ def test_max_str_digits(self):
+ maxdigits = sys.get_int_max_str_digits()
+
+ self.check('1' * (maxdigits + 1))
+ self.check(' ' + '1' * (maxdigits + 1))
+ self.check('1' * (maxdigits + 1) + ' ')
+ self.check('+' + '1' * (maxdigits + 1))
+ self.check('-' + '1' * (maxdigits + 1))
+ self.check('1' * (maxdigits + 1))
+
+ i = 10 ** maxdigits
+ with self.assertRaises(ValueError):
+ str(i)
+
+ def test_denial_of_service_prevented_int_to_str(self):
+ """Regression test: ensure we fail before performing O(N**2) work."""
+ maxdigits = sys.get_int_max_str_digits()
+ assert maxdigits < 50_000, maxdigits # A test prerequisite.
+ get_time = time.process_time
+ if get_time() <= 0: # some platforms like WASM lack process_time()
+ get_time = time.monotonic
+
+ huge_int = int(f'0x{"c"*65_000}', base=16) # 78268 decimal digits.
+ digits = 78_268
+ with support.adjust_int_max_str_digits(digits):
+ start = get_time()
+ huge_decimal = str(huge_int)
+ seconds_to_convert = get_time() - start
+ self.assertEqual(len(huge_decimal), digits)
+ # Ensuring that we chose a slow enough conversion to measure.
+ # It takes 0.1 seconds on a Zen based cloud VM in an opt build.
+ if seconds_to_convert < 0.005:
+ raise unittest.SkipTest('"slow" conversion took only '
+ f'{seconds_to_convert} seconds.')
+
+ # We test with the limit almost at the size needed to check performance.
+ # The performant limit check is slightly fuzzy, give it a some room.
+ with support.adjust_int_max_str_digits(int(.995 * digits)):
+ with self.assertRaises(ValueError) as err:
+ start = get_time()
+ str(huge_int)
+ seconds_to_fail_huge = get_time() - start
+ self.assertIn('conversion', str(err.exception))
+ self.assertLess(seconds_to_fail_huge, seconds_to_convert/8)
+
+ # Now we test that a conversion that would take 30x as long also fails
+ # in a similarly fast fashion.
+ extra_huge_int = int(f'0x{"c"*500_000}', base=16) # 602060 digits.
+ with self.assertRaises(ValueError) as err:
+ start = get_time()
+ # If not limited, 8 seconds said Zen based cloud VM.
+ str(extra_huge_int)
+ seconds_to_fail_extra_huge = get_time() - start
+ self.assertIn('conversion', str(err.exception))
+ self.assertLess(seconds_to_fail_extra_huge, seconds_to_convert/8)
+
+ def test_denial_of_service_prevented_str_to_int(self):
+ """Regression test: ensure we fail before performing O(N**2) work."""
+ maxdigits = sys.get_int_max_str_digits()
+ assert maxdigits < 100_000, maxdigits # A test prerequisite.
+ get_time = time.process_time
+ if get_time() <= 0: # some platforms like WASM lack process_time()
+ get_time = time.monotonic
+
+ digits = 133700
+ huge = '8'*digits
+ with support.adjust_int_max_str_digits(digits):
+ start = get_time()
+ int(huge)
+ seconds_to_convert = get_time() - start
+ # Ensuring that we chose a slow enough conversion to measure.
+ # It takes 0.1 seconds on a Zen based cloud VM in an opt build.
+ if seconds_to_convert < 0.005:
+ raise unittest.SkipTest('"slow" conversion took only '
+ f'{seconds_to_convert} seconds.')
+
+ with support.adjust_int_max_str_digits(digits - 1):
+ with self.assertRaises(ValueError) as err:
+ start = get_time()
+ int(huge)
+ seconds_to_fail_huge = get_time() - start
+ self.assertIn('conversion', str(err.exception))
+ self.assertLess(seconds_to_fail_huge, seconds_to_convert/8)
+
+ # Now we test that a conversion that would take 30x as long also fails
+ # in a similarly fast fashion.
+ extra_huge = '7'*1_200_000
+ with self.assertRaises(ValueError) as err:
+ start = get_time()
+ # If not limited, 8 seconds in the Zen based cloud VM.
+ int(extra_huge)
+ seconds_to_fail_extra_huge = get_time() - start
+ self.assertIn('conversion', str(err.exception))
+ self.assertLess(seconds_to_fail_extra_huge, seconds_to_convert/8)
+
+ def test_power_of_two_bases_unlimited(self):
+ """The limit does not apply to power of 2 bases."""
+ maxdigits = sys.get_int_max_str_digits()
+
+ for base in (2, 4, 8, 16, 32):
+ with self.subTest(base=base):
+ self.int_class('1' * (maxdigits + 1), base)
+ assert maxdigits < 100_000
+ self.int_class('1' * 100_000, base)
+
+ def test_underscores_ignored(self):
+ maxdigits = sys.get_int_max_str_digits()
+
+ triples = maxdigits // 3
+ s = '111' * triples
+ s_ = '1_11' * triples
+ self.int_class(s) # succeeds
+ self.int_class(s_) # succeeds
+ self.check(f'{s}111')
+ self.check(f'{s_}_111')
+
+ def test_sign_not_counted(self):
+ int_class = self.int_class
+ max_digits = sys.get_int_max_str_digits()
+ s = '5' * max_digits
+ i = int_class(s)
+ pos_i = int_class(f'+{s}')
+ assert i == pos_i
+ neg_i = int_class(f'-{s}')
+ assert -pos_i == neg_i
+ str(pos_i)
+ str(neg_i)
+
+ def _other_base_helper(self, base):
+ int_class = self.int_class
+ max_digits = sys.get_int_max_str_digits()
+ s = '2' * max_digits
+ i = int_class(s, base)
+ if base > 10:
+ with self.assertRaises(ValueError):
+ str(i)
+ elif base < 10:
+ str(i)
+ with self.assertRaises(ValueError) as err:
+ int_class(f'{s}1', base)
+
+ def test_int_from_other_bases(self):
+ base = 3
+ with self.subTest(base=base):
+ self._other_base_helper(base)
+ base = 36
+ with self.subTest(base=base):
+ self._other_base_helper(base)
+
+
+class IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests):
+ int_class = IntSubclass
+
+
if __name__ == "__main__":
unittest.main()
from io import StringIO
from collections import OrderedDict
from test.test_json import PyTest, CTest
+from test import support
class TestDecode:
d = self.json.JSONDecoder()
self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000)
+ def test_limit_int(self):
+ maxdigits = 5000
+ with support.adjust_int_max_str_digits(maxdigits):
+ self.loads('1' * maxdigits)
+ with self.assertRaises(ValueError):
+ self.loads('1' * (maxdigits + 1))
+
+
class TestPyDecode(TestDecode, PyTest): pass
class TestCDecode(TestDecode, CTest): pass
-# Copyright 2001-2021 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
"""Test harness for the logging module. Run all tests.
-Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved.
"""
import logging
logging.info('some log')
self.assertEqual(stderr.getvalue(), 'some log my_type\n')
+ def test_90195(self):
+ # See gh-90195
+ config = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'handlers': {
+ 'console': {
+ 'level': 'DEBUG',
+ 'class': 'logging.StreamHandler',
+ },
+ },
+ 'loggers': {
+ 'a': {
+ 'level': 'DEBUG',
+ 'handlers': ['console']
+ }
+ }
+ }
+ logger = logging.getLogger('a')
+ self.assertFalse(logger.disabled)
+ self.apply_config(config)
+ self.assertFalse(logger.disabled)
+ # Should disable all loggers ...
+ self.apply_config({'version': 1})
+ self.assertTrue(logger.disabled)
+ del config['disable_existing_loggers']
+ self.apply_config(config)
+ # Logger should be enabled, since explicitly mentioned
+ self.assertFalse(logger.disabled)
+
class ManagerTest(BaseTest):
def test_manager_loggerclass(self):
logged = []
f.converter = time.gmtime
self.assertEqual(f.formatTime(r), '21/04/1993 08:03:00')
+ def test_issue_89047(self):
+ f = logging.Formatter(fmt='{asctime}.{msecs:03.0f} {message}', style='{', datefmt="%Y-%m-%d %H:%M:%S")
+ for i in range(2500):
+ time.sleep(0.0004)
+ r = logging.makeLogRecord({'msg': 'Message %d' % (i + 1)})
+ s = f.format(r)
+ self.assertNotIn('.1000', s)
+
class TestBufferingFormatter(logging.BufferingFormatter):
def formatHeader(self, records):
import pyexpat
import xml.dom.minidom
-from xml.dom.minidom import parse, Node, Document, parseString
+from xml.dom.minidom import parse, Attr, Node, Document, parseString
from xml.dom.minidom import getDOMImplementation
from xml.parsers.expat import ExpatError
dom.unlink()
self.confirm(isinstance(dom, Document))
+ def testAttrModeSetsParamsAsAttrs(self):
+ attr = Attr("qName", "namespaceURI", "localName", "prefix")
+ self.assertEqual(attr.name, "qName")
+ self.assertEqual(attr.namespaceURI, "namespaceURI")
+ self.assertEqual(attr.prefix, "prefix")
+ self.assertEqual(attr.localName, "localName")
+
+ def testAttrModeSetsNonOptionalAttrs(self):
+ attr = Attr("qName", "namespaceURI", None, "prefix")
+ self.assertEqual(attr.name, "qName")
+ self.assertEqual(attr.namespaceURI, "namespaceURI")
+ self.assertEqual(attr.prefix, "prefix")
+ self.assertEqual(attr.localName, attr.name)
+
def testGetElementsByTagName(self):
dom = parse(tstfile)
self.confirm(dom.getElementsByTagName("LI") == \
_PyHASH_MODULUS = sys.hash_info.modulus
_PyHASH_INF = sys.hash_info.inf
+
+class DummyIntegral(int):
+ """Dummy Integral class to test conversion of the Rational to float."""
+
+ def __mul__(self, other):
+ return DummyIntegral(super().__mul__(other))
+ __rmul__ = __mul__
+
+ def __truediv__(self, other):
+ return NotImplemented
+ __rtruediv__ = __truediv__
+
+ @property
+ def numerator(self):
+ return DummyIntegral(self)
+
+ @property
+ def denominator(self):
+ return DummyIntegral(1)
+
+
class HashTest(unittest.TestCase):
def check_equal_hash(self, x, y):
# check both that x and y are equal and that their hashes are equal
self.assertEqual(hash(F(7*_PyHASH_MODULUS, 1)), 0)
self.assertEqual(hash(F(-_PyHASH_MODULUS, 1)), 0)
+ # The numbers ABC doesn't enforce that the "true" division
+ # of integers produces a float. This tests that the
+ # Rational.__float__() method has required type conversions.
+ x = F(DummyIntegral(1), DummyIntegral(2), _normalize=False)
+ self.assertRaises(TypeError, lambda: x.numerator/x.denominator)
+ self.assertEqual(float(x), 0.5)
+
def test_hash_normalization(self):
# Test for a bug encountered while changing long_hash.
#
self.assertRaises(TypeError, pwd.getpwnam)
self.assertRaises(TypeError, pwd.getpwnam, 42)
self.assertRaises(TypeError, pwd.getpwall, 42)
+ # embedded null character
+ self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b')
# try to get some errors
bynames = {}
def testSockName(self):
# Testing getsockname()
- port = socket_helper.find_unused_port()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.addCleanup(sock.close)
- sock.bind(("0.0.0.0", port))
+
+ # Since find_unused_port() is inherently subject to race conditions, we
+ # call it a couple times if necessary.
+ for i in itertools.count():
+ port = socket_helper.find_unused_port()
+ try:
+ sock.bind(("0.0.0.0", port))
+ except OSError as e:
+ if e.errno != errno.EADDRINUSE or i == 5:
+ raise
+ else:
+ break
+
name = sock.getsockname()
# XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate
# it reasonable to get the host's addr in addition to 0.0.0.0.
self.assertIsInstance(sys.executable, str)
self.assertEqual(len(sys.float_info), 11)
self.assertEqual(sys.float_info.radix, 2)
- self.assertEqual(len(sys.int_info), 2)
+ self.assertEqual(len(sys.int_info), 4)
self.assertTrue(sys.int_info.bits_per_digit % 5 == 0)
self.assertTrue(sys.int_info.sizeof_digit >= 1)
+ self.assertGreaterEqual(sys.int_info.default_max_str_digits, 500)
+ self.assertGreaterEqual(sys.int_info.str_digits_check_threshold, 100)
+ self.assertGreater(sys.int_info.default_max_str_digits,
+ sys.int_info.str_digits_check_threshold)
self.assertEqual(type(sys.int_info.bits_per_digit), int)
self.assertEqual(type(sys.int_info.sizeof_digit), int)
+ self.assertIsInstance(sys.int_info.default_max_str_digits, int)
+ self.assertIsInstance(sys.int_info.str_digits_check_threshold, int)
self.assertIsInstance(sys.hexversion, int)
self.assertEqual(len(sys.hash_info), 9)
"dont_write_bytecode", "no_user_site", "no_site",
"ignore_environment", "verbose", "bytes_warning", "quiet",
"hash_randomization", "isolated", "dev_mode", "utf8_mode",
- "warn_default_encoding")
+ "warn_default_encoding", "int_max_str_digits")
for attr in attrs:
self.assertTrue(hasattr(sys.flags, attr), attr)
attr_type = bool if attr == "dev_mode" else int
self.assertEqual(tree.type_ignores, [])
def test_longargs(self):
- for tree in self.parse_all(longargs):
+ for tree in self.parse_all(longargs, minver=8):
for t in tree.body:
# The expected args are encoded in the function name
todo = set(t.name[1:])
check('<bigdecimal>9876543210.0123456789</bigdecimal>',
decimal.Decimal('9876543210.0123456789'))
+ def test_limit_int(self):
+ check = self.check_loads
+ maxdigits = 5000
+ with support.adjust_int_max_str_digits(maxdigits):
+ s = '1' * (maxdigits + 1)
+ with self.assertRaises(ValueError):
+ check(f'<int>{s}</int>', None)
+ with self.assertRaises(ValueError):
+ check(f'<biginteger>{s}</biginteger>', None)
+
def test_get_host_info(self):
# see bug #3613, this raised a TypeError
transp = xmlrpc.client.Transport()
def isSet(self):
"""Return true if and only if the internal flag is true.
- This method is deprecated, use notify_all() instead.
+ This method is deprecated, use is_set() instead.
"""
import warnings
class TestAsyncCase(unittest.TestCase):
maxDiff = None
- def tearDown(self):
+ def setUp(self):
# Ensure that IsolatedAsyncioTestCase instances are destroyed before
# starting a new event loop
- support.gc_collect()
+ self.addCleanup(support.gc_collect)
def test_full_cycle(self):
class Test(unittest.IsolatedAsyncioTestCase):
events = []
test = Test("test_func")
+ self.addCleanup(test._tearDownAsyncioLoop)
try:
test.debug()
except MyException:
events = []
test = Test("test_func")
+ self.addCleanup(test._tearDownAsyncioLoop)
try:
test.debug()
except MyException:
events = []
test = Test("test_func")
+ self.addCleanup(test._tearDownAsyncioLoop)
try:
test.debug()
except MyException:
events = []
test = Test("test_func")
+ self.addCleanup(test._tearDownAsyncioLoop)
try:
test.debug()
except MyException:
events = []
test = Test("test_func")
+ self.addCleanup(test._tearDownAsyncioLoop)
try:
test.debug()
except MyException:
self._name = qName
self.namespaceURI = namespaceURI
self._prefix = prefix
+ if localName is not None:
+ self._localName = localName
self.childNodes = NodeList()
# Add the single child node that represents the value of the attr
result.extend([
dict(
- name="OpenSSL 1.1.1n",
- url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz",
- checksum='2aad5635f9bb338bc2c6b7d19cbc9676',
+ name="OpenSSL 1.1.1q",
+ url="https://www.openssl.org/source/openssl-1.1.1q.tar.gz",
+ checksum='d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca',
buildrecipe=build_universal_openssl,
configure=None,
install=None,
print("Downloading %s"%(name,))
downloadURL(url, fname)
print("Archive for %s stored as %s"%(name, fname))
+ if len(checksum) == 32:
+ algo = 'md5'
+ elif len(checksum) == 64:
+ algo = 'sha256'
+ else:
+ raise ValueError(checksum)
if os.system(
- 'MD5=$(openssl md5 %s) ; test "${MD5##*= }" = "%s"'
- % (shellQuote(fname), checksum) ):
- fatal('MD5 checksum mismatch for file %s' % fname)
+ 'CHECKSUM=$(openssl %s %s) ; test "${CHECKSUM##*= }" = "%s"'
+ % (algo, shellQuote(fname), checksum) ):
+ fatal('%s checksum mismatch for file %s' % (algo, fname))
def build_universal_openssl(basedir, archList):
"""
Tyler Kieft
Mads Kiilerich
Jason Killen
+Derek D. Kim
Jan Kim
Taek Joo Kim
Sam Kimbrel
Matheus Vieira Portela
Davin Potts
Guillaume Pratte
+Pedro Pregueiro
Florian Preinstorfer
Alex Prengère
Amrit Prem
Python News
+++++++++++
+What's New in Python 3.10.7 final?
+==================================
+
+*Release date: 2022-09-05*
+
+Security
+--------
+
+- gh-issue-95778: Converting between :class:`int` and :class:`str` in bases
+ other than 2 (binary), 4, 8 (octal), 16 (hexadecimal), or 32 such as base
+ 10 (decimal) now raises a :exc:`ValueError` if the number of digits in
+ string form is above a limit to avoid potential denial of service attacks
+ due to the algorithmic complexity. This is a mitigation for
+ `CVE-2020-10735
+ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735>`_.
+
+ This new limit can be configured or disabled by environment variable,
+ command line flag, or :mod:`sys` APIs. See the :ref:`integer string
+ conversion length limitation <int_max_str_digits>` documentation. The
+ default limit is 4300 digits in string form.
+
+ Patch by Gregory P. Smith [Google] and Christian Heimes [Red Hat] with
+ feedback from Victor Stinner, Thomas Wouters, Steve Dower, Ned Deily, and
+ Mark Dickinson.
+
+Core and Builtins
+-----------------
+
+- gh-issue-96187: Fixed a bug that caused ``_PyCode_GetExtra`` to return
+ garbage for negative indexes. Patch by Pablo Galindo
+
+- gh-issue-95876: Fix format string in
+ ``_PyPegen_raise_error_known_location`` that can lead to memory corruption
+ on some 64bit systems. The function was building a tuple with ``i`` (int)
+ instead of ``n`` (Py_ssize_t) for Py_ssize_t arguments.
+
+- gh-issue-95605: Fix misleading contents of error message when converting
+ an all-whitespace string to :class:`float`.
+
+- gh-issue-93592: ``coroutine.throw()`` now properly initializes the
+ ``frame.f_back`` when resuming a stack of coroutines. This allows e.g.
+ ``traceback.print_stack()`` to work correctly when an exception (such as
+ ``CancelledError``) is thrown into a coroutine.
+
+- gh-issue-94996: :func:`ast.parse` will no longer parse function
+ definitions with positional-only params when passed ``feature_version``
+ less than ``(3, 8)``. Patch by Shantanu Jain.
+
+Library
+-------
+
+- gh-issue-68163: Correct conversion of :class:`numbers.Rational`'s to
+ :class:`float`.
+
+- gh-issue-96159: Fix a performance regression in logging
+ TimedRotatingFileHandler. Only check for special files when the rollover
+ time has passed.
+
+- gh-issue-96175: Fix unused ``localName`` parameter in the ``Attr`` class
+ in :mod:`xml.dom.minidom`.
+
+- gh-issue-95609: Update bundled pip to 22.2.2.
+
+- gh-issue-95231: Fail gracefully if :data:`~errno.EPERM` or
+ :data:`~errno.ENOSYS` is raised when loading :mod:`crypt` methods. This
+ may happen when trying to load ``MD5`` on a Linux kernel with :abbr:`FIPS
+ (Federal Information Processing Standard)` enabled.
+
+Documentation
+-------------
+
+- gh-issue-96098: Improve discoverability of the higher level
+ concurrent.futures module by providing clearer links from the lower level
+ threading and multiprocessing modules.
+
+- gh-issue-95789: Update the default RFC base URL from deprecated
+ tools.ietf.org to datatracker.ietf.org
+
+- gh-issue-91207: Fix stylesheet not working in Windows CHM htmlhelp docs.
+ Contributed by C.A.M. Gerlach.
+
+- bpo-47115: The documentation now lists which members of C structs are part
+ of the :ref:`Limited API/Stable ABI <stable>`.
+
+Tests
+-----
+
+- gh-issue-95243: Mitigate the inherent race condition from using
+ find_unused_port() in testSockName() by trying to find an unused port a
+ few times before failing. Patch by Ross Burton.
+
+Build
+-----
+
+- gh-issue-94682: Build and test with OpenSSL 1.1.1q
+
+IDLE
+----
+
+- gh-issue-65802: Document handling of extensions in Save As dialogs.
+
+- gh-issue-95191: Include prompts when saving Shell (interactive input and
+ output).
+
+
What's New in Python 3.10.6 final?
==================================
- gh-issue-88831: Augmented documentation of asyncio.create_task().
Clarified the need to keep strong references to tasks and added a code
- snippet detailing how to to this.
+ snippet detailing how to do this.
- bpo-47161: Document that :class:`pathlib.PurePath` does not collapse
initial double slashes because they denote UNC paths.
- gh-issue-91330: Added more tests for :mod:`dataclasses` to cover behavior
with data descriptor-based fields.
- # Write your Misc/NEWS entry below. It should be a simple ReST paragraph.
- # Don't start with "- Issue #<n>: " or "- gh-issue-<n>: " or that sort of
- stuff.
- ###########################################################################
-
- gh-issue-94208: ``test_ssl`` is now checking for supported TLS version and
protocols in more tests.
# and PC/pythonXYstub.def
+# The current format is a simple line-based one with significant indentation.
+# Anything after a hash is a comment.
+
+# There are these kinds of top-level "items":
+# - struct: A C struct. Currently this file does not distinguish between:
+# - opaque structs, which the Limited API only handles via pointers
+# (so these can change at any time)
+# - structs where only certain members are part of the stable ABI (e.g.
+# PyObject)
+# - structs which must not be changed at all (e.g. PyType_Slot, which is
+# fully defined and used in arrays)
+# - function: A function that must be kept available (and exported, i.e. not
+# converted to a macro).
+# - const: A simple value, defined with `#define`.
+# - macro: A preprocessor macro more complex than a simple `const` value.
+# - data: An exported object, which must continue to be available but its exact
+# value may change.
+# - typedef: A C typedef which is used in other definitions in the limited API.
+# Its size/layout/signature must not change.
+
+# Each top-level item can have details defined below it:
+# - added: The version in which the item was added to the stable ABI.
+# - ifdef: A feature macro: the item is only available if this macro is defined
+# - abi_only: If present, the item is not part of the Limited API, but it *is*
+# part of the stable ABI. The item will not show up in user-facing docs.
+# Typically used for:
+# - private functions called by public macros, e.g. _Py_BuildValue_SizeT
+# - items that were part of the limited API in the past, and must remain part
+# of the stable ABI.
+# - a combination of the above (functions that were called by macros that
+# were public in the past)
+
+# For structs, one of the following must be set:
+# - opaque: The struct name is available in the Limited API, but its members
+# are not. Users must manipulate it via pointers.
+# - members: Space-separated list of members which are part of the
+# Limited API and Stable ABI.
+# Members that aren't listed are not accessible to applications.
+# - full-abi: The entire struct -- all its members and its size -- is part of
+# the Stable ABI, and must not change.
+
+# Removing items from this file is generally not allowed, and additions should
+# be considered with that in mind. See the devguide for exact rules:
+# https://devguide.python.org/c-api/#limited-api
+
+# User-facing docs are at:
+# https://docs.python.org/3/c-api/stable.html#stable
+
+
# Mentioned in PEP 384:
struct PyObject
added 3.2
+ members ob_refcnt ob_type
struct PyVarObject
added 3.2
+ members ob_base ob_size
struct PyMethodDef
added 3.2
+ full-abi
struct PyMemberDef
added 3.2
+ full-abi
struct PyGetSetDef
added 3.2
+ full-abi
struct PyModuleDef_Base
added 3.2
+ full-abi
struct PyModuleDef
added 3.2
+ full-abi
struct PyStructSequence_Field
added 3.2
+ full-abi
struct PyStructSequence_Desc
added 3.2
+ full-abi
struct PyType_Slot
added 3.2
+ full-abi
struct PyType_Spec
added 3.2
+ full-abi
struct PyThreadState
added 3.2
+ opaque
struct PyInterpreterState
added 3.2
+ opaque
struct PyFrameObject
added 3.2
+ opaque
struct symtable
added 3.2
+ opaque
struct PyWeakReference
added 3.2
+ opaque
struct PyLongObject
added 3.2
+ opaque
struct PyTypeObject
added 3.2
+ opaque
function PyType_FromSpec
added 3.2
added 3.2
typedef allocfunc
added 3.2
-struct PyCFunction
+typedef PyCFunction
added 3.2
-struct PyCFunctionWithKeywords
+typedef PyCFunctionWithKeywords
added 3.2
-struct PyCapsule_Destructor
+typedef PyCapsule_Destructor
added 3.2
typedef getter
added 3.2
/* C implementation for the date/time type documented at
- * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
+ * https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage
*/
/* bpo-35081: Defining this prevents including the C API capsule;
month = PyDateTime_GET_MONTH(obj);
day = PyDateTime_GET_DAY(obj);
- return Py_BuildValue("(lll)", year, month, day);
+ return Py_BuildValue("(iii)", year, month, day);
}
static PyObject *
microsecond = PyDateTime_DATE_GET_MICROSECOND(obj);
PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj);
- return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo);
+ return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo);
}
static PyObject *
microsecond = PyDateTime_TIME_GET_MICROSECOND(obj);
PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj);
- return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo);
+ return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo);
}
static PyObject *
seconds = PyDateTime_DELTA_GET_SECONDS(obj);
microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj);
- return Py_BuildValue("(lll)", days, seconds, microseconds);
+ return Py_BuildValue("(iii)", days, seconds, microseconds);
}
/* test_thread_state spawns a thread of its own, and that thread releases
\n\
Run all registered exit functions.\n\
\n\
-If a callaback raises an exception, it is logged with sys.unraisablehook.");
+If a callback raises an exception, it is logged with sys.unraisablehook.");
static PyObject *
atexit_run_exitfuncs(PyObject *module, PyObject *unused)
PyCodeObject *o = (PyCodeObject*) code;
_PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
- if (co_extra == NULL || co_extra->ce_size <= index) {
+ if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) {
*extra = NULL;
return 0;
}
double x;
const char *end;
const char *last = s + len;
- /* strip space */
+ /* strip leading whitespace */
while (s < last && Py_ISSPACE(*s)) {
s++;
}
+ if (s == last) {
+ PyErr_Format(PyExc_ValueError,
+ "could not convert string to float: "
+ "%R", obj);
+ return NULL;
+ }
+ /* strip trailing whitespace */
while (s < last - 1 && Py_ISSPACE(last[-1])) {
last--;
}
/* `yf` is a generator or a coroutine. */
PyThreadState *tstate = _PyThreadState_GET();
PyFrameObject *f = tstate->frame;
+ PyFrameObject *gf = gen->gi_frame;
/* Since we are fast-tracking things by skipping the eval loop,
we need to update the current frame so the stack trace
will be reported correctly to the user. */
/* XXX We should probably be updating the current frame
somewhere in ceval.c. */
- tstate->frame = gen->gi_frame;
+ assert(gf->f_back == NULL);
+ Py_XINCREF(f);
+ gf->f_back = f;
+ tstate->frame = gf;
/* Close the generator that we are currently iterating with
'yield from' or awaiting on with 'await'. */
- PyFrameState state = gen->gi_frame->f_state;
- gen->gi_frame->f_state = FRAME_EXECUTING;
+ PyFrameState state = gf->f_state;
+ gf->f_state = FRAME_EXECUTING;
ret = _gen_throw((PyGenObject *)yf, close_on_genexit,
typ, val, tb);
- gen->gi_frame->f_state = state;
+ gf->f_state = state;
+ Py_CLEAR(gf->f_back);
tstate->frame = f;
} else {
/* `yf` is an iterator or a coroutine-like object. */
#include "Python.h"
#include "pycore_bitutils.h" // _Py_popcount32()
+#include "pycore_initconfig.h" // _Py_global_config_int_max_str_digits
#include "pycore_interp.h" // _PY_NSMALLPOSINTS
#include "pycore_long.h" // __PyLong_GetSmallInt_internal()
#include "pycore_object.h" // _PyObject_InitVar()
#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)
#define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS)
+#define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d) for integer string conversion: value has %zd digits"
+#define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d) for integer string conversion"
+
static PyObject *
get_small_int(sdigit ival)
{
size_a = Py_ABS(Py_SIZE(a));
negative = Py_SIZE(a) < 0;
+ /* quick and dirty pre-check for overflowing the decimal digit limit,
+ based on the inequality 10/3 >= log2(10)
+
+ explanation in https://github.com/python/cpython/pull/96537
+ */
+ if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD
+ / (3 * PyLong_SHIFT) + 2) {
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ int max_str_digits = interp->int_max_str_digits;
+ if ((max_str_digits > 0) &&
+ (max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10)) {
+ PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR,
+ max_str_digits);
+ return -1;
+ }
+ }
+
/* quick and dirty upper bound for the number of digits
required to express a in base _PyLong_DECIMAL_BASE:
tenpow *= 10;
strlen++;
}
+ if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ int max_str_digits = interp->int_max_str_digits;
+ Py_ssize_t strlen_nosign = strlen - negative;
+ if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) {
+ Py_DECREF(scratch);
+ PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR,
+ max_str_digits);
+ return -1;
+ }
+ }
if (writer) {
if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) {
Py_DECREF(scratch);
start = str;
if ((base & (base - 1)) == 0) {
+ /* binary bases are not limited by int_max_str_digits */
int res = long_from_binary_base(&str, base, &z);
if (res < 0) {
/* Syntax error. */
goto onError;
}
+ /* Limit the size to avoid excessive computation attacks. */
+ if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ int max_str_digits = interp->int_max_str_digits;
+ if ((max_str_digits > 0) && (digits > max_str_digits)) {
+ PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_INT,
+ max_str_digits, digits);
+ return NULL;
+ }
+ }
+
/* Create an int object that can contain the largest possible
* integer with this base and length. Note that there's no
* need to initialize z->ob_digit -- no slot is read up before
}
return PyLong_FromLong(0L);
}
+ /* default base and limit, forward to standard implementation */
if (obase == NULL)
return PyNumber_Long(x);
static PyStructSequence_Field int_info_fields[] = {
{"bits_per_digit", "size of a digit in bits"},
{"sizeof_digit", "size in bytes of the C type used to represent a digit"},
+ {"default_max_str_digits", "maximum string conversion digits limitation"},
+ {"str_digits_check_threshold", "minimum positive value for int_max_str_digits"},
{NULL, NULL}
};
"sys.int_info", /* name */
int_info__doc__, /* doc */
int_info_fields, /* fields */
- 2 /* number of fields */
+ 4 /* number of fields */
};
PyObject *
PyLong_FromLong(PyLong_SHIFT));
PyStructSequence_SET_ITEM(int_info, field++,
PyLong_FromLong(sizeof(digit)));
+ /*
+ * The following two fields were added after investigating uses of
+ * sys.int_info in the wild: Exceedingly rarely used. The ONLY use found was
+ * numba using sys.int_info.bits_per_digit as attribute access rather than
+ * sequence unpacking. Cython and sympy also refer to sys.int_info but only
+ * as info for debugging. No concern about adding these in a backport.
+ */
+ PyStructSequence_SET_ITEM(int_info, field++,
+ PyLong_FromLong(_PY_LONG_DEFAULT_MAX_STR_DIGITS));
+ PyStructSequence_SET_ITEM(int_info, field++,
+ PyLong_FromLong(_PY_LONG_MAX_STR_DIGITS_THRESHOLD));
if (PyErr_Occurred()) {
Py_CLEAR(int_info);
return NULL;
interp->small_ints[i] = v;
}
+ interp->int_max_str_digits = _Py_global_config_int_max_str_digits;
+ if (interp->int_max_str_digits == -1) {
+ interp->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS;
+ }
return 0;
}
" reserved=0)\n"
"--\n"
"\n"
-"Deletes the specified key (64-bit OS only).\n"
+"Deletes the specified key (intended for 64-bit OS).\n"
"\n"
" key\n"
" An already open key, or any one of the predefined HKEY_* constants.\n"
" reserved\n"
" A reserved integer, and must be zero. Default is zero.\n"
"\n"
+"While this function is intended to be used for 64-bit OS, it is also\n"
+" available on 32-bit systems.\n"
+"\n"
"This method can not delete keys with subkeys.\n"
"\n"
"If the function succeeds, the entire key, including all of its values,\n"
exit:
return return_value;
}
-/*[clinic end generated code: output=497a2e804821d5c9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8ce6fb3b6cd46242 input=a9049054013a1b77]*/
(Py_ssize_t)0) < 0) {
return NULL;
}
- rc = RegDeleteKeyW(key, sub_key );
+ Py_BEGIN_ALLOW_THREADS
+ rc = RegDeleteKeyW(key, sub_key);
+ Py_END_ALLOW_THREADS
if (rc != ERROR_SUCCESS)
return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey");
Py_RETURN_NONE;
reserved: int = 0
A reserved integer, and must be zero. Default is zero.
-Deletes the specified key (64-bit OS only).
+Deletes the specified key (intended for 64-bit OS).
+
+While this function is intended to be used for 64-bit OS, it is also
+ available on 32-bit systems.
This method can not delete keys with subkeys.
winreg_DeleteKeyEx_impl(PyObject *module, HKEY key,
const Py_UNICODE *sub_key, REGSAM access,
int reserved)
-/*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/
+/*[clinic end generated code: output=52a1c8b374ebc003 input=a3186db079b3bf85]*/
{
- HMODULE hMod;
- typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int);
- RDKEFunc pfn = NULL;
long rc;
-
if (PySys_Audit("winreg.DeleteKey", "nun",
(Py_ssize_t)key, sub_key,
(Py_ssize_t)access) < 0) {
return NULL;
}
- /* Only available on 64bit platforms, so we must load it
- dynamically. */
Py_BEGIN_ALLOW_THREADS
- hMod = GetModuleHandleW(L"advapi32.dll");
- if (hMod)
- pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW");
+ rc = RegDeleteKeyExW(key, sub_key, access, reserved);
Py_END_ALLOW_THREADS
- if (!pfn) {
- PyErr_SetString(PyExc_NotImplementedError,
- "not implemented on this platform");
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- rc = (*pfn)(key, sub_key, access, reserved);
- Py_END_ALLOW_THREADS
-
if (rc != ERROR_SUCCESS)
return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx");
Py_RETURN_NONE;
set libraries=\r
set libraries=%libraries% bzip2-1.0.8\r
if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0\r
-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n\r
+if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1q\r
set libraries=%libraries% sqlite-3.37.2.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0\r
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0\r
\r
set binaries=\r
if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.3.0\r
-if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n\r
+if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1q\r
if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0\r
if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06\r
\r
<libffiDir>$(ExternalsDir)libffi-3.3.0\</libffiDir>\r
<libffiOutDir>$(ExternalsDir)libffi-3.3.0\$(ArchName)\</libffiOutDir>\r
<libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir>\r
- <opensslDir>$(ExternalsDir)openssl-1.1.1n\</opensslDir>\r
- <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\</opensslOutDir>\r
+ <opensslDir>$(ExternalsDir)openssl-1.1.1q\</opensslDir>\r
+ <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1q\$(ArchName)\</opensslOutDir>\r
<opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir>\r
<nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir>\r
<zlibDir>$(ExternalsDir)\zlib-1.2.12\</zlibDir>\r
Homepage:\r
https://tukaani.org/xz/\r
_ssl\r
- Python wrapper for version 1.1.1k of the OpenSSL secure sockets\r
+ Python wrapper for version 1.1.1q of the OpenSSL secure sockets\r
library, which is downloaded from our binaries repository at\r
https://github.com/python/cpython-bin-deps.\r
\r
)
{
D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?"));
- _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d );
+ _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
p->level--;
)
{
D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?"));
- _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c );
+ _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
p->level--;
)
{
D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?"));
- _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d );
+ _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
p->level--;
)
{
D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?"));
- _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c );
+ _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
p->level--;
#include <Python.h>
#include "pycore_ast.h" // _PyAST_Validate(),
+#include "pycore_pystate.h" // _PyThreadState_GET()
#include <errcode.h>
#include "tokenizer.h"
byte_offset_to_character_offset(error_line, end_col_offset) :
end_col_number;
}
- tmp = Py_BuildValue("(OiiNii)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number);
+ tmp = Py_BuildValue("(OnnNnn)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number);
if (!tmp) {
goto error;
}
if (c == NULL) {
p->error_indicator = 1;
+ PyThreadState *tstate = _PyThreadState_GET();
+ // The only way a ValueError should happen in _this_ code is via
+ // PyLong_FromString hitting a length limit.
+ if (tstate->curexc_type == PyExc_ValueError &&
+ tstate->curexc_value != NULL) {
+ PyObject *type, *value, *tb;
+ // This acts as PyErr_Clear() as we're replacing curexc.
+ PyErr_Fetch(&type, &value, &tb);
+ Py_XDECREF(tb);
+ Py_DECREF(type);
+ /* Intentionally omitting columns to avoid a wall of 1000s of '^'s
+ * on the error message. Nobody is going to overlook their huge
+ * numeric literal once given the line. */
+ RAISE_ERROR_KNOWN_LOCATION(
+ p, PyExc_SyntaxError,
+ t->lineno, -1 /* col_offset */,
+ t->end_lineno, -1 /* end_col_offset */,
+ "%S - Consider hexadecimal for huge integer literals "
+ "to avoid decimal conversion limits.",
+ value);
+ Py_DECREF(value);
+ }
return NULL;
}
#endif /* defined(USE_MALLOPT) */
+PyDoc_STRVAR(sys_get_int_max_str_digits__doc__,
+"get_int_max_str_digits($module, /)\n"
+"--\n"
+"\n"
+"Set the maximum string digits limit for non-binary int<->str conversions.");
+
+#define SYS_GET_INT_MAX_STR_DIGITS_METHODDEF \
+ {"get_int_max_str_digits", (PyCFunction)sys_get_int_max_str_digits, METH_NOARGS, sys_get_int_max_str_digits__doc__},
+
+static PyObject *
+sys_get_int_max_str_digits_impl(PyObject *module);
+
+static PyObject *
+sys_get_int_max_str_digits(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return sys_get_int_max_str_digits_impl(module);
+}
+
+PyDoc_STRVAR(sys_set_int_max_str_digits__doc__,
+"set_int_max_str_digits($module, /, maxdigits)\n"
+"--\n"
+"\n"
+"Set the maximum string digits limit for non-binary int<->str conversions.");
+
+#define SYS_SET_INT_MAX_STR_DIGITS_METHODDEF \
+ {"set_int_max_str_digits", (PyCFunction)(void(*)(void))sys_set_int_max_str_digits, METH_FASTCALL|METH_KEYWORDS, sys_set_int_max_str_digits__doc__},
+
+static PyObject *
+sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits);
+
+static PyObject *
+sys_set_int_max_str_digits(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"maxdigits", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "set_int_max_str_digits", 0};
+ PyObject *argsbuf[1];
+ int maxdigits;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ maxdigits = _PyLong_AsInt(args[0]);
+ if (maxdigits == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = sys_set_int_max_str_digits_impl(module, maxdigits);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(sys_getrefcount__doc__,
"getrefcount($module, object, /)\n"
"--\n"
#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
#define SYS_GETANDROIDAPILEVEL_METHODDEF
#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
-/*[clinic end generated code: output=68c62b9ca317a0c8 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=6230a1e3a4415744 input=a9049054013a1b77]*/
#include "pycore_getopt.h" // _PyOS_GetOpt()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_interp.h" // _PyInterpreterState.runtime
+#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
#include "pycore_pathconfig.h" // _Py_path_config
#include "pycore_pyerrors.h" // _PyErr_Fetch()
#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
-X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\
given directory instead of to the code tree\n\
-X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\
+ -X int_max_str_digits=number: limit the size of int<->str conversions.\n\
+ This helps avoid denial of service attacks when parsing untrusted data.\n\
+ The default is sys.int_info.default_max_str_digits. 0 disables.\n\
+\n\
--check-hash-based-pycs always|default|never:\n\
control how Python invalidates hash-based .pyc files\n\
";
" to seed the hashes of str and bytes objects. It can also be set to an\n"
" integer in the range [0,4294967295] to get hash values with a\n"
" predictable seed.\n"
+"PYTHONINTMAXSTRDIGITS: limits the maximum digit characters in an int value\n"
+" when converting from a string and when converting an int back to a str.\n"
+" A value of 0 disables the limit. Conversions to or from bases 2, 4, 8,\n"
+" 16, and 32 are never limited.\n"
"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
" hooks.\n"
#endif
}
+/* Excluded from public struct PyConfig for backporting reasons. */
+/* default to unconfigured, _PyLong_InitTypes() does the rest */
+int _Py_global_config_int_max_str_digits = -1;
+
static void
config_init_defaults(PyConfig *config)
return _PyStatus_OK();
}
+static PyStatus
+config_init_int_max_str_digits(PyConfig *config)
+{
+ int maxdigits;
+ int valid = 0;
+
+ const char *env = config_get_env(config, "PYTHONINTMAXSTRDIGITS");
+ if (env) {
+ if (!_Py_str_to_int(env, &maxdigits)) {
+ valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD));
+ }
+ if (!valid) {
+#define STRINGIFY(VAL) _STRINGIFY(VAL)
+#define _STRINGIFY(VAL) #VAL
+ return _PyStatus_ERR(
+ "PYTHONINTMAXSTRDIGITS: invalid limit; must be >= "
+ STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD)
+ " or 0 for unlimited.");
+ }
+ _Py_global_config_int_max_str_digits = maxdigits;
+ }
+
+ const wchar_t *xoption = config_get_xoption(config, L"int_max_str_digits");
+ if (xoption) {
+ const wchar_t *sep = wcschr(xoption, L'=');
+ if (sep) {
+ if (!config_wstr_to_int(sep + 1, &maxdigits)) {
+ valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD));
+ }
+ }
+ if (!valid) {
+ return _PyStatus_ERR(
+ "-X int_max_str_digits: invalid limit; must be >= "
+ STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD)
+ " or 0 for unlimited.");
+#undef _STRINGIFY
+#undef STRINGIFY
+ }
+ _Py_global_config_int_max_str_digits = maxdigits;
+ }
+ return _PyStatus_OK();
+}
static PyStatus
config_init_pycache_prefix(PyConfig *config)
return status;
}
}
+ if (_Py_global_config_int_max_str_digits < 0) {
+ status = config_init_int_max_str_digits(config);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
if (config->pycache_prefix == NULL) {
status = config_init_pycache_prefix(config);
#include "Python.h"
#include "pycore_ceval.h" // _Py_RecursionLimitLowerWaterMark()
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
+#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
#include "pycore_object.h" // _PyObject_IS_GC()
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
#include "pycore_pyerrors.h" // _PyErr_Fetch()
}
#endif /* USE_MALLOPT */
+
+/*[clinic input]
+sys.get_int_max_str_digits
+
+Set the maximum string digits limit for non-binary int<->str conversions.
+[clinic start generated code]*/
+
+static PyObject *
+sys_get_int_max_str_digits_impl(PyObject *module)
+/*[clinic end generated code: output=0042f5e8ae0e8631 input=8dab13e2023e60d5]*/
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ return PyLong_FromSsize_t(interp->int_max_str_digits);
+}
+
+/*[clinic input]
+sys.set_int_max_str_digits
+
+ maxdigits: int
+
+Set the maximum string digits limit for non-binary int<->str conversions.
+[clinic start generated code]*/
+
+static PyObject *
+sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
+/*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) {
+ tstate->interp->int_max_str_digits = maxdigits;
+ Py_RETURN_NONE;
+ } else {
+ PyErr_Format(
+ PyExc_ValueError, "maxdigits must be 0 or larger than %d",
+ _PY_LONG_MAX_STR_DIGITS_THRESHOLD);
+ return NULL;
+ }
+}
+
size_t
_PySys_GetSizeOf(PyObject *o)
{
SYS_GETANDROIDAPILEVEL_METHODDEF
SYS_UNRAISABLEHOOK_METHODDEF
SYS__DEACTIVATE_OPCACHE_METHODDEF
+ SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
+ SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
{NULL, NULL} /* sentinel */
};
{"dev_mode", "-X dev"},
{"utf8_mode", "-X utf8"},
{"warn_default_encoding", "-X warn_default_encoding"},
+ {"int_max_str_digits", "-X int_max_str_digits"},
{0}
};
"sys.flags", /* name */
flags__doc__, /* doc */
flags_fields, /* fields */
- 16
+ 17
};
static int
SetFlagObj(PyBool_FromLong(config->dev_mode));
SetFlag(preconfig->utf8_mode);
SetFlag(config->warn_default_encoding);
+ SetFlag(_Py_global_config_int_max_str_digits);
#undef SetFlagObj
#undef SetFlag
return 0;
-This is Python version 3.10.6
+This is Python version 3.10.7
=============================
.. image:: https://travis-ci.com/python/cpython.svg?branch=master
* ...
-(see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)
+(see: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)
We have taken advantage of the elements of the C grammar that are used
only in a few limited contexts, mostly as delimiters. They allow us to
set REBUILD=\r
\r
:CheckOpts\r
-if "%~1" EQU "-h" goto Help\r
-if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts\r
-if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts\r
-if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts\r
-if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts\r
-if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts\r
-if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts\r
-if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts\r
+if "%~1" EQU "-h" goto Help\r
+if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts\r
+if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts\r
+if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts\r
+if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts\r
+if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts\r
+if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts\r
+if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts\r
+if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts\r
\r
if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1)\r
\r
\r
\r
:CheckOpts\r
-if "%1" EQU "-h" goto Help\r
-if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts\r
-if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts\r
-if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts\r
-if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts\r
-if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts\r
-if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts\r
-if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts\r
-if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts\r
-if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts\r
-if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts\r
-if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts\r
-if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts\r
-if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts\r
+if "%1" EQU "-h" goto Help\r
+if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts\r
+if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts\r
+if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts\r
+if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts\r
+if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts\r
+if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts\r
+if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts\r
+if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts\r
+if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts\r
\r
if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1\r
\r
contents: list = dataclasses.field(default_factory=list)
abi_only: bool = False
ifdef: str = None
+ struct_abi_kind: str = None
+ members: list = None
KINDS = frozenset({
'struct', 'function', 'macro', 'data', 'const', 'typedef',
if parent.kind not in {'function', 'data'}:
raise_error(f'{kind} cannot go in {parent.kind}')
parent.abi_only = True
+ elif kind in {'members', 'full-abi', 'opaque'}:
+ if parent.kind not in {'struct'}:
+ raise_error(f'{kind} cannot go in {parent.kind}')
+ if prev := getattr(parent, 'struct_abi_kind', None):
+ raise_error(
+ f'{parent.name} already has {prev}, cannot add {kind}')
+ parent.struct_abi_kind = kind
+ if kind == 'members':
+ parent.members = content.split()
else:
raise_error(f"unknown kind {kind!r}")
levels.append((entry, level))
def gen_doc_annotations(manifest, args, outfile):
"""Generate/check the stable ABI list for documentation annotations"""
writer = csv.DictWriter(
- outfile, ['role', 'name', 'added', 'ifdef_note'], lineterminator='\n')
+ outfile,
+ ['role', 'name', 'added', 'ifdef_note', 'struct_abi_kind'],
+ lineterminator='\n')
writer.writeheader()
for item in manifest.select(REST_ROLES.keys(), include_abi_only=False):
if item.ifdef:
'role': REST_ROLES[item.kind],
'name': item.name,
'added': item.added,
- 'ifdef_note': ifdef_note})
+ 'ifdef_note': ifdef_note,
+ 'struct_abi_kind': item.struct_abi_kind})
+ for member_name in item.members or ():
+ writer.writerow({
+ 'role': 'member',
+ 'name': f'{item.name}.{member_name}',
+ 'added': item.added})
def generate_or_check(manifest, args, path, func):
"""Generate/check a file with a single generator
]
OPENSSL_RECENT_VERSIONS = [
- "1.1.1n",
- "3.0.2"
+ "1.1.1q",
+ "3.0.5"
]
LIBRESSL_OLD_VERSIONS = [
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for python 3.10.
#
-# Report bugs to <https://bugs.python.org/>.
+# Report bugs to <https://github.com/python/cpython/issues/>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
$as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: https://bugs.python.org/ about your system, including
-$0: any error possibly output before this message. Then
-$0: install a modern shell, or manually run the script
-$0: under such a shell if you do have one."
+$0: https://github.com/python/cpython/issues/ about your
+$0: system, including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
fi
exit 1
fi
PACKAGE_TARNAME='python'
PACKAGE_VERSION='3.10'
PACKAGE_STRING='python 3.10'
-PACKAGE_BUGREPORT='https://bugs.python.org/'
+PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/'
PACKAGE_URL=''
ac_unique_file="Include/object.h"
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
-Report bugs to <https://bugs.python.org/>.
+Report bugs to <https://github.com/python/cpython/issues/>.
_ACEOF
ac_status=$?
fi
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## --------------------------------------- ##
-## Report this to https://bugs.python.org/ ##
-## --------------------------------------- ##"
+( $as_echo "## -------------------------------------------------------- ##
+## Report this to https://github.com/python/cpython/issues/ ##
+## -------------------------------------------------------- ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
# rounding issues. The result of this test has little meaning on non
# IEEE 754 platforms. On IEEE 754, test should return 1 if rounding
# mode is round-to-nearest and double rounding issues are present, and
-# 0 otherwise. See http://bugs.python.org/issue2937 for more info.
+# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5
$as_echo_n "checking for x87-style double rounding... " >&6; }
# $BASECFLAGS may affect the result
Configuration headers:
$config_headers
-Report bugs to <https://bugs.python.org/>."
+Report bugs to <https://github.com/python/cpython/issues/>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
dnl * Please run autoreconf -if to test your changes! *
dnl ***************************************************
dnl
-dnl Python's configure script requires autoconf 2.69 and autoconf-archive.
+dnl Python's configure.ac file requires autoconf 2.69 and autoconf-archive.
dnl
# Set VERSION so we only need to edit in one place (i.e., here)
AC_PREREQ([2.69])
-AC_INIT([python],[PYTHON_VERSION],[https://bugs.python.org/])
+AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/])
m4_ifdef(
[AX_C_FLOAT_WORDS_BIGENDIAN],
# rounding issues. The result of this test has little meaning on non
# IEEE 754 platforms. On IEEE 754, test should return 1 if rounding
# mode is round-to-nearest and double rounding issues are present, and
-# 0 otherwise. See http://bugs.python.org/issue2937 for more info.
+# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info.
AC_MSG_CHECKING(for x87-style double rounding)
# $BASECFLAGS may affect the result
ac_save_cc="$CC"