Imported Upstream version 3.10.7 upstream/3.10.7
authorJinWang An <jinwang.an@samsung.com>
Wed, 18 Jan 2023 06:01:45 +0000 (15:01 +0900)
committerJinWang An <jinwang.an@samsung.com>
Wed, 18 Jan 2023 06:01:45 +0000 (15:01 +0900)
177 files changed:
Doc/about.rst
Doc/bugs.rst
Doc/c-api/typeobj.rst
Doc/conf.py
Doc/data/python3.10.abi
Doc/data/stable_abi.dat
Doc/docutils.conf [new file with mode: 0644]
Doc/extending/index.rst
Doc/faq/design.rst
Doc/faq/extending.rst
Doc/faq/general.rst
Doc/faq/programming.rst
Doc/glossary.rst
Doc/howto/cporting.rst
Doc/howto/curses.rst
Doc/howto/descriptor.rst
Doc/howto/functional.rst
Doc/howto/logging-cookbook.rst
Doc/howto/pyporting.rst
Doc/howto/unicode.rst
Doc/howto/urllib2.rst
Doc/includes/sqlite3/adapter_point_1.py [deleted file]
Doc/includes/sqlite3/adapter_point_2.py [deleted file]
Doc/includes/sqlite3/collation_reverse.py [deleted file]
Doc/includes/sqlite3/complete_statement.py [deleted file]
Doc/includes/sqlite3/converter_point.py [deleted file]
Doc/includes/sqlite3/ctx_manager.py [deleted file]
Doc/includes/sqlite3/execute_1.py [deleted file]
Doc/includes/sqlite3/load_extension.py [deleted file]
Doc/includes/sqlite3/md5func.py [deleted file]
Doc/includes/sqlite3/mysumaggr.py [deleted file]
Doc/includes/sqlite3/row_factory.py [deleted file]
Doc/includes/sqlite3/rowclass.py [deleted file]
Doc/includes/sqlite3/shortcut_methods.py [deleted file]
Doc/includes/sqlite3/text_factory.py [deleted file]
Doc/install/index.rst
Doc/library/asyncio-eventloop.rst
Doc/library/bdb.rst
Doc/library/bisect.rst
Doc/library/collections.rst
Doc/library/difflib.rst
Doc/library/functions.rst
Doc/library/functools.rst
Doc/library/gettext.rst
Doc/library/grp.rst
Doc/library/http.client.rst
Doc/library/http.cookiejar.rst
Doc/library/idle.rst
Doc/library/json.rst
Doc/library/logging.config.rst
Doc/library/logging.handlers.rst
Doc/library/logging.rst
Doc/library/multiprocessing.rst
Doc/library/numbers.rst
Doc/library/os.path.rst
Doc/library/os.rst
Doc/library/random.rst
Doc/library/secrets.rst
Doc/library/shutil.rst
Doc/library/socket.rst
Doc/library/sqlite3.rst
Doc/library/statistics.rst
Doc/library/stdtypes.rst
Doc/library/string.rst
Doc/library/sys.rst
Doc/library/syslog.rst
Doc/library/test.rst
Doc/library/threading.rst
Doc/library/tkinter.rst
Doc/library/typing.rst
Doc/library/winreg.rst
Doc/library/xmlrpc.client.rst
Doc/license.rst
Doc/reference/compound_stmts.rst
Doc/reference/introduction.rst
Doc/reference/lexical_analysis.rst
Doc/tools/extensions/c_annotations.py
Doc/tools/susp-ignored.csv
Doc/using/cmdline.rst
Doc/using/mac.rst
Doc/using/windows.rst
Doc/whatsnew/2.3.rst
Doc/whatsnew/2.5.rst
Doc/whatsnew/2.6.rst
Doc/whatsnew/2.7.rst
Doc/whatsnew/3.1.rst
Doc/whatsnew/3.10.rst
Doc/whatsnew/3.2.rst
Doc/whatsnew/3.3.rst
Doc/whatsnew/3.5.rst
Doc/whatsnew/3.7.rst
Grammar/python.gram
Include/internal/pycore_atomic.h
Include/internal/pycore_initconfig.h
Include/internal/pycore_interp.h
Include/internal/pycore_long.h
Include/patchlevel.h
Lib/bdb.py
Lib/crypt.py
Lib/ensurepip/__init__.py
Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl [moved from Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl with 94% similarity]
Lib/idlelib/CREDITS.txt
Lib/idlelib/NEWS.txt
Lib/idlelib/README.txt
Lib/idlelib/browser.py
Lib/idlelib/config.py
Lib/idlelib/configdialog.py
Lib/idlelib/editor.py
Lib/idlelib/help.html
Lib/idlelib/idle_test/test_iomenu.py
Lib/idlelib/idle_test/test_sidebar.py
Lib/idlelib/iomenu.py
Lib/idlelib/mainmenu.py
Lib/idlelib/pyshell.py
Lib/logging/__init__.py
Lib/logging/config.py
Lib/logging/handlers.py
Lib/numbers.py
Lib/posixpath.py
Lib/pydoc_data/topics.py
Lib/test/datetimetester.py
Lib/test/support/__init__.py
Lib/test/test_ast.py
Lib/test/test_asyncio/test_unix_events.py
Lib/test/test_capi.py
Lib/test/test_check_c_globals.py
Lib/test/test_cmd_line.py
Lib/test/test_compile.py
Lib/test/test_coroutines.py
Lib/test/test_csv.py
Lib/test/test_dataclasses.py
Lib/test/test_decimal.py
Lib/test/test_descrtut.py
Lib/test/test_float.py
Lib/test/test_grp.py
Lib/test/test_int.py
Lib/test/test_json/test_decode.py
Lib/test/test_logging.py
Lib/test/test_minidom.py
Lib/test/test_numeric_tower.py
Lib/test/test_pwd.py
Lib/test/test_socket.py
Lib/test/test_sys.py
Lib/test/test_type_comments.py
Lib/test/test_xmlrpc.py
Lib/threading.py
Lib/unittest/test/test_async_case.py
Lib/xml/dom/minidom.py
Mac/BuildScript/build-installer.py
Misc/ACKS
Misc/NEWS
Misc/stable_abi.txt
Modules/_datetimemodule.c
Modules/_testcapimodule.c
Modules/atexitmodule.c
Objects/codeobject.c
Objects/floatobject.c
Objects/genobject.c
Objects/longobject.c
PC/clinic/winreg.c.h
PC/winreg.c
PCbuild/get_externals.bat
PCbuild/python.props
PCbuild/readme.txt
Parser/parser.c
Parser/pegen.c
Python/clinic/sysmodule.c.h
Python/initconfig.c
Python/sysmodule.c
README.rst
Tools/c-analyzer/c_parser/parser/__init__.py
Tools/msi/build.bat
Tools/msi/buildrelease.bat
Tools/scripts/stable_abi.py
Tools/ssl/multissltests.py
configure
configure.ac

index f0b9084..0ce3566 100644 (file)
@@ -6,7 +6,7 @@ About these documents
 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
@@ -21,7 +21,7 @@ Many thanks go to:
 
 * 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.
index 0feddeb..69d7c27 100644 (file)
@@ -44,38 +44,39 @@ though it may take a while to be processed.
 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::
@@ -99,6 +100,6 @@ patching Python in the `Python Developer's Guide`_.  If you have questions,
 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/
index 8d7a2ed..b939d93 100644 (file)
@@ -1990,9 +1990,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
           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
@@ -2010,6 +2007,12 @@ and :c:type:`PyType_Type` effectively act as defaults.)
 
    .. 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`)
 
 
@@ -2047,9 +2050,9 @@ This results in types that are limited relative to types defined in Python:
   :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:
index 01243de..8fdff79 100644 (file)
@@ -74,6 +74,11 @@ html_theme_options = {
     '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
 
index b7886ae..16fbb39 100644 (file)
         <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'>
index ea102b9..7334d98 100644 (file)
-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,,
diff --git a/Doc/docutils.conf b/Doc/docutils.conf
new file mode 100644 (file)
index 0000000..75995ad
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# 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/
index 0994e3e..01b4df6 100644 (file)
@@ -27,8 +27,8 @@ Recommended third party tools
 
 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.
 
index 794b697..9da1d01 100644 (file)
@@ -321,8 +321,8 @@ is exactly the same type of object that a lambda expression yields) is assigned!
 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.
 
@@ -338,8 +338,8 @@ cycles and deletes the objects involved. The :mod:`gc` module provides functions
 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.
index 1d2aca6..318e355 100644 (file)
@@ -41,7 +41,7 @@ on what you're trying to do.
 
 .. 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
@@ -49,10 +49,10 @@ to learn Python's C API.
 
 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.
 
@@ -286,6 +286,6 @@ Can I create an object class with some methods implemented in C and others in Py
 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).
index 7723114..f77bf7e 100644 (file)
@@ -336,7 +336,7 @@ different companies and organizations.
 
 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.
index db4d057..79176d0 100644 (file)
@@ -95,7 +95,7 @@ The following packages can help with the creation of console and GUI
 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)
@@ -1066,7 +1066,7 @@ performance levels:
   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
index af6ed71..24daf19 100644 (file)
@@ -576,9 +576,9 @@ Glossary
       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
index ce7700f..7773620 100644 (file)
@@ -22,5 +22,5 @@ We recommend the following resources for porting extension modules to Python 3:
 
 .. _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/
index c0149ff..b4de190 100644 (file)
@@ -537,12 +537,12 @@ Patches adding support for these would be welcome; see
 `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.
index f2e2f7e..6e7719e 100644 (file)
@@ -582,11 +582,18 @@ a pure Python equivalent:
 
 .. 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__')
@@ -663,6 +670,15 @@ a pure Python equivalent:
         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:
@@ -696,6 +712,10 @@ a pure Python equivalent:
     >>> 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.
index eb80015..1c3bd23 100644 (file)
@@ -1215,7 +1215,7 @@ flow inside a program.  The book uses Scheme for its examples, but many of the
 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
@@ -1228,7 +1228,7 @@ https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying.
 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".
index 321c4bc..16df3b7 100644 (file)
@@ -2678,6 +2678,88 @@ You can of course use the conventional means of decoration::
         ...
 
 
+.. _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
index abcc342..add1c11 100644 (file)
@@ -433,9 +433,9 @@ to make sure everything functions as expected in both versions of Python.
 
 
 .. _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/
@@ -445,7 +445,7 @@ to make sure everything functions as expected in both versions of Python.
 .. _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
index 535b21b..4969d24 100644 (file)
@@ -167,7 +167,7 @@ On the Computerphile Youtube channel, Tom Scott briefly
 (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/>`_
@@ -735,7 +735,7 @@ References
 ----------
 
 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
@@ -745,7 +745,7 @@ discuss questions of character encodings as well as how to internationalize
 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.
 
index e1a2f48..69af3c3 100644 (file)
@@ -411,7 +411,7 @@ fetched, particularly the headers sent by the server. It is currently an
 :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.
 
diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py
deleted file mode 100644 (file)
index 77daf8f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py
deleted file mode 100644 (file)
index cb86331..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py
deleted file mode 100644 (file)
index 3504a35..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py
deleted file mode 100644 (file)
index cd38d73..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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()
diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py
deleted file mode 100644 (file)
index 147807a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py
deleted file mode 100644 (file)
index 2e1175e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py
deleted file mode 100644 (file)
index ee0000e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py
deleted file mode 100644 (file)
index 624cfe2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py
deleted file mode 100644 (file)
index 16dc348..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py
deleted file mode 100644 (file)
index 11f9639..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py
deleted file mode 100644 (file)
index 9de6e7b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py
deleted file mode 100644 (file)
index fc60287..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py
deleted file mode 100644 (file)
index 48ea6fa..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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()
diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py
deleted file mode 100644 (file)
index c0d87cd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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()
index 63b64b9..84df5e7 100644 (file)
@@ -1062,7 +1062,7 @@ normal libraries do.
 
 .. 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.
 
 
index 300092d..0e66b3e 100644 (file)
@@ -332,7 +332,7 @@ Creating Futures and Tasks
 
 .. 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`
index 7e4066c..7b74bbd 100644 (file)
@@ -20,20 +20,21 @@ The following exception is defined:
 
 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:
 
@@ -59,12 +60,12 @@ The :mod:`bdb` module also defines two classes:
       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
 
@@ -73,6 +74,49 @@ The :mod:`bdb` module also defines two classes:
       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)
 
@@ -95,9 +139,12 @@ The :mod:`bdb` module also defines two classes:
 
    .. 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()
 
@@ -166,45 +213,46 @@ The :mod:`bdb` module also defines two classes:
    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)
 
@@ -228,9 +276,9 @@ The :mod:`bdb` module also defines two classes:
 
       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])
@@ -253,7 +301,7 @@ The :mod:`bdb` module also defines two classes:
    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*
@@ -261,8 +309,8 @@ The :mod:`bdb` module also defines two classes:
 
    .. 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)
 
@@ -272,12 +320,13 @@ The :mod:`bdb` module also defines two classes:
 
    .. 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)
 
@@ -290,7 +339,7 @@ The :mod:`bdb` module also defines two classes:
 
    .. 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)
 
@@ -311,16 +360,18 @@ The :mod:`bdb` module also defines two classes:
 
    .. 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).
@@ -352,20 +403,34 @@ Finally, the module defines the following functions:
 
 .. 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()
 
index 513675d..c2927c1 100644 (file)
@@ -216,7 +216,7 @@ records in a table::
     ...     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)]
index 67b64dd..2086383 100644 (file)
@@ -664,7 +664,7 @@ added elements by appending to the right and popping to the left::
 
     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)
index a5ee0fb..feaa7c1 100644 (file)
@@ -353,9 +353,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
 
 .. 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:
index d22cc28..e4c40cf 100644 (file)
@@ -164,6 +164,8 @@ are always available.  They are listed here in alphabetical order.
    :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
 
@@ -891,6 +893,14 @@ are always available.  They are listed here in alphabetical order.
    .. 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)
 
@@ -1507,6 +1517,8 @@ are always available.  They are listed here in alphabetical order.
    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)
index c78818b..188443c 100644 (file)
@@ -119,7 +119,7 @@ The :mod:`functools` module defines the following functions:
    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.
index ec2c128..2a9946d 100644 (file)
@@ -528,7 +528,7 @@ There are a few tools to extract the strings meant for translation.
 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
index fbfb922..69598d4 100644 (file)
@@ -38,14 +38,13 @@ accessible via :func:`getgrnam` or :func:`getgrgid`.)
 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)
 
index e605f7b..380f52b 100644 (file)
@@ -589,7 +589,7 @@ Here is an example session that shows how to ``POST`` requests::
    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
index 3d59665..ba2fa01 100644 (file)
@@ -160,11 +160,10 @@ contained :class:`Cookie` objects.
    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
 
@@ -186,11 +185,11 @@ contained :class:`Cookie` objects.
    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
 
index e91ec40..3058bce 100644 (file)
@@ -61,17 +61,17 @@ New File
 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.
 
@@ -87,11 +87,14 @@ Save
 
 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.
@@ -114,6 +117,9 @@ Undo
 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.
 
@@ -125,9 +131,6 @@ Paste
 
 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
 
@@ -156,12 +159,12 @@ Expand Word
    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:
@@ -169,6 +172,11 @@ Show surrounding parens
 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).
 
@@ -195,12 +203,7 @@ New Indent Width
    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,
@@ -471,6 +474,14 @@ are restricted to four spaces due to Tcl/Tk limitations.
 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
@@ -972,3 +983,23 @@ changed with the Extensions tab of the preferences dialog. See the
 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`).
index 608e70d..dc1799c 100644 (file)
@@ -18,6 +18,11 @@ is a lightweight data interchange format inspired by
 `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.
 
@@ -226,7 +231,7 @@ Basic Usage
    *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
@@ -248,6 +253,12 @@ Basic Usage
    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
@@ -326,7 +337,7 @@ Encoders and Decoders
    *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
index a1b8dc7..88a8353 100644 (file)
@@ -524,6 +524,25 @@ valid keyword parameter name, and so will not clash with the names 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:
 
@@ -823,7 +842,7 @@ Sections which specify formatter configuration are typified by the following.
    [formatter_form01]
    format=F1 %(asctime)s %(levelname)s %(message)s
    datefmt=
-   style='%'
+   style=%
    validate=True
    class=logging.Formatter
 
index 0dc0525..f3b26e7 100644 (file)
@@ -572,6 +572,13 @@ over UDP sockets.
    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.
@@ -629,6 +636,12 @@ supports sending logging messages to a remote or local Unix syslog.
    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.
 
@@ -1047,6 +1060,20 @@ possible, while any potentially slow operations (such as sending an email via
       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
index 6885c4f..824076f 100644 (file)
@@ -707,6 +707,7 @@ the :class:`LogRecord` being processed. Obviously changing the LogRecord needs
 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
@@ -722,32 +723,54 @@ wire).
 
    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()
 
index 0de4485..18e9b1e 100644 (file)
@@ -43,6 +43,16 @@ will print to standard output ::
    [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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index b77845e..db06b08 100644 (file)
@@ -58,11 +58,14 @@ The numeric tower
 
 .. 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.
index ce7913e..f02877e 100644 (file)
@@ -335,7 +335,7 @@ the :mod:`glob` module.)
 
   .. 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
index 6694768..c8bb5a9 100644 (file)
@@ -2439,9 +2439,9 @@ features:
    .. 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
@@ -4870,7 +4870,7 @@ Random numbers
    :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.
 
index b9c33af..7cfa275 100644 (file)
@@ -474,7 +474,7 @@ Example of `statistical bootstrapping
 <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
 
index 86fa35f..dc8e5f4 100644 (file)
@@ -153,7 +153,7 @@ Generate an eight-character alphanumeric password:
 .. 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.
 
index cb672d9..311aae4 100644 (file)
@@ -791,4 +791,4 @@ Querying the size of the output terminal
    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
index bbf2ea1..9c94b86 100644 (file)
@@ -340,7 +340,7 @@ Constants
 
    .. 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.
index 2b08040..cf78bd2 100644 (file)
@@ -8,11 +8,17 @@
 
 **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
@@ -21,117 +27,19 @@ SQLite for internal data storage.  It's also possible to prototype an
 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
@@ -145,119 +53,212 @@ both styles:
       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.
 
@@ -267,15 +268,14 @@ Module functions and constants
        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,
@@ -288,43 +288,38 @@ Module functions and constants
        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
 
@@ -340,6 +335,43 @@ Module functions and constants
    .. 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, /)
 
@@ -355,36 +387,113 @@ Module functions and constants
    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:
@@ -409,8 +518,8 @@ 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
@@ -424,10 +533,84 @@ Connection objects
       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)
 
@@ -471,31 +654,28 @@ Connection objects
       :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.
@@ -505,21 +685,28 @@ Connection objects
 
       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:
@@ -531,12 +718,37 @@ Connection objects
           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)
@@ -551,9 +763,33 @@ Connection objects
 
       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()
@@ -567,21 +803,20 @@ Connection objects
 
       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)
@@ -592,7 +827,7 @@ Connection objects
       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`
@@ -609,10 +844,10 @@ Connection objects
       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
@@ -626,7 +861,7 @@ Connection objects
    .. 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
@@ -634,7 +869,7 @@ Connection objects
 
       .. 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,
@@ -648,59 +883,56 @@ Connection objects
       .. 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
 
@@ -708,35 +940,33 @@ Connection objects
       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
@@ -744,43 +974,46 @@ Connection objects
           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
 
@@ -799,11 +1032,25 @@ Cursor objects
 
    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
@@ -825,7 +1072,7 @@ Cursor objects
       :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*.
@@ -839,46 +1086,50 @@ Cursor objects
       :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.
@@ -894,7 +1145,7 @@ Cursor objects
 
    .. 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.
@@ -908,19 +1159,38 @@ Cursor objects
 
    .. 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
 
@@ -929,7 +1199,7 @@ Cursor objects
       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.
@@ -937,31 +1207,20 @@ Cursor objects
       .. 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
@@ -969,10 +1228,9 @@ 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.
@@ -986,45 +1244,20 @@ Row objects
    .. 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
@@ -1046,7 +1279,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`).
 
 .. 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`.
@@ -1059,8 +1292,8 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`).
 
 .. 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
@@ -1098,7 +1331,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`).
 
 .. 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`.
@@ -1107,7 +1340,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`).
 
    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`.
 
@@ -1125,7 +1358,7 @@ The following Python types can thus be sent to SQLite without any problem:
 +-------------------------------+-------------+
 | Python type                   | SQLite type |
 +===============================+=============+
-| :const:`None`                 | ``NULL``    |
+| ``None``                      | ``NULL``    |
 +-------------------------------+-------------+
 | :class:`int`                  | ``INTEGER`` |
 +-------------------------------+-------------+
@@ -1142,7 +1375,7 @@ This is how SQLite types are converted to Python types by default:
 +-------------+----------------------------------------------+
 | SQLite type | Python type                                  |
 +=============+==============================================+
-| ``NULL``    | :const:`None`                                |
+| ``NULL``    | ``None``                                     |
 +-------------+----------------------------------------------+
 | ``INTEGER`` | :class:`int`                                 |
 +-------------+----------------------------------------------+
@@ -1154,26 +1387,111 @@ This is how SQLite types are converted to Python types by default:
 | ``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*.
@@ -1186,10 +1504,10 @@ registering custom adapter functions.
 
 .. _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.
@@ -1197,47 +1515,86 @@ This can be implemented by adding a ``__conform__(self, protocol)``
 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:
 
@@ -1249,37 +1606,50 @@ 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:
@@ -1289,7 +1659,7 @@ Adapter and converter recipes
 
 This section shows recipes for common adapters and converters.
 
-.. code-block::
+.. testcode::
 
    import datetime
    import sqlite3
@@ -1302,7 +1672,7 @@ This section shows recipes for common adapters and converters.
        """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())
 
@@ -1329,8 +1699,8 @@ This section shows recipes for common adapters and converters.
 
 .. _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`
@@ -1341,26 +1711,38 @@ objects are created implicitly and these shortcut methods return the cursor
 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
@@ -1380,33 +1762,72 @@ the context manager is a no-op.
    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`_.
@@ -1424,22 +1845,22 @@ Explanation
 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
@@ -1452,7 +1873,7 @@ any pending transaction before execution of the given SQL script,
 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:
index 6484e74..1ff6fae 100644 (file)
@@ -911,7 +911,7 @@ Carlo simulation <https://en.wikipedia.org/wiki/Monte_Carlo_method>`_:
     [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%.
 
index dd7c1ab..c82a6ad 100644 (file)
@@ -1415,7 +1415,7 @@ objects that compare equal might have different :attr:`~range.start`,
 
 .. 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.
 
@@ -2508,9 +2508,10 @@ data and are closely related to string objects in a variety of other ways.
 
       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('-')
@@ -5406,6 +5407,165 @@ types, where they are relevant.  Some of these are not reported by the
       [<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
index b710864..e661faf 100644 (file)
@@ -8,6 +8,7 @@
 
 --------------
 
+
 .. seealso::
 
    :ref:`textseq`
@@ -729,7 +730,7 @@ internationalization (i18n) since in that context, the simpler syntax and
 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
 
index c1a8b01..55214cf 100644 (file)
@@ -460,9 +460,9 @@ always available.
    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`
@@ -478,7 +478,8 @@ always available.
    :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.
@@ -497,6 +498,9 @@ always available.
       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
 
@@ -677,6 +681,13 @@ always available.
 
    .. 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
@@ -950,19 +961,31 @@ always available.
 
    .. 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__
 
@@ -1255,6 +1278,14 @@ always available.
 
    .. 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::
@@ -1744,4 +1775,4 @@ always available.
 
 .. 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\ .
index d264a33..ce51856 100644 (file)
@@ -29,10 +29,15 @@ The module defines the following functions:
    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]]])
 
@@ -51,8 +56,7 @@ The module defines the following functions:
 
    .. 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()
index 07c3339..5944052 100644 (file)
@@ -942,6 +942,16 @@ The :mod:`test.support` module defines the following functions:
    .. 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:
 
 
index 14434fb..47ff74d 100644 (file)
@@ -9,11 +9,23 @@
 --------------
 
 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
index 096a343..0d2b344 100644 (file)
@@ -61,7 +61,7 @@ details that are unchanged.
    * `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>`_
@@ -90,7 +90,7 @@ Tcl
    (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.
@@ -988,7 +988,7 @@ wherever the image was used.
 
 .. 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:
index 1b7cf31..f0a85d6 100644 (file)
@@ -1544,6 +1544,9 @@ These are not used in annotations. They are building blocks for declaring types.
          True
 
    .. attribute:: __required_keys__
+
+      .. versionadded:: 3.9
+
    .. attribute:: __optional_keys__
 
       ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return
@@ -1566,6 +1569,8 @@ These are not used in annotations. They are building blocks for declaring types.
          >>> 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
index 487856a..4ab6718 100644 (file)
@@ -144,12 +144,6 @@ This module offers the following functions:
 
    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>`.
 
@@ -159,9 +153,10 @@ This module offers the following functions:
 
    *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.*
 
@@ -658,13 +653,12 @@ For more information, see `Accessing an Alternate Registry View
 .. 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:
 
index 0d9bfd5..247509d 100644 (file)
@@ -154,12 +154,12 @@ between conformable Python objects and XML on the wire.
       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.
 
index e0276b4..00691b3 100644 (file)
@@ -353,7 +353,7 @@ Sockets
 
 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.
index 2b42968..911c38f 100644 (file)
@@ -1074,7 +1074,7 @@ subject value:
 
    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:
 
index 72e874e..914a115 100644 (file)
@@ -54,7 +54,7 @@ Jython
    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
@@ -66,7 +66,7 @@ IronPython
    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
@@ -74,7 +74,7 @@ PyPy
    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
index 1a2cb41..e50a036 100644 (file)
@@ -552,7 +552,7 @@ Standard C.  The recognized escape sequences are:
 +-----------------+---------------------------------+-------+
 | Escape Sequence | Meaning                         | Notes |
 +=================+=================================+=======+
-| ``\newline``    | Backslash and newline ignored   |       |
+| ``\``\ <newline>| Backslash and newline ignored   | \(1)  |
 +-----------------+---------------------------------+-------+
 | ``\\``          | Backslash (``\``)               |       |
 +-----------------+---------------------------------+-------+
@@ -574,10 +574,10 @@ Standard C.  The recognized escape sequences are:
 +-----------------+---------------------------------+-------+
 | ``\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:
@@ -585,37 +585,47 @@ 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.
 
index 489f066..9defb24 100644 (file)
@@ -36,6 +36,7 @@ REST_ROLE_MAP = {
     'type': 'type',
     'macro': 'macro',
     'type': 'type',
+    'member': 'member',
 }
 
 
@@ -100,6 +101,12 @@ class Annotations:
             # 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:
@@ -113,15 +120,27 @@ class Annotations:
                 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
index 7167f05..7504978 100644 (file)
@@ -212,12 +212,11 @@ library/smtplib,,:port,method must support that as well as a regular host:port
 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"
index b1e297d..303b884 100644 (file)
@@ -457,6 +457,9 @@ Miscellaneous options
      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
@@ -506,6 +509,9 @@ Miscellaneous options
    .. 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.
 
@@ -517,8 +523,7 @@ Options you shouldn't use
 
    Reserved for use by Jython_.
 
-.. _Jython: http://www.jython.org/
-
+.. _Jython: https://www.jython.org/
 
 .. _using-on-envvars:
 
@@ -676,6 +681,13 @@ conflict.
 
    .. 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
 
index f7db038..9ae0270 100644 (file)
@@ -17,15 +17,16 @@ the IDE and the Package Manager that are worth pointing out.
 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.
@@ -65,7 +66,7 @@ number of standard Unix command line editors, :program:`vim` and
 :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
index 992767a..e0da5d2 100644 (file)
@@ -177,18 +177,22 @@ of available options is shown below.
 | 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                        |
 +---------------------------+--------------------------------------+--------------------------+
index 745b0aa..55061d2 100644 (file)
@@ -1082,7 +1082,7 @@ Here are all of the changes that Python 2.3 makes to the core Python language.
   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
index 1b1fb3b..6c21682 100644 (file)
@@ -882,7 +882,7 @@ in an :c:type:`int`.  The C compilers for most 64-bit platforms still define
 :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
@@ -1930,7 +1930,7 @@ with the same digest state.
 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`.
 
@@ -2019,7 +2019,7 @@ https://www.sqlite.org.
 
 .. seealso::
 
-   http://www.pysqlite.org
+   https://www.pysqlite.org
       The pysqlite web page.
 
    https://www.sqlite.org
index 7524da8..3d0d187 100644 (file)
@@ -155,7 +155,7 @@ up different products and import some of the bugs and patches from
 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
@@ -176,7 +176,7 @@ Hosting of the Python bug tracker is kindly provided by
 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::
@@ -184,13 +184,13 @@ other projects wishing to move from SourceForge to Roundup.
   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
@@ -238,7 +238,7 @@ have adopted Sphinx as their documentation tool.
    `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.
 
 
@@ -1433,7 +1433,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6.
 
    `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
index b74a456..f79dcdc 100644 (file)
@@ -299,7 +299,7 @@ modules.
   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::
 
@@ -1048,7 +1048,7 @@ changes, or look through the Subversion logs for all the details.
   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:``.
@@ -1831,7 +1831,7 @@ packaged as the :mod:`unittest2` package, from
 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
@@ -2692,7 +2692,7 @@ As part of this change, the :ref:`installing-index` and
 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
index 3d89b97..6ce6358 100644 (file)
@@ -72,7 +72,7 @@ order.  The *_asdict()* method for :func:`collections.namedtuple` now
 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::
 
index 322e15e..16855c1 100644 (file)
@@ -1175,6 +1175,9 @@ New in 3.10 maintenance releases.
 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
 ------------------
 
@@ -2319,3 +2322,19 @@ Removed
 
 * 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.
+
index 8526fac..e53955e 100644 (file)
@@ -2506,7 +2506,7 @@ IDLE
 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/\ .
 
index 0f98946..1b5b683 100644 (file)
@@ -1106,7 +1106,7 @@ the precision is user configurable, the exact figures may vary. For example,
 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   |
index 1defee4..89b8eef 100644 (file)
@@ -1253,7 +1253,7 @@ imghdr
 ------
 
 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`.)
index 7d6e7f2..98ed72c 100644 (file)
@@ -611,7 +611,7 @@ Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`.
 
 .. 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.
 
 
index 7570748..de582d2 100644 (file)
@@ -427,9 +427,9 @@ params[arguments_ty]:
 
 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)}
@@ -552,9 +552,9 @@ lambda_params[arguments_ty]:
 #
 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)}
index 3d42e54..425d69f 100644 (file)
@@ -236,7 +236,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order)
     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 {
index 4b009e8..21c71bf 100644 (file)
@@ -165,6 +165,8 @@ extern PyStatus _PyConfig_SetPyArgv(
 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 ---------------------------------- */
 
index 4307b61..a564b12 100644 (file)
@@ -305,6 +305,8 @@ struct _is {
 
     struct ast_state ast;
     struct type_cache type_cache;
+
+    int int_max_str_digits;
 };
 
 extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
index 2bea3a5..90069f8 100644 (file)
@@ -11,6 +11,41 @@ extern "C" {
 #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)
 {
index cef4374..1714f85 100644 (file)
 /*--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.
index 75d6113..81fbb85 100644 (file)
@@ -805,15 +805,18 @@ def checkfuncname(b, frame):
     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:
index 33dbc46..b296c3e 100644 (file)
@@ -94,7 +94,7 @@ def _add_method(name, *args, rounds=None):
         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:
index b6973db..1826cdc 100644 (file)
@@ -12,7 +12,7 @@ from importlib import resources
 __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"),
similarity index 94%
rename from Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl
rename to Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl
index 4654c00..0309971 100644 (file)
Binary files a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl and b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl differ
index 3a50eb8..4a42af5 100644 (file)
@@ -2,9 +2,10 @@ Guido van Rossum, as well as being the creator of the Python language, is the
 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
@@ -28,6 +29,15 @@ Jim Jewett, Martin v. Löwis, Jason Orendorff, Guilherme Polo, Josh Robb,
 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
index add0d8c..277fd94 100644 (file)
@@ -4,6 +4,10 @@ Released 2023-04-03?
 =========================
 
 
+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.
 
index 8870fda..76aec58 100644 (file)
@@ -16,8 +16,9 @@ and omissions and lag behind changes in idlelib.
 
 
 IDLELIB FILES
+=============
+
 Implementation files not in IDLE MENU are marked (nim).
-Deprecated files and objects are listed separately as the end.
 
 Startup
 -------
@@ -33,22 +34,22 @@ autocomplete.py   # Complete attribute names or filenames.
 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.
@@ -59,7 +60,6 @@ macosx.py         # Help IDLE run on Macs (nim).
 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).
@@ -69,22 +69,25 @@ query.py          # Query user for information
 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
 -------------
@@ -98,6 +101,7 @@ Text
 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
@@ -108,13 +112,10 @@ Subdirectories
 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>>'.
@@ -160,63 +161,68 @@ Edit
   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
@@ -232,11 +238,14 @@ Help
 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.
@@ -250,3 +259,32 @@ htest function def or "if __name__ == '__main__'" clause.
 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.
index 10d9a72..4fe64dc 100644 (file)
@@ -52,7 +52,7 @@ def transform_children(child_dict, modname=None):
                 # 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
index 04444a3..376c6ee 100644 (file)
@@ -578,7 +578,7 @@ class IdleConf:
         """
         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.
index 4c89c27..09f455c 100644 (file)
@@ -121,7 +121,7 @@ class ConfigDialog(Toplevel):
         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 ')
index 859a288..08d6aa2 100644 (file)
@@ -86,10 +86,20 @@ class EditorWindow:
                     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,
index e8e7d28..722406b 100644 (file)
@@ -91,6 +91,7 @@
 <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>
@@ -237,13 +239,13 @@ described below are moved around to conform to Apple guidelines.</p>
 </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
@@ -255,10 +257,13 @@ and after the window title.  If there is no associated file,
 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>
@@ -278,6 +283,8 @@ be undone.</p>
 </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>
@@ -287,8 +294,6 @@ be undone.</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>
@@ -309,17 +314,21 @@ Clear any selection and update the line and column status.</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>
@@ -338,11 +347,7 @@ Editing and navigation section below.</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>
@@ -565,6 +570,13 @@ are restricted to four spaces due to Tcl/Tk limitations.</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
@@ -991,6 +1003,18 @@ information.  The only current default extension is zzdummy, an example
 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 =&gt; 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>
 
 
@@ -1021,6 +1045,7 @@ also used for testing.</p>
 <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>
@@ -1044,6 +1069,7 @@ also used for testing.</p>
 <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>
@@ -1141,7 +1167,7 @@ also used for testing.</p>
 <br />
     <br />
 
-    Last updated on Jul 03, 2022.
+    Last updated on Sep 03, 2022.
     <a href="/bugs.html">Found a bug</a>?
     <br />
 
index e338893..2fb836d 100644 (file)
@@ -1,10 +1,12 @@
 "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):
@@ -36,9 +38,14 @@ 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')
index 290e037..049531e 100644 (file)
@@ -6,6 +6,7 @@ from itertools import chain
 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
 
@@ -612,7 +613,8 @@ class ShellSidebarTest(unittest.TestCase):
 
     @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(), ['>>>'])
index 327e885..af8159c 100644 (file)
@@ -251,11 +251,17 @@ class IOBinding:
             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
index 429c866..91a32ce 100644 (file)
@@ -111,7 +111,7 @@ menudefs = [
  ('help', [
    ('_About IDLE', '<<about-idle>>'),
    None,
-   ('_IDLE Help', '<<help>>'),
+   ('_IDLE Doc', '<<help>>'),
    ('Python _Docs', '<<python-docs>>'),
    ]),
 ]
index ba33f58..e7fef5f 100755 (executable)
@@ -995,6 +995,23 @@ class PyShell(OutputWindow):
     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.
 
@@ -1011,23 +1028,9 @@ class PyShell(OutputWindow):
         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
index 19bd2bc..09810bd 100644 (file)
@@ -325,7 +325,7 @@ class LogRecord(object):
         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()
index 3bc63b7..5cab008 100644 (file)
@@ -794,6 +794,7 @@ class DictConfigurator(BaseConfigurator):
         """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
index b2d1f27..f0fdeda 100644 (file)
@@ -348,11 +348,15 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
         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
 
@@ -1094,7 +1098,16 @@ class NTEventLogHandler(logging.Handler):
                 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,
index 5b98e64..0985dd8 100644 (file)
@@ -288,7 +288,7 @@ class Rational(Real):
         so that ratios of huge integers convert without overflowing.
 
         """
-        return self.numerator / self.denominator
+        return int(self.numerator) / int(self.denominator)
 
 
 class Integral(Rational):
index 1953746..526f017 100644 (file)
@@ -352,7 +352,7 @@ def normpath(path):
     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
index 6473b95..198bd7c 100644 (file)
@@ -1,5 +1,5 @@
 # -*- 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'
@@ -3429,8 +3429,8 @@ topics = {'assert': 'The "assert" statement\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'
@@ -8907,31 +8907,7 @@ topics = {'assert': 'The "assert" statement\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'
@@ -12180,8 +12156,8 @@ topics = {'assert': 'The "assert" statement\n'
             '| Escape Sequence   | Meaning                           | Notes   '
             '|\n'
             '|===================|===================================|=========|\n'
-            '| "\\newline"        | Backslash and newline ignored     '
-            '|         |\n'
+            '| "\\"<newline>      | Backslash and newline ignored     | '
+            '(1)     |\n'
             '+-------------------+-----------------------------------+---------+\n'
             '| "\\\\"              | Backslash ("\\")                   '
             '|         |\n'
@@ -12214,10 +12190,10 @@ topics = {'assert': 'The "assert" statement\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'
@@ -12227,39 +12203,51 @@ topics = {'assert': 'The "assert" statement\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'
index 43eab64..f474a75 100644 (file)
@@ -1,6 +1,6 @@
 """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
index 9afa282..c9a80c2 100644 (file)
@@ -2111,3 +2111,14 @@ def clear_ignored_deprecations(*tokens: object) -> None:
     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)
index eb86109..57b9735 100644 (file)
@@ -686,6 +686,21 @@ class AST_Tests(unittest.TestCase):
         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
@@ -694,7 +709,7 @@ class AST_Tests(unittest.TestCase):
             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))
@@ -1012,6 +1027,14 @@ Module(
         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)
index 2f68459..1d92278 100644 (file)
@@ -1530,7 +1530,7 @@ class ChildWatcherTestsMixin:
             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:
index 7b208c9..0adb689 100644 (file)
@@ -825,6 +825,20 @@ class TestThreadState(unittest.TestCase):
         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))
index 030debc..898807a 100644 (file)
@@ -1,9 +1,14 @@
 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):
index d299f76..84bd883 100644 (file)
@@ -825,6 +825,39 @@ class CmdLineTest(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.')
index 8312613..ac06518 100644 (file)
@@ -191,6 +191,19 @@ if 1:
         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:
index a6a199e..a414a6f 100644 (file)
@@ -4,6 +4,7 @@ import inspect
 import pickle
 import sys
 import types
+import traceback
 import unittest
 import warnings
 from test import support
@@ -2119,6 +2120,29 @@ class CoroutineTest(unittest.TestCase):
             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):
 
index 6e5dfc6..d94a6f2 100644 (file)
@@ -421,6 +421,34 @@ class TestDialectRegistry(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"
index f4f7ed5..f72e81c 100644 (file)
@@ -2129,12 +2129,12 @@ class TestInit(unittest.TestCase):
         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):
index 310c105..172d5ca 100644 (file)
@@ -2463,6 +2463,15 @@ class CUsabilityTest(UsabilityTest):
 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):
@@ -4522,6 +4531,15 @@ class CCoverage(Coverage):
 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"""
 
index 8e25f58..c5fbcba 100644 (file)
@@ -1,7 +1,7 @@
 # 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
index 29f7756..4c4a8f9 100644 (file)
@@ -135,6 +135,10 @@ class GeneralFloatCases(unittest.TestCase):
         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!')
index c7ec03e..e52e17b 100644 (file)
@@ -49,10 +49,12 @@ class GroupDatabaseTestCase(unittest.TestCase):
 
     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 = {}
index d6be64e..a578ca8 100644 (file)
@@ -1,4 +1,5 @@
 import sys
+import time
 
 import unittest
 from test import support
@@ -568,5 +569,200 @@ class IntTestCases(unittest.TestCase):
         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()
index fdb9e62..124045b 100644 (file)
@@ -2,6 +2,7 @@ import decimal
 from io import StringIO
 from collections import OrderedDict
 from test.test_json import PyTest, CTest
+from test import support
 
 
 class TestDecode:
@@ -95,5 +96,13 @@ 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
index af68f25..74e9504 100644 (file)
@@ -1,4 +1,4 @@
-# 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,
@@ -16,7 +16,7 @@
 
 """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
@@ -3439,6 +3439,36 @@ class ConfigDictTest(BaseTest):
             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 = []
@@ -4020,6 +4050,14 @@ class FormatterTest(unittest.TestCase, AssertErrorMessage):
         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):
index 9762025..ef38c36 100644 (file)
@@ -9,7 +9,7 @@ import unittest
 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
 
@@ -77,6 +77,20 @@ class MinidomTest(unittest.TestCase):
             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") == \
index c54dedb..9cd85e1 100644 (file)
@@ -14,6 +14,27 @@ from fractions import Fraction as F
 _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
@@ -121,6 +142,13 @@ class HashTest(unittest.TestCase):
         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.
         #
index f8f1257..d217e05 100644 (file)
@@ -59,6 +59,8 @@ class PwdTest(unittest.TestCase):
         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 = {}
index 9c5f6d3..e0e0f24 100644 (file)
@@ -1374,10 +1374,21 @@ class GeneralModuleTests(unittest.TestCase):
 
     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.
index 3c36248..1094d40 100644 (file)
@@ -483,11 +483,17 @@ class SysModuleTest(unittest.TestCase):
         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)
@@ -592,7 +598,7 @@ class SysModuleTest(unittest.TestCase):
                  "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
index 71d1430..7a348be 100644 (file)
@@ -323,7 +323,7 @@ class TypeCommentTests(unittest.TestCase):
         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:])
index 1f06f5f..e38bffe 100644 (file)
@@ -287,6 +287,16 @@ class XMLRPCTestCase(unittest.TestCase):
         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()
index 6681265..62f49c0 100644 (file)
@@ -557,7 +557,7 @@ class Event:
     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
index e46b99f..b97ad93 100644 (file)
@@ -14,10 +14,10 @@ def tearDownModule():
 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):
@@ -108,6 +108,7 @@ class TestAsyncCase(unittest.TestCase):
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -143,6 +144,7 @@ class TestAsyncCase(unittest.TestCase):
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -178,6 +180,7 @@ class TestAsyncCase(unittest.TestCase):
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -219,6 +222,7 @@ class TestAsyncCase(unittest.TestCase):
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
@@ -331,6 +335,7 @@ class TestAsyncCase(unittest.TestCase):
 
         events = []
         test = Test("test_func")
+        self.addCleanup(test._tearDownAsyncioLoop)
         try:
             test.debug()
         except MyException:
index d09ef5e..ef8a159 100644 (file)
@@ -358,6 +358,8 @@ class Attr(Node):
         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
index 4308a20..668667c 100755 (executable)
@@ -246,9 +246,9 @@ def library_recipes():
 
     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,
@@ -793,10 +793,16 @@ def verifyThirdPartyFile(url, checksum, fname):
         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):
     """
index f356d02..fc1dcaf 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -911,6 +911,7 @@ Sanyam Khurana
 Tyler Kieft
 Mads Kiilerich
 Jason Killen
+Derek D. Kim
 Jan Kim
 Taek Joo Kim
 Sam Kimbrel
@@ -1404,6 +1405,7 @@ John Popplewell
 Matheus Vieira Portela
 Davin Potts
 Guillaume Pratte
+Pedro Pregueiro
 Florian Preinstorfer
 Alex Prengère
 Amrit Prem
index 2019ab0..b93e410 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,111 @@
 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?
 ==================================
 
@@ -217,7 +322,7 @@ Documentation
 
 - 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.
@@ -234,11 +339,6 @@ Tests
 - 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.
 
index 4a2ee18..095ee73 100644 (file)
 # 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
@@ -259,11 +326,11 @@ typedef newfunc
     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
index ec823ae..ce6335c 100644 (file)
@@ -1,5 +1,5 @@
 /*  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;
index 7cce4e5..9f74c99 100644 (file)
@@ -2800,7 +2800,7 @@ test_PyDateTime_GET(PyObject *self, PyObject *obj)
     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 *
@@ -2814,7 +2814,7 @@ test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj)
     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 *
@@ -2828,7 +2828,7 @@ test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj)
     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 *
@@ -2840,7 +2840,7 @@ test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj)
     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
index 95c653c..7df2db5 100644 (file)
@@ -185,7 +185,7 @@ PyDoc_STRVAR(atexit_run_exitfuncs__doc__,
 \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)
index 976cec5..390b76c 100644 (file)
@@ -1304,7 +1304,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
     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;
     }
index 5af2678..064ba2e 100644 (file)
@@ -150,11 +150,18 @@ float_from_string_inner(const char *s, Py_ssize_t len, void *obj)
     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--;
     }
index 123c17a..4f6fefd 100644 (file)
@@ -439,20 +439,25 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
             /* `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. */
index 685bd56..aea5edc 100644 (file)
@@ -4,6 +4,7 @@
 
 #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()
@@ -35,6 +36,9 @@ _Py_IDENTIFIER(big);
 #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)
 {
@@ -1601,6 +1605,23 @@ long_to_decimal_string_internal(PyObject *aa,
     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:
 
@@ -1660,6 +1681,17 @@ long_to_decimal_string_internal(PyObject *aa,
         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);
@@ -2173,6 +2205,7 @@ PyLong_FromString(const char *str, char **pend, int base)
 
     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. */
@@ -2324,6 +2357,17 @@ digit beyond the first.
             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
@@ -4944,6 +4988,7 @@ long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase)
         }
         return PyLong_FromLong(0L);
     }
+    /* default base and limit, forward to standard implementation */
     if (obase == NULL)
         return PyNumber_Long(x);
 
@@ -5674,6 +5719,8 @@ internal representation of integers.  The attributes are read only.");
 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}
 };
 
@@ -5681,7 +5728,7 @@ static PyStructSequence_Desc int_info_desc = {
     "sys.int_info",   /* name */
     int_info__doc__,  /* doc */
     int_info_fields,  /* fields */
-    2                 /* number of fields */
+    4                 /* number of fields */
 };
 
 PyObject *
@@ -5696,6 +5743,17 @@ PyLong_GetInfo(void)
                               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;
@@ -5720,6 +5778,10 @@ _PyLong_Init(PyInterpreterState *interp)
 
         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;
 }
 
index 183301f..3051bcc 100644 (file)
@@ -390,7 +390,7 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__,
 "            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"
@@ -404,6 +404,9 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__,
 "  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"
@@ -1346,4 +1349,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=497a2e804821d5c9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8ce6fb3b6cd46242 input=a9049054013a1b77]*/
index 004a89a..4fefcdc 100644 (file)
@@ -991,7 +991,9 @@ winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key)
                     (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;
@@ -1012,7 +1014,10 @@ winreg.DeleteKeyEx
     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.
 
@@ -1025,34 +1030,17 @@ static PyObject *
 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;
index 8d7b918..c719114 100644 (file)
@@ -53,7 +53,7 @@ echo.Fetching external libraries...
 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
@@ -77,7 +77,7 @@ echo.Fetching external binaries...
 \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
index c672d7c..bfb0988 100644 (file)
@@ -63,8 +63,8 @@
     <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
index 2ca3f2f..d819637 100644 (file)
@@ -167,7 +167,7 @@ _lzma
     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
index c0080e8..458ada0 100644 (file)
@@ -8997,7 +8997,7 @@ parameters_rule(Parser *p)
         )
         {
             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--;
@@ -9027,7 +9027,7 @@ parameters_rule(Parser *p)
         )
         {
             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--;
@@ -11194,7 +11194,7 @@ lambda_parameters_rule(Parser *p)
         )
         {
             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--;
@@ -11224,7 +11224,7 @@ lambda_parameters_rule(Parser *p)
         )
         {
             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--;
index 016f070..c12aded 100644 (file)
@@ -1,5 +1,6 @@
 #include <Python.h>
 #include "pycore_ast.h"           // _PyAST_Validate(),
+#include "pycore_pystate.h"       // _PyThreadState_GET()
 #include <errcode.h>
 #include "tokenizer.h"
 
@@ -547,7 +548,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,
                          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;
     }
@@ -1131,6 +1132,28 @@ _PyPegen_number_token(Parser *p)
 
     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;
     }
 
index 04c8481..2a6ad89 100644 (file)
@@ -647,6 +647,59 @@ exit:
 
 #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"
@@ -983,4 +1036,4 @@ sys__deactivate_opcache(PyObject *module, PyObject *Py_UNUSED(ignored))
 #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]*/
index 0341e7b..0d2077a 100644 (file)
@@ -3,6 +3,7 @@
 #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()
@@ -95,6 +96,10 @@ static const char usage_3[] = "\
          -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\
 ";
@@ -120,6 +125,10 @@ static const char usage_6[] =
 "   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"
@@ -721,6 +730,10 @@ _PyConfig_InitCompatConfig(PyConfig *config)
 #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)
@@ -1757,6 +1770,48 @@ config_init_tracemalloc(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)
@@ -1808,6 +1863,12 @@ config_read_complex_options(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);
index ac49f78..1d5a06a 100644 (file)
@@ -17,6 +17,7 @@ Data members:
 #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()
@@ -1652,6 +1653,45 @@ sys_mdebug_impl(PyObject *module, int flag)
 }
 #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)
 {
@@ -2027,6 +2067,8 @@ static PyMethodDef sys_methods[] = {
     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 */
 };
 
@@ -2516,6 +2558,7 @@ static PyStructSequence_Field flags_fields[] = {
     {"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}
 };
 
@@ -2523,7 +2566,7 @@ static PyStructSequence_Desc flags_desc = {
     "sys.flags",        /* name */
     flags__doc__,       /* doc */
     flags_fields,       /* fields */
-    16
+    17
 };
 
 static int
@@ -2563,6 +2606,7 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
     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;
index c554ff6..934ae45 100644 (file)
@@ -1,4 +1,4 @@
-This is Python version 3.10.6
+This is Python version 3.10.7
 =============================
 
 .. image:: https://travis-ci.com/python/cpython.svg?branch=master
index df70aae..8ec4b00 100644 (file)
@@ -12,7 +12,7 @@ conditions that must be applied when parsing C code:
 
 * ...
 
-(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
index a153bd8..23c80f3 100644 (file)
@@ -11,14 +11,15 @@ set BUILDPACK=
 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
index d7ae31b..0612a3c 100644 (file)
@@ -43,26 +43,27 @@ set BUILDZIP=1
 \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
index 6d70340..2820efd 100755 (executable)
@@ -119,6 +119,8 @@ class ABIItem:
     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',
@@ -173,6 +175,15 @@ def parse_manifest(file):
             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))
@@ -246,7 +257,9 @@ REST_ROLES = {
 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:
@@ -257,7 +270,13 @@ def gen_doc_annotations(manifest, args, outfile):
             '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
index 8207680..91d6f55 100755 (executable)
@@ -47,8 +47,8 @@ OPENSSL_OLD_VERSIONS = [
 ]
 
 OPENSSL_RECENT_VERSIONS = [
-    "1.1.1n",
-    "3.0.2"
+    "1.1.1q",
+    "3.0.5"
 ]
 
 LIBRESSL_OLD_VERSIONS = [
index 19f1bd5..bad6199 100755 (executable)
--- a/configure
+++ b/configure
@@ -2,7 +2,7 @@
 # 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.
@@ -267,10 +267,10 @@ fi
     $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
@@ -582,7 +582,7 @@ PACKAGE_NAME='python'
 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"
@@ -1651,7 +1651,7 @@ Some influential environment variables:
 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
@@ -1919,9 +1919,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $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
@@ -14866,7 +14866,7 @@ fi
 # 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
@@ -18627,7 +18627,7 @@ $config_files
 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
index 763fc69..cc69015 100644 (file)
@@ -2,7 +2,7 @@ dnl ***************************************************
 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)
@@ -10,7 +10,7 @@ m4_define(PYTHON_VERSION, 3.10)
 
 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],
@@ -4585,7 +4585,7 @@ fi
 # 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"