diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index 2affb50dc10..3ed3abd02a7 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -10,6 +10,10 @@ steps: clean: true fetchDepth: 5 +# Work around a known issue affecting Ubuntu VMs on Pipelines +- script: sudo setfacl -Rb /home/vsts + displayName: 'Workaround ACL issue' + - script: ${{ parameters.sudo_dependencies }} ./.azure-pipelines/posix-deps-${{ parameters.dependencies }}.sh $(openssl_version) displayName: 'Install dependencies' diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 03e36cfcedd..fae51384356 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,6 +11,7 @@ **/*context* @1st1 **/*genobject* @1st1 **/*hamt* @1st1 +Objects/dict* @methane # Hashing **/*hashlib* @python/crypto-team @@ -25,8 +26,8 @@ # Ignoring importlib.h so as to not get flagged on # all pull requests that change the emitted # bytecode. -**/*import*.c @python/import-team -**/*import*.py @python/import-team +**/*import*.c @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw +**/*import*.py @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw # SSL @@ -42,6 +43,12 @@ Python/bootstrap_hash.c @python/crypto-team **/*imap* @python/email-team **/*poplib* @python/email-team +# Parser/Pgen +/Parser/pgen/ @pablogsal + +# SQLite 3 +**/*sqlite* @berkerpeksag + # subprocess **/*subprocess* @gpshead @@ -49,6 +56,9 @@ Python/bootstrap_hash.c @python/crypto-team /PC/ @python/windows-team /PCbuild/ @python/windows-team +# Urllib +**/*robotparser* @berkerpeksag + # Windows installer packages /Tools/msi/ @python/windows-team /Tools/nuget/ @python/windows-team diff --git a/Doc/Makefile b/Doc/Makefile index 53877e61329..cf1bb88b0b8 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -48,11 +48,19 @@ build: @if [ -f ../Misc/NEWS ] ; then \ echo "Using existing Misc/NEWS file"; \ cp ../Misc/NEWS build/NEWS; \ - elif [ -d ../Misc/NEWS.d ]; then \ - echo "Building NEWS from Misc/NEWS.d with blurb"; \ - $(BLURB) merge -f build/NEWS; \ + elif $(BLURB) help >/dev/null 2>&1 && $(SPHINXBUILD) --version >/dev/null 2>&1; then \ + if [ -d ../Misc/NEWS.d ]; then \ + echo "Building NEWS from Misc/NEWS.d with blurb"; \ + $(BLURB) merge -f build/NEWS; \ + else \ + echo "Neither Misc/NEWS.d nor Misc/NEWS found; cannot build docs"; \ + exit 1; \ + fi \ else \ - echo "Neither Misc/NEWS.d nor Misc/NEWS found; cannot build docs"; \ + echo ""; \ + echo "Missing the required blurb or sphinx-build tools."; \ + echo "Please run 'make venv' to install local copies."; \ + echo ""; \ exit 1; \ fi $(SPHINXBUILD) $(ALLSPHINXOPTS) diff --git a/Doc/bugs.rst b/Doc/bugs.rst index c449ba2e719..1e044ad2033 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -25,7 +25,15 @@ docs@python.org (behavioral bugs can be sent to python-list@python.org). though it may take a while to be processed. .. seealso:: - `Documentation bugs`_ on the Python issue tracker + + `Documentation bugs`_ + A list of documentation bugs that have been submitted to the Python issue tracker. + + `Issue Tracking `_ + Overview of the process involved in reporting an improvement on the tracker. + + `Helping with Documentation `_ + Comprehensive guide for individuals that are interested in contributing to Python documentation. .. _using-the-tracker: diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index 78724619ea3..b7949e23500 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -98,6 +98,22 @@ Macros to create objects: minute, second and microsecond. +.. c:function:: PyObject* PyDateTime_FromDateAndTimeAndFold(int year, int month, int day, int hour, int minute, int second, int usecond, int fold) + + Return a :class:`datetime.datetime` object with the specified year, month, day, hour, + minute, second, microsecond and fold. + + .. versionadded:: 3.6 + + +.. c:function:: PyObject* PyTime_FromTimeAndFold(int hour, int minute, int second, int usecond, int fold) + + Return a :class:`datetime.time` object with the specified hour, minute, second, + microsecond and fold. + + .. versionadded:: 3.6 + + .. c:function:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond) Return a :class:`datetime.time` object with the specified hour, minute, second and diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 8c5f66cbef7..13f0aff1cf9 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -53,8 +53,8 @@ Printing and clearing .. c:function:: void PyErr_PrintEx(int set_sys_last_vars) Print a standard traceback to ``sys.stderr`` and clear the error indicator. - **Unless** the error is a ``SystemExit``. In that case the no traceback - is printed and Python process will exit with the error code specified by + **Unless** the error is a ``SystemExit``, in that case no traceback is + printed and the Python process will exit with the error code specified by the ``SystemExit`` instance. Call this function **only** when the error indicator is set. Otherwise it diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 2c6d21fa9da..367c069a7ff 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -37,6 +37,7 @@ The following functions can be safely called before Python is initialized: * Informative functions: + * :c:func:`Py_IsInitialized` * :c:func:`PyMem_GetAllocator` * :c:func:`PyObject_GetArenaAllocator` * :c:func:`Py_GetBuildInfo` @@ -855,6 +856,12 @@ code, or when embedding the Python interpreter: created, the current thread must not have acquired it, otherwise deadlock ensues. + .. note:: + Calling this function from a thread when the runtime is finalizing + will terminate the thread, even if the thread was not created by Python. + You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + check if the interpreter is in process of being finalized before calling + this function to avoid unwanted termination. .. c:function:: PyThreadState* PyThreadState_Get() @@ -902,6 +909,12 @@ with sub-interpreters: When the function returns, the current thread will hold the GIL and be able to call arbitrary Python code. Failure is a fatal error. + .. note:: + Calling this function from a thread when the runtime is finalizing + will terminate the thread, even if the thread was not created by Python. + You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + check if the interpreter is in process of being finalized before calling + this function to avoid unwanted termination. .. c:function:: void PyGILState_Release(PyGILState_STATE) @@ -1067,6 +1080,18 @@ All of the following functions must be called after :c:func:`Py_Initialize`. *tstate*, which should not be *NULL*. The lock must have been created earlier. If this thread already has the lock, deadlock ensues. + .. note:: + Calling this function from a thread when the runtime is finalizing + will terminate the thread, even if the thread was not created by Python. + You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + check if the interpreter is in process of being finalized before calling + this function to avoid unwanted termination. + + .. versionchanged:: 3.8 + Updated to be consistent with :c:func:`PyEval_RestoreThread`, + :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`, + and terminate the current thread if called while the interpreter is finalizing. + :c:func:`PyEval_RestoreThread` is a higher-level function which is always available (even when threads have not been initialized). @@ -1093,6 +1118,18 @@ All of the following functions must be called after :c:func:`Py_Initialize`. :c:func:`PyEval_RestoreThread` or :c:func:`PyEval_AcquireThread` instead. + .. note:: + Calling this function from a thread when the runtime is finalizing + will terminate the thread, even if the thread was not created by Python. + You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + check if the interpreter is in process of being finalized before calling + this function to avoid unwanted termination. + + .. versionchanged:: 3.8 + Updated to be consistent with :c:func:`PyEval_RestoreThread`, + :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`, + and terminate the current thread if called while the interpreter is finalizing. + .. c:function:: void PyEval_ReleaseLock() @@ -1394,6 +1431,11 @@ These functions are only intended to be used by advanced debugging tools. Return the interpreter state object at the head of the list of all such objects. +.. c:function:: PyInterpreterState* PyInterpreterState_Main() + + Return the main interpreter state object. + + .. c:function:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp) Return the next interpreter state object after *interp* from the list of all diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 6bb2356f694..69aef0da04f 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -48,7 +48,8 @@ Include Files All function, type and macro definitions needed to use the Python/C API are included in your code by the following line:: - #include "Python.h" + #define PY_SSIZE_T_CLEAN + #include This implies inclusion of the following standard headers: ````, ````, ````, ````, ```` and ```` @@ -60,6 +61,9 @@ This implies inclusion of the following standard headers: ````, headers on some systems, you *must* include :file:`Python.h` before any standard headers are included. + It is recommended to always define ``PY_SSIZE_T_CLEAN`` before including + ``Python.h``. See :ref:`arg-parsing` for a description of this macro. + All user visible names defined by Python.h (except those defined by the included standard headers) have one of the prefixes ``Py`` or ``_Py``. Names beginning with ``_Py`` are for internal use by the Python implementation and should not be diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index b79b7e49b67..65a207691b8 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -440,8 +440,9 @@ Customize Memory Allocators Setup hooks to detect bugs in the Python memory allocator functions. - Newly allocated memory is filled with the byte ``0xCB``, freed memory is - filled with the byte ``0xDB``. + Newly allocated memory is filled with the byte ``0xCD`` (``CLEANBYTE``), + freed memory is filled with the byte ``0xDD`` (``DEADBYTE``). Memory blocks + are surrounded by "forbidden bytes" (``FORBIDDENBYTE``: byte ``0xFD``). Runtime checks: @@ -471,6 +472,12 @@ Customize Memory Allocators if the GIL is held when functions of :c:data:`PYMEM_DOMAIN_OBJ` and :c:data:`PYMEM_DOMAIN_MEM` domains are called. + .. versionchanged:: 3.8.0 + Byte patterns ``0xCB`` (``CLEANBYTE``), ``0xDB`` (``DEADBYTE``) and + ``0xFB`` (``FORBIDDENBYTE``) have been replaced with ``0xCD``, ``0xDD`` + and ``0xFD`` to use the same values than Windows CRT debug ``malloc()`` + and ``free()``. + .. _pymalloc: diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index f36cfe551e4..0647a493303 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2052,7 +2052,7 @@ Sequence Object Structures signature. It should modify its first operand, and return it. This slot may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceConcat` will fall back to :c:func:`PySequence_Concat`. It is also used by the - augmented assignment ``+=``, after trying numeric inplace addition + augmented assignment ``+=``, after trying numeric in-place addition via the :c:member:`~PyNumberMethods.nb_inplace_add` slot. .. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat @@ -2061,7 +2061,7 @@ Sequence Object Structures signature. It should modify its first operand, and return it. This slot may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceRepeat` will fall back to :c:func:`PySequence_Repeat`. It is also used by the - augmented assignment ``*=``, after trying numeric inplace multiplication + augmented assignment ``*=``, after trying numeric in-place multiplication via the :c:member:`~PyNumberMethods.nb_inplace_multiply` slot. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index c891f6320f9..317093e9561 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -109,6 +109,10 @@ the same library that the Python runtime is using. (:func:`sys.getfilesystemencoding`). If *closeit* is true, the file is closed before PyRun_SimpleFileExFlags returns. + .. note:: + On Windows, *fp* should be opened as binary mode (e.g. ``fopen(filename, "rb")``. + Otherwise, Python may not handle script file with LF line ending correctly. + .. c:function:: int PyRun_InteractiveOne(FILE *fp, const char *filename) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index a825efc1a67..1facc0408d5 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -277,6 +277,11 @@ the full reference. | | simply skip the extension. | | +------------------------+--------------------------------+---------------------------+ + .. versionchanged:: 3.8 + + On Unix, C extensions are no longer linked to libpython except on + Android. + .. class:: Distribution diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst index 54ed1aebc24..a65a26ac57f 100644 --- a/Doc/distutils/setupscript.rst +++ b/Doc/distutils/setupscript.rst @@ -523,7 +523,7 @@ following way:: setup(..., data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']), - ('config', ['cfg/data.cfg']), + ('config', ['cfg/data.cfg'])], ) Each (*directory*, *files*) pair in the sequence specifies the installation diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst index 9fe12c2424c..9bfad7fc318 100644 --- a/Doc/extending/building.rst +++ b/Doc/extending/building.rst @@ -145,7 +145,7 @@ that distutils gets the invocations right. Distributing your extension modules =================================== -When an extension has been successfully build, there are three ways to use it. +When an extension has been successfully built, there are three ways to use it. End-users will typically want to install the module, they do so by running :: @@ -158,7 +158,7 @@ Module maintainers should produce source packages; to do so, they run :: In some cases, additional files need to be included in a source distribution; this is done through a :file:`MANIFEST.in` file; see :ref:`manifest` for details. -If the source distribution has been build successfully, maintainers can also +If the source distribution has been built successfully, maintainers can also create binary distributions. Depending on the platform, one of the following commands can be used to do so. :: diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index 7e4fc19db83..13d83b72f82 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -53,6 +53,7 @@ interface. This interface is intended to execute a Python script without needing to interact with the application directly. This can for example be used to perform some operation on a file. :: + #define PY_SSIZE_T_CLEAN #include int diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 9fbd91f6a03..433178ab64d 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -55,8 +55,9 @@ called ``spam``, the C file containing its implementation is called :file:`spammodule.c`; if the module name is very long, like ``spammify``, the module name can be just :file:`spammify.c`.) -The first line of our file can be:: +The first two lines of our file can be:: + #define PY_SSIZE_T_CLEAN #include which pulls in the Python API (you can add a comment describing the purpose of @@ -68,6 +69,9 @@ the module and a copyright notice if you like). headers on some systems, you *must* include :file:`Python.h` before any standard headers are included. + It is recommended to always define ``PY_SSIZE_T_CLEAN`` before including + ``Python.h``. See :ref:`parsetuple` for a description of this macro. + All user-visible symbols defined by :file:`Python.h` have a prefix of ``Py`` or ``PY``, except those defined in standard header files. For convenience, and since they are used extensively by the Python interpreter, ``"Python.h"`` @@ -729,7 +733,8 @@ it returns false and raises an appropriate exception. Here is an example module which uses keywords, based on an example by Geoff Philbrick (philbrick@hks.com):: - #include "Python.h" + #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ + #include static PyObject * keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds) @@ -1228,7 +1233,7 @@ The function :c:func:`spam_system` is modified in a trivial way:: In the beginning of the module, right after the line :: - #include "Python.h" + #include two more lines must be added:: diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index bb8a40d0fb0..b4bf9b9e6f7 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -92,6 +92,7 @@ The second bit is the definition of the type object. :: .tp_doc = "Custom objects", .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = PyType_GenericNew, }; diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 74e1af6ef24..2ad27658705 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -280,6 +280,7 @@ solution then is to call :c:func:`PyParser_ParseString` and test for ``e.error`` equal to ``E_EOF``, which means the input is incomplete. Here's a sample code fragment, untested, inspired by code from Alex Farber:: + #define PY_SSIZE_T_CLEAN #include #include #include @@ -318,6 +319,7 @@ complete example using the GNU readline library (you may want to ignore #include #include + #define PY_SSIZE_T_CLEAN #include #include #include diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 7ee340d7957..3ef553e8acb 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -306,14 +306,10 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. The latest stable releases can always be found on the `Python download page -`_. There are two production-ready version -of Python: 2.x and 3.x, but the recommended one at this times is Python 3.x. -Although Python 2.x is still widely used, `it will not be -maintained after January 1, 2020 `_. -Python 2.x was known for having more third-party libraries available, however, -by the time of this writing, most of the widely used libraries support Python 3.x, -and some are even dropping the Python 2.x support. - +`_. There are two production-ready versions +of Python: 2.x and 3.x. The recommended version is 3.x, which is supported by +most widely used libraries. Although 2.x is still widely used, `it will not +be maintained after January 1, 2020 `_. How many people are using Python? --------------------------------- diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 31614189a62..f14e8cc824e 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -16,6 +16,9 @@ Is there a source code level debugger with breakpoints, single-stepping, etc.? Yes. +Several debuggers for Python are described below, and the built-in function +:func:`breakpoint` allows you to drop into any of them. + The pdb module is a simple but adequate console-mode debugger for Python. It is part of the standard Python library, and is :mod:`documented in the Library Reference Manual `. You can also write your own debugger by using the code diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 31cdba2444b..5810a6b7997 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -663,6 +663,11 @@ Glossary :term:`finder`. See :pep:`302` for details and :class:`importlib.abc.Loader` for an :term:`abstract base class`. + magic method + .. index:: pair: magic; method + + An informal synonym for :term:`special method`. + mapping A container object that supports arbitrary key lookups and implements the methods specified in the :class:`~collections.abc.Mapping` or @@ -1004,6 +1009,8 @@ Glossary (subscript) notation uses :class:`slice` objects internally. special method + .. index:: pair: special; method + A method that is called implicitly by Python to execute a certain operation on a type, such as addition. Such methods have names starting and ending with double underscores. Special methods are documented in diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index d385d991344..d574c3736b1 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -942,6 +942,13 @@ given numbers, so you can retrieve information about a group in two ways:: >>> m.group(1) 'Lots' +Additionally, you can retrieve named groups as a dictionary with +:meth:`~re.Match.groupdict`:: + + >>> m = re.match(r'(?P\w+) (?P\w+)', 'Jane Doe') + >>> m.groupdict() + {'first': 'Jane', 'last': 'Doe'} + Named groups are handy because they let you use easily-remembered names, instead of having to remember numbers. Here's an example RE from the :mod:`imaplib` module:: diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c index fb2c7b2a430..13d16f5424a 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/custom.c @@ -1,3 +1,4 @@ +#define PY_SSIZE_T_CLEAN #include typedef struct { diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c index 51ab4b80d68..6477a19dafe 100644 --- a/Doc/includes/custom2.c +++ b/Doc/includes/custom2.c @@ -1,3 +1,4 @@ +#define PY_SSIZE_T_CLEAN #include #include "structmember.h" diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c index 09e87355b91..213d0864ce1 100644 --- a/Doc/includes/custom3.c +++ b/Doc/includes/custom3.c @@ -1,3 +1,4 @@ +#define PY_SSIZE_T_CLEAN #include #include "structmember.h" diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c index 0994d8fda0e..b0b2906dbdc 100644 --- a/Doc/includes/custom4.c +++ b/Doc/includes/custom4.c @@ -1,3 +1,4 @@ +#define PY_SSIZE_T_CLEAN #include #include "structmember.h" diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c index 9caf1fdb201..392f86d65ec 100644 --- a/Doc/includes/run-func.c +++ b/Doc/includes/run-func.c @@ -1,3 +1,4 @@ +#define PY_SSIZE_T_CLEAN #include int diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c index 376dddfac09..76ff93948cf 100644 --- a/Doc/includes/sublist.c +++ b/Doc/includes/sublist.c @@ -1,3 +1,4 @@ +#define PY_SSIZE_T_CLEAN #include typedef struct { diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 8d157fd5f59..06f673be790 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -281,9 +281,9 @@ clocks to track time. the event loop's internal monotonic clock. .. note:: - - Timeouts (relative *delay* or absolute *when*) should not - exceed one day. + .. versionchanged:: 3.8 + In Python 3.7 and earlier timeouts (relative *delay* or absolute *when*) + should not exceed one day. This has been fixed in Python 3.8. .. seealso:: @@ -397,9 +397,27 @@ Opening network connections If given, these should all be integers from the corresponding :mod:`socket` module constants. + * *happy_eyeballs_delay*, if given, enables Happy Eyeballs for this + connection. It should + be a floating-point number representing the amount of time in seconds + to wait for a connection attempt to complete, before starting the next + attempt in parallel. This is the "Connection Attempt Delay" as defined + in :rfc:`8305`. A sensible default value recommended by the RFC is ``0.25`` + (250 milliseconds). + + * *interleave* controls address reordering when a host name resolves to + multiple IP addresses. + If ``0`` or unspecified, no reordering is done, and addresses are + tried in the order returned by :meth:`getaddrinfo`. If a positive integer + is specified, the addresses are interleaved by address family, and the + given integer is interpreted as "First Address Family Count" as defined + in :rfc:`8305`. The default is ``0`` if *happy_eyeballs_delay* is not + specified, and ``1`` if it is. + * *sock*, if given, should be an existing, already connected :class:`socket.socket` object to be used by the transport. - If *sock* is given, none of *host*, *port*, *family*, *proto*, *flags* + If *sock* is given, none of *host*, *port*, *family*, *proto*, *flags*, + *happy_eyeballs_delay*, *interleave* and *local_addr* should be specified. * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used @@ -410,6 +428,10 @@ Opening network connections to wait for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). + .. versionadded:: 3.8 + + The *happy_eyeballs_delay* and *interleave* parameters. + .. versionadded:: 3.7 The *ssl_handshake_timeout* parameter. @@ -1601,7 +1623,7 @@ using the :meth:`loop.add_signal_handler` method:: import os import signal - def ask_exit(signame): + def ask_exit(signame, loop): print("got signal %s: exit" % signame) loop.stop() @@ -1611,7 +1633,7 @@ using the :meth:`loop.add_signal_handler` method:: for signame in {'SIGINT', 'SIGTERM'}: loop.add_signal_handler( getattr(signal, signame), - functools.partial(ask_exit, signame)) + functools.partial(ask_exit, signame, loop)) await asyncio.sleep(3600) diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index a2cf5173484..00dc66c48b2 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -56,7 +56,7 @@ See also the `Examples`_ subsection. Creating Subprocesses ===================== -.. coroutinefunction:: create_subprocess_exec(\*args, stdin=None, \ +.. coroutinefunction:: create_subprocess_exec(program, \*args, stdin=None, \ stdout=None, stderr=None, loop=None, \ limit=None, \*\*kwds) diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index 18da18873db..e3f18ccb434 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -17,7 +17,7 @@ those of the :mod:`threading` module with two important caveats: argument; use the :func:`asyncio.wait_for` function to perform operations with timeouts. -asyncio has the following basic sychronization primitives: +asyncio has the following basic synchronization primitives: * :class:`Lock` * :class:`Event` diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index d2a0c8b3369..b3246376846 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -638,7 +638,7 @@ define in order to be compatible with the Python codec registry. .. method:: setstate(state) - Set the state of the encoder to *state*. *state* must be a decoder state + Set the state of the decoder to *state*. *state* must be a decoder state returned by :meth:`getstate`. diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 185b4a10ec9..04b52dc7b21 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -721,6 +721,12 @@ be overridden by subclasses or by attribute assignment. >>> list(custom['Section2'].keys()) ['AnotherKey'] + .. note:: + The optionxform function transforms option names to a canonical form. + This should be an idempotent function: if the name is already in + canonical form, it should be returned unchanged. + + .. attribute:: ConfigParser.SECTCRE A compiled regular expression used to parse section headers. The default diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index 43d4b5b749e..d25c626a175 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -30,6 +30,8 @@ the :manpage:`crypt(3)` routine in the running system. Therefore, any extensions available on the current implementation will also be available on this module. +.. availability:: Unix. Not available on VxWorks. + Hashing Methods --------------- diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 500aad8858f..baab0de8f8a 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1322,14 +1322,14 @@ There are several ways to load shared libraries into the Python process. One way is to instantiate one of the following classes: -.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) +.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0) Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return :c:type:`int`. -.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) +.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0) Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are @@ -1342,7 +1342,7 @@ way is to instantiate one of the following classes: :exc:`WindowsError` used to be raised. -.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) +.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0) Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are @@ -1394,6 +1394,17 @@ the Windows error code which is managed by the :func:`GetLastError` and :func:`ctypes.set_last_error` are used to request and change the ctypes private copy of the windows error code. +The *winmode* parameter is used on Windows to specify how the library is loaded +(since *mode* is ignored). It takes any value that is valid for the Win32 API +``LoadLibraryEx`` flags parameter. When omitted, the default is to use the flags +that result in the most secure DLL load to avoiding issues such as DLL +hijacking. Passing the full path to the DLL is the safest way to ensure the +correct library and dependencies are loaded. + +.. versionchanged:: 3.8 + Added *winmode* parameter. + + .. data:: RTLD_GLOBAL :noindex: diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 1ee23c2175a..abdc9773548 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -458,6 +458,13 @@ Other constructors, all class methods: .. versionadded:: 3.7 +.. classmethod:: date.fromisocalendar(year, week, day) + + Return a :class:`date` corresponding to the ISO calendar date specified by + year, week and day. This is the inverse of the function :meth:`date.isocalendar`. + + .. versionadded:: 3.8 + Class attributes: @@ -854,6 +861,16 @@ Other constructors, all class methods: .. versionadded:: 3.7 + +.. classmethod:: datetime.fromisocalendar(year, week, day) + + Return a :class:`datetime` corresponding to the ISO calendar date specified + by year, week and day. The non-date components of the datetime are populated + with their normal default values. This is the inverse of the function + :meth:`datetime.isocalendar`. + + .. versionadded:: 3.8 + .. classmethod:: datetime.strptime(date_string, format) Return a :class:`.datetime` corresponding to *date_string*, parsed according to diff --git a/Doc/library/email.encoders.rst b/Doc/library/email.encoders.rst index e24ac7b90d2..70bf61323c3 100644 --- a/Doc/library/email.encoders.rst +++ b/Doc/library/email.encoders.rst @@ -19,7 +19,7 @@ need to encode the payloads for transport through compliant mail servers. This is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages containing binary data. -The :mod:`email` package provides some convenient encodings in its +The :mod:`email` package provides some convenient encoders in its :mod:`encoders` module. These encoders are actually used by the :class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` class constructors to provide default encodings. All encoder functions take diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index fc535a3e439..c09ae8cbc60 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -188,7 +188,7 @@ to be using :class:`BytesGenerator`, and not :class:`Generator`. (This is required because strings cannot represent non-ASCII bytes.) Convert any bytes with the high bit set as needed using an ASCII-compatible :mailheader:`Content-Transfer-Encoding`. That is, - transform parts with non-ASCII :mailheader:`Cotnent-Transfer-Encoding` + transform parts with non-ASCII :mailheader:`Content-Transfer-Encoding` (:mailheader:`Content-Transfer-Encoding: 8bit`) to an ASCII compatible :mailheader:`Content-Transfer-Encoding`, and encode RFC-invalid non-ASCII bytes in headers using the MIME ``unknown-8bit`` character set, thus diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 57ed2914581..52a505e0a0f 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -691,8 +691,13 @@ The following exceptions are used as warning categories; see the .. exception:: PendingDeprecationWarning - Base class for warnings about features which will be deprecated in the - future. + Base class for warnings about features which are obsolete and + expected to be deprecated in the future, but are not deprecated + at the moment. + + This class is rarely used as emitting a warning about a possible + upcoming deprecation is unusual, and :exc:`DeprecationWarning` + is preferred for already active deprecations. .. exception:: SyntaxWarning diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ae0c9fb55a7..613e4f74ac4 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -211,19 +211,18 @@ are always available. They are listed here in alphabetical order. @classmethod def f(cls, arg1, arg2, ...): ... - The ``@classmethod`` form is a function :term:`decorator` -- see the description - of function definitions in :ref:`function` for details. + The ``@classmethod`` form is a function :term:`decorator` -- see + :ref:`function` for details. - It can be called either on the class (such as ``C.f()``) or on an instance (such + A class method can be called either on the class (such as ``C.f()``) or on an instance (such as ``C().f()``). The instance is ignored except for its class. If a class method is called for a derived class, the derived class object is passed as the implied first argument. Class methods are different than C++ or Java static methods. If you want those, - see :func:`staticmethod` in this section. + see :func:`staticmethod`. - For more information on class methods, consult the documentation on the standard - type hierarchy in :ref:`types`. + For more information on class methods, see :ref:`types`. .. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) @@ -844,7 +843,8 @@ are always available. They are listed here in alphabetical order. Update and return a dictionary representing the current local symbol table. Free variables are returned by :func:`locals` when it is called in function - blocks, but not in class blocks. + blocks, but not in class blocks. Note that at the module level, :func:`locals` + and :func:`globals` are the same dictionary. .. note:: The contents of this dictionary should not be modified; changes may not @@ -1452,11 +1452,11 @@ are always available. They are listed here in alphabetical order. @staticmethod def f(arg1, arg2, ...): ... - The ``@staticmethod`` form is a function :term:`decorator` -- see the - description of function definitions in :ref:`function` for details. + The ``@staticmethod`` form is a function :term:`decorator` -- see + :ref:`function` for details. - It can be called either on the class (such as ``C.f()``) or on an instance (such - as ``C().f()``). The instance is ignored except for its class. + A static method can be called either on the class (such as ``C.f()``) or on an instance (such + as ``C().f()``). Static methods in Python are similar to those found in Java or C++. Also see :func:`classmethod` for a variant that is useful for creating alternate class @@ -1471,8 +1471,7 @@ are always available. They are listed here in alphabetical order. class C: builtin_open = staticmethod(open) - For more information on static methods, consult the documentation on the - standard type hierarchy in :ref:`types`. + For more information on static methods, see :ref:`types`. .. index:: diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index cd59e5bebfd..16a779fa836 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -474,6 +474,9 @@ The :mod:`functools` module defines the following functions: The same pattern can be used for other similar decorators: ``staticmethod``, ``abstractmethod``, and others. + .. versionadded:: 3.8 + + .. function:: update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES) Update a *wrapper* function to look like the *wrapped* function. The optional diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index f3457a0cdc7..17792b20059 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -55,8 +55,9 @@ in Cookie name (as :attr:`~Morsel.key`). .. class:: SimpleCookie([input]) This class derives from :class:`BaseCookie` and overrides :meth:`value_decode` - and :meth:`value_encode` to be the identity and :func:`str` respectively. - + and :meth:`value_encode`. SimpleCookie supports strings as cookie values. + When setting the value, SimpleCookie calls the builtin :func:`str()` to convert + the value to a string. Values received from HTTP are kept as strings. .. seealso:: @@ -76,15 +77,16 @@ Cookie Objects .. method:: BaseCookie.value_decode(val) - Return a decoded value from a string representation. Return value can be any - type. This method does nothing in :class:`BaseCookie` --- it exists so it can be - overridden. + Return a tuple ``(real_value, coded_value)`` from a string representation. + ``real_value`` can be any type. This method does no decoding in + :class:`BaseCookie` --- it exists so it can be overridden. .. method:: BaseCookie.value_encode(val) - Return an encoded value. *val* can be any type, but return value must be a - string. This method does nothing in :class:`BaseCookie` --- it exists so it can + Return a tuple ``(real_value, coded_value)``. *val* can be any type, but + ``coded_value`` will always be converted to a string. + This method does no encoding in :class:`BaseCookie` --- it exists so it can be overridden. In general, it should be the case that :meth:`value_encode` and diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 8ef9e2eed53..ad449112832 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -356,8 +356,8 @@ Shell and Output windows also have the following. Go to file/line Same as in Debug menu. -The Shell window also has an output squeezing facility explained in the -the *Python Shell window* subsection below. +The Shell window also has an output squeezing facility explained in the *Python +Shell window* subsection below. Squeeze If the cursor is over an output line, squeeze all the output between @@ -716,21 +716,17 @@ In contrast, some system text windows only keep the last n lines of output. A Windows console, for instance, keeps a user-settable 1 to 9999 lines, with 300 the default. -A Tk Text widget, and hence IDLE's Shell, displays characters (codepoints) -in the the BMP (Basic Multilingual Plane) subset of Unicode. -Which characters are displayed with a proper glyph and which with a -replacement box depends on the operating system and installed fonts. -Tab characters cause the following text to begin after -the next tab stop. (They occur every 8 'characters'). -Newline characters cause following text to appear on a new line. -Other control characters are ignored or displayed as a space, box, or -something else, depending on the operating system and font. -(Moving the text cursor through such output with arrow keys may exhibit -some surprising spacing behavior.) +A Tk Text widget, and hence IDLE's Shell, displays characters (codepoints) in +the BMP (Basic Multilingual Plane) subset of Unicode. Which characters are +displayed with a proper glyph and which with a replacement box depends on the +operating system and installed fonts. Tab characters cause the following text +to begin after the next tab stop. (They occur every 8 'characters'). Newline +characters cause following text to appear on a new line. Other control +characters are ignored or displayed as a space, box, or something else, +depending on the operating system and font. (Moving the text cursor through +such output with arrow keys may exhibit some surprising spacing behavior.) :: -.. code-block:: none - - >>> s = 'a\tb\a<\x02><\r>\bc\nd' + >>> s = 'a\tb\a<\x02><\r>\bc\nd' # Enter 22 chars. >>> len(s) 14 >>> s # Display repr(s) diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index d0709f8b678..f027f82ddeb 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -327,6 +327,9 @@ An :class:`IMAP4` instance has the following methods: Shutdown connection to server. Returns server ``BYE`` response. + .. versionchanged:: 3.8 + The method no longer ignores silently arbitrary exceptions. + .. method:: IMAP4.lsub(directory='""', pattern='*') diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 81824ddc1e5..d12f122a57b 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -948,6 +948,11 @@ Classes and functions APIs. This function is retained primarily for use in code that needs to maintain compatibility with the Python 2 ``inspect`` module API. + .. deprecated:: 3.8 + Use :func:`signature` and + :ref:`Signature Object `, which provide a + better introspecting API for callables. + .. versionchanged:: 3.4 This function is now based on :func:`signature`, but still ignores ``__wrapped__`` attributes and includes the already bound first diff --git a/Doc/library/io.rst b/Doc/library/io.rst index e623a041acf..0f1251687ae 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -226,7 +226,7 @@ I/O Base Classes implementations represent a file that cannot be read, written or seeked. - Even though :class:`IOBase` does not declare :meth:`read`, :meth:`readinto`, + Even though :class:`IOBase` does not declare :meth:`read` or :meth:`write` because their signatures will vary, implementations and clients should consider those methods part of the interface. Also, implementations may raise a :exc:`ValueError` (or :exc:`UnsupportedOperation`) @@ -234,9 +234,7 @@ I/O Base Classes The basic type used for binary data read from or written to a file is :class:`bytes`. Other :term:`bytes-like objects ` are - accepted as method arguments too. In some cases, such as - :meth:`~RawIOBase.readinto`, a writable object such as :class:`bytearray` - is required. Text I/O classes work with :class:`str` data. + accepted as method arguments too. Text I/O classes work with :class:`str` data. Note that calling any method (even inquiries) on a closed stream is undefined. Implementations may raise :exc:`ValueError` in this case. @@ -405,7 +403,8 @@ I/O Base Classes Read bytes into a pre-allocated, writable :term:`bytes-like object` *b*, and return the - number of bytes read. If the object is in non-blocking mode and no bytes + number of bytes read. For example, *b* might be a :class:`bytearray`. + If the object is in non-blocking mode and no bytes are available, ``None`` is returned. .. method:: write(b) @@ -495,6 +494,7 @@ I/O Base Classes Read bytes into a pre-allocated, writable :term:`bytes-like object` *b* and return the number of bytes read. + For example, *b* might be a :class:`bytearray`. Like :meth:`read`, multiple reads may be issued to the underlying raw stream, unless the latter is interactive. @@ -719,15 +719,15 @@ than raw I/O does. .. class:: BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE) A buffered interface to random access streams. It inherits - :class:`BufferedReader` and :class:`BufferedWriter`, and further supports - :meth:`seek` and :meth:`tell` functionality. + :class:`BufferedReader` and :class:`BufferedWriter`. The constructor creates a reader and writer for a seekable raw stream, given in the first argument. If the *buffer_size* is omitted it defaults to :data:`DEFAULT_BUFFER_SIZE`. :class:`BufferedRandom` is capable of anything :class:`BufferedReader` or - :class:`BufferedWriter` can do. + :class:`BufferedWriter` can do. In addition, :meth:`seek` and :meth:`tell` + are guaranteed to be implemented. .. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE) @@ -757,8 +757,7 @@ Text I/O .. class:: TextIOBase Base class for text streams. This class provides a character and line based - interface to stream I/O. There is no :meth:`readinto` method because - Python's character strings are immutable. It inherits :class:`IOBase`. + interface to stream I/O. It inherits :class:`IOBase`. There is no public constructor. :class:`TextIOBase` provides or overrides these data attributes and @@ -1048,4 +1047,3 @@ The above implicitly extends to text files, since the :func:`open()` function will wrap a buffered object inside a :class:`TextIOWrapper`. This includes standard streams and therefore affects the built-in function :func:`print()` as well. - diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 3d4e5836cf2..b3a0a5f5192 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -827,7 +827,7 @@ which incur interpreter overhead. "List unique elements, preserving order. Remember only the element just seen." # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B # unique_justseen('ABBCcAD', str.lower) --> A B C A D - return map(next, map(itemgetter(1), groupby(iterable, key))) + return map(next, map(operator.itemgetter(1), groupby(iterable, key))) def iter_except(func, exception, first=None): """ Call a function repeatedly until an exception is raised. diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 589e86ca810..b476c372370 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -265,18 +265,21 @@ Basic Usage *fp* can now be a :term:`binary file`. The input encoding should be UTF-8, UTF-16 or UTF-32. -.. function:: loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) +.. function:: loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) Deserialize *s* (a :class:`str`, :class:`bytes` or :class:`bytearray` instance containing a JSON document) to a Python object using this :ref:`conversion table `. The other arguments have the same meaning as in :func:`load`, except - *encoding* which is ignored and deprecated. + *encoding* which is ignored and deprecated since Python 3.1. If the data being deserialized is not a valid JSON document, a :exc:`JSONDecodeError` will be raised. + .. deprecated-removed:: 3.1 3.9 + *encoding* keyword argument. + .. versionchanged:: 3.6 *s* can now be of type :class:`bytes` or :class:`bytearray`. The input encoding should be UTF-8, UTF-16 or UTF-32. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 5adde29f508..08555c3a357 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -1215,6 +1215,10 @@ functions. closing all handlers. This should be called at application exit and no further use of the logging system should be made after this call. + When the logging module is imported, it registers this function as an exit + handler (see :mod:`atexit`), so normally there's no need to do that + manually. + .. function:: setLoggerClass(klass) diff --git a/Doc/library/multiprocessing.shared_memory.rst b/Doc/library/multiprocessing.shared_memory.rst index 426fef62fa7..cba576a29e2 100644 --- a/Doc/library/multiprocessing.shared_memory.rst +++ b/Doc/library/multiprocessing.shared_memory.rst @@ -176,6 +176,7 @@ same ``numpy.ndarray`` from two distinct Python shells: .. class:: SharedMemoryManager([address[, authkey]]) + :module: multiprocessing.managers A subclass of :class:`~multiprocessing.managers.BaseManager` which can be used for the management of shared memory blocks across processes. @@ -218,8 +219,8 @@ The following example demonstrates the basic mechanisms of a .. doctest:: :options: +SKIP - >>> from multiprocessing import shared_memory - >>> smm = shared_memory.SharedMemoryManager() + >>> from multiprocessing.managers import SharedMemoryManager + >>> smm = SharedMemoryManager() >>> smm.start() # Start the process that manages the shared memory blocks >>> sl = smm.ShareableList(range(4)) >>> sl @@ -238,7 +239,7 @@ needed: .. doctest:: :options: +SKIP - >>> with shared_memory.SharedMemoryManager() as smm: + >>> with SharedMemoryManager() as smm: ... sl = smm.ShareableList(range(2000)) ... # Divide the work among two processes, storing partial results in sl ... p1 = Process(target=do_work, args=(sl, 0, 1000)) diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index 250cbb6b7c0..5d0ea7dfdd8 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -440,8 +440,8 @@ Python syntax and the functions in the :mod:`operator` module. | Ordering | ``a > b`` | ``gt(a, b)`` | +-----------------------+-------------------------+---------------------------------------+ -Inplace Operators ------------------ +In-place Operators +------------------ Many operations have an "in-place" version. Listed below are functions providing a more primitive access to in-place operators than the usual syntax @@ -464,7 +464,7 @@ value is computed, but not assigned back to the input variable: >>> a 'hello' -For mutable targets such as lists and dictionaries, the inplace method +For mutable targets such as lists and dictionaries, the in-place method will perform the update, so no subsequent assignment is necessary: >>> s = ['h', 'e', 'l', 'l', 'o'] diff --git a/Doc/library/os.rst b/Doc/library/os.rst index f8803af9520..e77a8fed377 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1453,16 +1453,19 @@ features: .. _path_fd: * **specifying a file descriptor:** - For some functions, the *path* argument can be not only a string giving a path - name, but also a file descriptor. The function will then operate on the file - referred to by the descriptor. (For POSIX systems, Python will call the - ``f...`` version of the function.) + Normally the *path* argument provided to functions in the :mod:`os` module + must be a string specifying a file path. However, some functions now + alternatively accept an open file descriptor for their *path* argument. + The function will then operate on the file referred to by the descriptor. + (For POSIX systems, Python will call the variant of the function prefixed + with ``f`` (e.g. call ``fchdir`` instead of ``chdir``).) - You can check whether or not *path* can be specified as a file descriptor on - your platform using :data:`os.supports_fd`. If it is unavailable, using it - will raise a :exc:`NotImplementedError`. + You can check whether or not *path* can be specified as a file descriptor + for a particular function on your platform using :data:`os.supports_fd`. + If this functionality is unavailable, using it will raise a + :exc:`NotImplementedError`. - If the function also supports *dir_fd* or *follow_symlinks* arguments, it is + If the function also supports *dir_fd* or *follow_symlinks* arguments, it's an error to specify one of those when supplying *path* as a file descriptor. .. _dir_fd: @@ -1471,23 +1474,24 @@ features: should be a file descriptor referring to a directory, and the path to operate on should be relative; path will then be relative to that directory. If the path is absolute, *dir_fd* is ignored. (For POSIX systems, Python will call - the ``...at`` or ``f...at`` version of the function.) + the variant of the function with an ``at`` suffix and possibly prefixed with + ``f`` (e.g. call ``faccessat`` instead of ``access``). - You can check whether or not *dir_fd* is supported on your platform using - :data:`os.supports_dir_fd`. If it is unavailable, using it will raise a - :exc:`NotImplementedError`. + You can check whether or not *dir_fd* is supported for a particular function + on your platform using :data:`os.supports_dir_fd`. If it's unavailable, + using it will raise a :exc:`NotImplementedError`. .. _follow_symlinks: * **not following symlinks:** If *follow_symlinks* is ``False``, and the last element of the path to operate on is a symbolic link, - the function will operate on the symbolic link itself instead of the file the - link points to. (For POSIX systems, Python will call the ``l...`` version of - the function.) + the function will operate on the symbolic link itself rather than the file + pointed to by the link. (For POSIX systems, Python will call the ``l...`` + variant of the function.) - You can check whether or not *follow_symlinks* is supported on your platform - using :data:`os.supports_follow_symlinks`. If it is unavailable, using it - will raise a :exc:`NotImplementedError`. + You can check whether or not *follow_symlinks* is supported for a particular + function on your platform using :data:`os.supports_follow_symlinks`. + If it's unavailable, using it will raise a :exc:`NotImplementedError`. @@ -1662,7 +1666,7 @@ features: .. availability:: Unix. .. versionadded:: 3.3 - Added support for specifying an open file descriptor for *path*, + Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. .. versionchanged:: 3.6 @@ -1781,7 +1785,7 @@ features: The *path* parameter became optional. .. versionadded:: 3.3 - Added support for specifying an open file descriptor for *path*. + Added support for specifying *path* as an open file descriptor. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2593,7 +2597,7 @@ features: The :const:`ST_RDONLY` and :const:`ST_NOSUID` constants were added. .. versionadded:: 3.3 - Added support for specifying an open file descriptor for *path*. + Added support for specifying *path* as an open file descriptor. .. versionchanged:: 3.4 The :const:`ST_NODEV`, :const:`ST_NOEXEC`, :const:`ST_SYNCHRONOUS`, @@ -2610,59 +2614,61 @@ features: .. data:: supports_dir_fd - A :class:`~collections.abc.Set` object indicating which functions in the - :mod:`os` module permit use of their *dir_fd* parameter. Different platforms - provide different functionality, and an option that might work on one might - be unsupported on another. For consistency's sakes, functions that support - *dir_fd* always allow specifying the parameter, but will raise an exception - if the functionality is not actually available. + A :class:`set` object indicating which functions in the :mod:`os` + module accept an open file descriptor for their *dir_fd* parameter. + Different platforms provide different features, and the underlying + functionality Python uses to implement the *dir_fd* parameter is not + available on all platforms Python supports. For consistency's sake, + functions that may support *dir_fd* always allow specifying the + parameter, but will throw an exception if the functionality is used + when it's not locally available. (Specifying ``None`` for *dir_fd* + is always supported on all platforms.) - To check whether a particular function permits use of its *dir_fd* - parameter, use the ``in`` operator on ``supports_dir_fd``. As an example, - this expression determines whether the *dir_fd* parameter of :func:`os.stat` - is locally available:: + To check whether a particular function accepts an open file descriptor + for its *dir_fd* parameter, use the ``in`` operator on ``supports_dir_fd``. + As an example, this expression evaluates to ``True`` if :func:`os.stat` + accepts open file descriptors for *dir_fd* on the local platform:: os.stat in os.supports_dir_fd - Currently *dir_fd* parameters only work on Unix platforms; none of them work - on Windows. + Currently *dir_fd* parameters only work on Unix platforms; + none of them work on Windows. .. versionadded:: 3.3 .. data:: supports_effective_ids - A :class:`~collections.abc.Set` object indicating which functions in the - :mod:`os` module permit use of the *effective_ids* parameter for - :func:`os.access`. If the local platform supports it, the collection will - contain :func:`os.access`, otherwise it will be empty. + A :class:`set` object indicating whether :func:`os.access` permits + specifying ``True`` for its *effective_ids* parameter on the local platform. + (Specifying ``False`` for *effective_ids* is always supported on all + platforms.) If the local platform supports it, the collection will contain + :func:`os.access`; otherwise it will be empty. - To check whether you can use the *effective_ids* parameter for - :func:`os.access`, use the ``in`` operator on ``supports_effective_ids``, - like so:: + This expression evaluates to ``True`` if :func:`os.access` supports + ``effective_ids=True`` on the local platform:: os.access in os.supports_effective_ids - Currently *effective_ids* only works on Unix platforms; it does not work on - Windows. + Currently *effective_ids* is only supported on Unix platforms; + it does not work on Windows. .. versionadded:: 3.3 .. data:: supports_fd - A :class:`~collections.abc.Set` object indicating which functions in the + A :class:`set` object indicating which functions in the :mod:`os` module permit specifying their *path* parameter as an open file - descriptor. Different platforms provide different functionality, and an - option that might work on one might be unsupported on another. For - consistency's sakes, functions that support *fd* always allow specifying - the parameter, but will raise an exception if the functionality is not - actually available. + descriptor on the local platform. Different platforms provide different + features, and the underlying functionality Python uses to accept open file + descriptors as *path* arguments is not available on all platforms Python + supports. - To check whether a particular function permits specifying an open file + To determine whether a particular function permits specifying an open file descriptor for its *path* parameter, use the ``in`` operator on - ``supports_fd``. As an example, this expression determines whether - :func:`os.chdir` accepts open file descriptors when called on your local + ``supports_fd``. As an example, this expression evaluates to ``True`` if + :func:`os.chdir` accepts open file descriptors for *path* on your local platform:: os.chdir in os.supports_fd @@ -2672,17 +2678,21 @@ features: .. data:: supports_follow_symlinks - A :class:`~collections.abc.Set` object indicating which functions in the - :mod:`os` module permit use of their *follow_symlinks* parameter. Different - platforms provide different functionality, and an option that might work on - one might be unsupported on another. For consistency's sakes, functions that - support *follow_symlinks* always allow specifying the parameter, but will - raise an exception if the functionality is not actually available. + A :class:`set` object indicating which functions in the :mod:`os` module + accept ``False`` for their *follow_symlinks* parameter on the local platform. + Different platforms provide different features, and the underlying + functionality Python uses to implement *follow_symlinks* is not available + on all platforms Python supports. For consistency's sake, functions that + may support *follow_symlinks* always allow specifying the parameter, but + will throw an exception if the functionality is used when it's not locally + available. (Specifying ``True`` for *follow_symlinks* is always supported + on all platforms.) - To check whether a particular function permits use of its *follow_symlinks* - parameter, use the ``in`` operator on ``supports_follow_symlinks``. As an - example, this expression determines whether the *follow_symlinks* parameter - of :func:`os.stat` is locally available:: + To check whether a particular function accepts ``False`` for its + *follow_symlinks* parameter, use the ``in`` operator on + ``supports_follow_symlinks``. As an example, this expression evaluates + to ``True`` if you may specify ``follow_symlinks=False`` when calling + :func:`os.stat` on the local platform:: os.stat in os.supports_follow_symlinks @@ -2699,19 +2709,15 @@ features: as a directory if *target_is_directory* is ``True`` or a file symlink (the default) otherwise. On non-Windows platforms, *target_is_directory* is ignored. - Symbolic link support was introduced in Windows 6.0 (Vista). :func:`symlink` - will raise a :exc:`NotImplementedError` on Windows versions earlier than 6.0. - This function can support :ref:`paths relative to directory descriptors `. .. note:: - On Windows, the *SeCreateSymbolicLinkPrivilege* is required in order to - successfully create symlinks. This privilege is not typically granted to - regular users but is available to accounts which can escalate privileges - to the administrator level. Either obtaining the privilege or running your - application as an administrator are ways to successfully create symlinks. + On newer versions of Windows 10, unprivileged accounts can create symlinks + if Developer Mode is enabled. When Developer Mode is not available/enabled, + the *SeCreateSymbolicLinkPrivilege* privilege is required, or the process + must be run as an administrator. :exc:`OSError` is raised when the function is called by an unprivileged @@ -2729,6 +2735,9 @@ features: .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *src* and *dst*. + .. versionchanged:: 3.8 + Added support for unelevated symlinks on Windows with Developer Mode. + .. function:: sync() @@ -2802,7 +2811,7 @@ features: following symlinks `. .. versionadded:: 3.3 - Added support for specifying an open file descriptor for *path*, + Added support for specifying *path* as an open file descriptor, and the *dir_fd*, *follow_symlinks*, and *ns* parameters. .. versionchanged:: 3.6 @@ -3079,6 +3088,36 @@ to be ignored. :func:`signal.signal`. +.. function:: add_dll_directory(path) + + Add a path to the DLL search path. + + This search path is used when resolving dependencies for imported + extension modules (the module itself is resolved through sys.path), + and also by :mod:`ctypes`. + + Remove the directory by calling **close()** on the returned object + or using it in a :keyword:`with` statement. + + See the `Microsoft documentation + `_ + for more information about how DLLs are loaded. + + .. availability:: Windows. + + .. versionadded:: 3.8 + Previous versions of CPython would resolve DLLs using the default + behavior for the current process. This led to inconsistencies, + such as only sometimes searching :envvar:`PATH` or the current + working directory, and OS functions such as ``AddDllDirectory`` + having no effect. + + In 3.8, the two primary ways DLLs are loaded now explicitly + override the process-wide behavior to ensure consistency. See the + :ref:`porting notes ` for information on + updating libraries. + + .. function:: execl(path, arg0, arg1, ...) execle(path, arg0, arg1, ..., env) execlp(file, arg0, arg1, ...) @@ -3133,7 +3172,7 @@ to be ignored. .. availability:: Unix, Windows. .. versionadded:: 3.3 - Added support for specifying an open file descriptor for *path* + Added support for specifying *path* as an open file descriptor for :func:`execve`. .. versionchanged:: 3.6 diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 450e8ff378a..7a4a20dc611 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1054,6 +1054,13 @@ call fails (for example because the path doesn't exist). use :func:`Path.rmdir` instead. +.. method:: Path.link_to(target) + + Create a hard link pointing to a path named *target*. + + .. versionchanged:: 3.8 + + .. method:: Path.write_bytes(data) Open the file pointed to in bytes mode, write *data* to it, and close the diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index 60c6089ad3c..e07f9d613a0 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -216,6 +216,21 @@ Windows Platform later (support for this was added in Python 2.6). It obviously only runs on Win32 compatible platforms. +.. function:: win32_edition() + + Returns a string representing the current Windows edition. Possible + values include but are not limited to ``'Enterprise'``, ``'IoTUAP'``, + ``'ServerStandard'``, and ``'nanoserver'``. + + .. versionadded:: 3.8 + +.. function:: win32_is_iot() + + Returns True if the windows edition returned by win32_edition is recognized + as an IoT edition. + + .. versionadded:: 3.8 + Mac OS Platform --------------- diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index a70c8df6a7b..b80a2faed9b 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -44,7 +44,7 @@ modules. .. versionadded:: 3.7 Descriptors for nested definitions. They are accessed through the - new children attibute. Each has a new parent attribute. + new children attribute. Each has a new parent attribute. The descriptors returned by these functions are instances of Function and Class classes. Users are not expected to create instances diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index f99f6ffb05f..2eeab5e2626 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -150,6 +150,11 @@ provide the public methods described below. Otherwise (*block* is false), return an item if one is immediately available, else raise the :exc:`Empty` exception (*timeout* is ignored in that case). + Prior to 3.0 on POSIX systems, and for all versions on Windows, if + *block* is true and *timeout* is ``None``, this operation goes into + an uninterruptible wait on an underlying lock. This means that no exceptions + can occur, and in particular a SIGINT will not trigger a :exc:`KeyboardInterrupt`. + .. method:: Queue.get_nowait() diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 79a7bddad49..fcedba4dbc2 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -310,6 +310,11 @@ be found in any statistics text. Alternative Generator --------------------- +.. class:: Random([seed]) + + Class that implements the default pseudo-random number generator used by the + :mod:`random` module. + .. class:: SystemRandom([seed]) Class that uses the :func:`os.urandom` function for generating random numbers diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 4ac5dee1407..5ef72b535ce 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -908,6 +908,7 @@ form. Unknown escapes in *repl* consisting of ``'\'`` and an ASCII letter now are errors. + .. versionchanged:: 3.7 Empty matches for the pattern are replaced when adjacent to a previous non-empty match. diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 2ed15c13673..3573da7ea2d 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -76,6 +76,8 @@ this module for those platforms. ``setrlimit`` may also raise :exc:`error` if the underlying system call fails. + VxWorks only supports setting :data:`RLIMIT_NOFILE`. + .. function:: prlimit(pid, resource[, limits]) Combines :func:`setrlimit` and :func:`getrlimit` in one function and diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 587be3befa0..2dc872fd077 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -559,6 +559,10 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. The *verbose* argument is unused and deprecated. + .. versionchanged:: 3.8 + The modern pax (POSIX.1-2001) format is now used instead of + the legacy GNU format for archives created with ``format="tar"``. + .. function:: get_archive_formats() @@ -568,7 +572,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. By default :mod:`shutil` provides these formats: - *zip*: ZIP file (if the :mod:`zlib` module is available). - - *tar*: uncompressed tar file. + - *tar*: Uncompressed tar file. Uses POSIX.1-2001 pax format for new archives. - *gztar*: gzip'ed tar-file (if the :mod:`zlib` module is available). - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available). - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available). diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index ac6cad9aff8..01200b4df88 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -16,7 +16,8 @@ The :func:`signal.signal` function allows defining custom handlers to be executed when a signal is received. A small number of default handlers are installed: :const:`SIGPIPE` is ignored (so write errors on pipes and sockets can be reported as ordinary Python exceptions) and :const:`SIGINT` is -translated into a :exc:`KeyboardInterrupt` exception. +translated into a :exc:`KeyboardInterrupt` exception if the parent process +has not changed it. A handler for a particular signal, once set, remains installed until it is explicitly reset (Python emulates the BSD style interface regardless of the diff --git a/Doc/library/site.rst b/Doc/library/site.rst index 7974e20974f..dfc40d17944 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -45,9 +45,9 @@ sys.prefix and sys.exec_prefix are set to that directory and it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains -the key "include-system-site-packages" set to anything other than "false" -(case-insensitive), the system-level prefixes will still also be -searched for site-packages; otherwise they won't. +the key "include-system-site-packages" set to anything other than "true" +(case-insensitive), the system-level prefixes will not be +searched for site-packages; otherwise they will. .. index:: single: # (hash); comment diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index d466884d613..379633a3b60 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -595,6 +595,50 @@ The following functions all create :ref:`socket objects `. .. versionchanged:: 3.2 *source_address* was added. +.. function:: create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, dualstack_ipv6=False) + + Convenience function which creates a TCP socket bound to *address* (a 2-tuple + ``(host, port)``) and return the socket object. + + *family* should be either :data:`AF_INET` or :data:`AF_INET6`. + *backlog* is the queue size passed to :meth:`socket.listen`; when ``0`` + a default reasonable value is chosen. + *reuse_port* dictates whether to set the :data:`SO_REUSEPORT` socket option. + + If *dualstack_ipv6* is true and the platform supports it the socket will + be able to accept both IPv4 and IPv6 connections, else it will raise + :exc:`ValueError`. Most POSIX platforms and Windows are supposed to support + this functionality. + When this functionality is enabled the address returned by + :meth:`socket.getpeername` when an IPv4 connection occurs will be an IPv6 + address represented as an IPv4-mapped IPv6 address. + If *dualstack_ipv6* is false it will explicitly disable this functionality + on platforms that enable it by default (e.g. Linux). + This parameter can be used in conjunction with :func:`has_dualstack_ipv6`: + + :: + + import socket + + addr = ("", 8080) # all interfaces, port 8080 + if socket.has_dualstack_ipv6(): + s = socket.create_server(addr, family=socket.AF_INET6, dualstack_ipv6=True) + else: + s = socket.create_server(addr) + + .. note:: + On POSIX platforms the :data:`SO_REUSEADDR` socket option is set in order to + immediately reuse previous sockets which were bound on the same *address* + and remained in TIME_WAIT state. + + .. versionadded:: 3.8 + +.. function:: has_dualstack_ipv6() + + Return ``True`` if the platform supports creating a TCP socket which can + handle both IPv4 and IPv6 connections. + + .. versionadded:: 3.8 .. function:: fromfd(fd, family, type, proto=0) @@ -752,6 +796,8 @@ The :mod:`socket` module also offers various network-related services: For IPv6 addresses, ``%scope`` is appended to the host part if *sockaddr* contains meaningful *scopeid*. Usually this happens for multicast addresses. + For more information about *flags* you can consult :manpage:`getnameinfo(3)`. + .. function:: getprotobyname(protocolname) Translate an Internet protocol name (for example, ``'icmp'``) to a constant @@ -1778,7 +1824,6 @@ sends traffic to the first one connected successfully. :: data = s.recv(1024) print('Received', repr(data)) - The next example shows how to write a very simple network sniffer with raw sockets on Windows. The example requires administrator privileges to modify the interface:: diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 6a441983f88..20f57244471 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -665,7 +665,7 @@ Constants .. data:: PROTOCOL_SSLv23 - Alias for data:`PROTOCOL_TLS`. + Alias for :data:`PROTOCOL_TLS`. .. deprecated:: 3.6 @@ -1821,7 +1821,7 @@ to speed up repeated connections from the same clients. .. attribute:: SSLContext.sslsocket_class - The return type of :meth:`SSLContext.wrap_sockets`, defaults to + The return type of :meth:`SSLContext.wrap_socket`, defaults to :class:`SSLSocket`. The attribute can be overridden on instance of class in order to return a custom subclass of :class:`SSLSocket`. @@ -1831,7 +1831,7 @@ to speed up repeated connections from the same clients. server_hostname=None, session=None) Wrap the BIO objects *incoming* and *outgoing* and return an instance of - attr:`SSLContext.sslobject_class` (default :class:`SSLObject`). The SSL + :attr:`SSLContext.sslobject_class` (default :class:`SSLObject`). The SSL routines will read input data from the incoming BIO and write data to the outgoing BIO. diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 1d52d98b299..fb7df4e7188 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -40,6 +40,7 @@ or sample. ======================= =============================================================== :func:`mean` Arithmetic mean ("average") of data. :func:`fmean` Fast, floating point arithmetic mean. +:func:`geometric_mean` Geometric mean of data. :func:`harmonic_mean` Harmonic mean of data. :func:`median` Median (middle value) of data. :func:`median_low` Low median of data. @@ -47,6 +48,7 @@ or sample. :func:`median_grouped` Median, or 50th percentile, of grouped data. :func:`mode` Single mode (most common value) of discrete or nominal data. :func:`multimode` List of modes (most common values) of discrete or nomimal data. +:func:`quantiles` Divide data into intervals with equal probability. ======================= =============================================================== Measures of spread @@ -130,6 +132,24 @@ However, for reading convenience, most of the examples show sorted sequences. .. versionadded:: 3.8 +.. function:: geometric_mean(data) + + Convert *data* to floats and compute the geometric mean. + + Raises a :exc:`StatisticsError` if the input dataset is empty, + if it contains a zero, or if it contains a negative value. + + No special efforts are made to achieve exact results. + (However, this may change in the future.) + + .. doctest:: + + >>> round(geometric_mean([54, 24, 36]), 9) + 36.0 + + .. versionadded:: 3.8 + + .. function:: harmonic_mean(data) Return the harmonic mean of *data*, a sequence or iterator of @@ -480,6 +500,53 @@ However, for reading convenience, most of the examples show sorted sequences. :func:`pvariance` function as the *mu* parameter to get the variance of a sample. +.. function:: quantiles(dist, *, n=4, method='exclusive') + + Divide *dist* into *n* continuous intervals with equal probability. + Returns a list of ``n - 1`` cut points separating the intervals. + + Set *n* to 4 for quartiles (the default). Set *n* to 10 for deciles. Set + *n* to 100 for percentiles which gives the 99 cuts points that separate + *dist* in to 100 equal sized groups. Raises :exc:`StatisticsError` if *n* + is not least 1. + + The *dist* can be any iterable containing sample data or it can be an + instance of a class that defines an :meth:`~inv_cdf` method. + Raises :exc:`StatisticsError` if there are not at least two data points. + + For sample data, the cut points are linearly interpolated from the + two nearest data points. For example, if a cut point falls one-third + of the distance between two sample values, ``100`` and ``112``, the + cut-point will evaluate to ``104``. Other selection methods may be + offered in the future (for example choose ``100`` as the nearest + value or compute ``106`` as the midpoint). This might matter if + there are too few samples for a given number of cut points. + + If *method* is set to *inclusive*, *dist* is treated as population data. + The minimum value is treated as the 0th percentile and the maximum + value is treated as the 100th percentile. If *dist* is an instance of + a class that defines an :meth:`~inv_cdf` method, setting *method* + has no effect. + + .. doctest:: + + # Decile cut points for empirically sampled data + >>> data = [105, 129, 87, 86, 111, 111, 89, 81, 108, 92, 110, + ... 100, 75, 105, 103, 109, 76, 119, 99, 91, 103, 129, + ... 106, 101, 84, 111, 74, 87, 86, 103, 103, 106, 86, + ... 111, 75, 87, 102, 121, 111, 88, 89, 101, 106, 95, + ... 103, 107, 101, 81, 109, 104] + >>> [round(q, 1) for q in quantiles(data, n=10)] + [81.0, 86.2, 89.0, 99.4, 102.5, 103.6, 106.0, 109.8, 111.0] + + >>> # Quartile cut points for the standard normal distibution + >>> Z = NormalDist() + >>> [round(q, 4) for q in quantiles(Z, n=4)] + [-0.6745, 0.0, 0.6745] + + .. versionadded:: 3.8 + + Exceptions ---------- @@ -540,7 +607,7 @@ of applications in statistics. :exc:`StatisticsError` because it takes at least one point to estimate a central value and at least two points to estimate dispersion. - .. method:: NormalDist.samples(n, seed=None) + .. method:: NormalDist.samples(n, *, seed=None) Generates *n* random samples for a given mean and standard deviation. Returns a :class:`list` of :class:`float` values. @@ -587,7 +654,7 @@ of applications in statistics. `_ between two normal distributions, giving a measure of agreement. Returns a value between 0.0 and 1.0 giving `the overlapping area for - two probability density functions + the two probability density functions `_. Instances of :class:`NormalDist` support addition, subtraction, @@ -630,8 +697,8 @@ of applications in statistics. For example, given `historical data for SAT exams `_ showing that scores are normally distributed with a mean of 1060 and a standard deviation of 192, -determine the percentage of students with scores between 1100 and 1200, after -rounding to the nearest whole number: +determine the percentage of students with test scores between 1100 and +1200, after rounding to the nearest whole number: .. doctest:: diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 66915a7c560..0a6bb149075 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1509,6 +1509,10 @@ expression support in the :mod:`re` module). Return a copy of the string with its first character capitalized and the rest lowercased. + .. versionchanged:: 3.8 + The first character is now put into titlecase rather than uppercase. + This means that characters like digraphs will only have their first + letter capitalized, instead of the full character. .. method:: str.casefold() @@ -2052,8 +2056,7 @@ expression support in the :mod:`re` module). >>> import re >>> def titlecase(s): ... return re.sub(r"[A-Za-z]+('[A-Za-z]+)?", - ... lambda mo: mo.group(0)[0].upper() + - ... mo.group(0)[1:].lower(), + ... lambda mo: mo.group(0).capitalize(), ... s) ... >>> titlecase("they're bill's friends.") @@ -2696,8 +2699,8 @@ arbitrary binary data. containing the part before the separator, the separator itself or its bytearray copy, and the part after the separator. If the separator is not found, return a 3-tuple - containing a copy of the original sequence, followed by two empty bytes or - bytearray objects. + containing two empty bytes or bytearray objects, followed by a copy of the + original sequence. The separator to search for may be any :term:`bytes-like object`. @@ -4251,7 +4254,10 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: Create a new dictionary with keys from *iterable* and values set to *value*. :meth:`fromkeys` is a class method that returns a new dictionary. *value* - defaults to ``None``. + defaults to ``None``. All of the values refer to just a single instance, + so it generally doesn't make sense for *value* to be a mutable object + such as an empty list. To get distinct values, use a :ref:`dict + comprehension ` instead. .. method:: get(key[, default]) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index ca0813c7830..3280c95cacb 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -567,6 +567,13 @@ functions. Popen destructor now emits a :exc:`ResourceWarning` warning if the child process is still running. + .. versionchanged:: 3.8 + Popen can use :func:`os.posix_spawn` in some cases for better + performance. On Windows Subsystem for Linux and QEMU User Emulation, + Popen constructor using :func:`os.posix_spawn` no longer raise an + exception on errors like missing program, but the child process fails + with a non-zero :attr:`~Popen.returncode`. + Exceptions ^^^^^^^^^^ diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 0fa5bd46229..591972e9b78 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -30,6 +30,12 @@ always available. To loop over the standard input, or the list of files given on the command line, see the :mod:`fileinput` module. + .. note:: + On Unix, command line arguments are passed by bytes from OS. Python decodes + them with filesystem encoding and "surrogateescape" error handler. + When you need original bytes, you can get it by + ``[os.fsencode(arg) for arg in sys.argv]``. + .. data:: base_exec_prefix @@ -1008,7 +1014,7 @@ always available. This string contains a platform identifier that can be used to append platform-specific components to :data:`sys.path`, for instance. - For Unix systems, except on Linux, this is the lowercased OS name as + For Unix systems, except on Linux and AIX, this is the lowercased OS name as returned by ``uname -s`` with the first part of the version as returned by ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, *at the time when Python was built*. Unless you want to test for a specific system @@ -1018,12 +1024,15 @@ always available. # FreeBSD-specific code here... elif sys.platform.startswith('linux'): # Linux-specific code here... + elif sys.platform.startswith('aix'): + # AIX-specific code here... For other systems, the values are: ================ =========================== System ``platform`` value ================ =========================== + AIX ``'aix'`` Linux ``'linux'`` Windows ``'win32'`` Windows/Cygwin ``'cygwin'`` @@ -1036,6 +1045,12 @@ always available. older Python versions include the version number, it is recommended to always use the ``startswith`` idiom presented above. + .. versionchanged:: 3.8 + On AIX, :attr:`sys.platform` doesn't contain the major version anymore. + It is always ``'aix'``, instead of ``'aix5'`` or ``'aix7'``. Since + older Python versions include the version number, it is recommended to + always use the ``startswith`` idiom presented above. + .. seealso:: :attr:`os.name` has a coarser granularity. :func:`os.uname` gives diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index c7012a7d48f..f25af8ca6a3 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -231,9 +231,9 @@ details. The default format for creating archives. This is currently :const:`PAX_FORMAT`. - .. versionchanged:: 3.8 - The default format for new archives was changed to - :const:`PAX_FORMAT` from :const:`GNU_FORMAT`. + .. versionchanged:: 3.8 + The default format for new archives was changed to + :const:`PAX_FORMAT` from :const:`GNU_FORMAT`. .. seealso:: @@ -813,8 +813,8 @@ Supported tar formats There are three tar formats that can be created with the :mod:`tarfile` module: * The POSIX.1-1988 ustar format (:const:`USTAR_FORMAT`). It supports filenames - up to a length of at best 256 characters and linknames up to 100 characters. The - maximum file size is 8 GiB. This is an old and limited but widely + up to a length of at best 256 characters and linknames up to 100 characters. + The maximum file size is 8 GiB. This is an old and limited but widely supported format. * The GNU tar format (:const:`GNU_FORMAT`). It supports long filenames and @@ -826,14 +826,15 @@ There are three tar formats that can be created with the :mod:`tarfile` module: format with virtually no limits. It supports long filenames and linknames, large files and stores pathnames in a portable way. Modern tar implementations, including GNU tar, bsdtar/libarchive and star, fully support extended *pax* - features; some older or unmaintained libraries may not, but should treat + features; some old or unmaintained libraries may not, but should treat *pax* archives as if they were in the universally-supported *ustar* format. + It is the current default format for new archives. - The *pax* format is an extension to the existing *ustar* format. It uses extra - headers for information that cannot be stored otherwise. There are two flavours - of pax headers: Extended headers only affect the subsequent file header, global - headers are valid for the complete archive and affect all following files. All - the data in a pax header is encoded in *UTF-8* for portability reasons. + It extends the existing *ustar* format with extra headers for information + that cannot be stored otherwise. There are two flavours of pax headers: + Extended headers only affect the subsequent file header, global + headers are valid for the complete archive and affect all following files. + All the data in a pax header is encoded in *UTF-8* for portability reasons. There are some more variants of the tar format which can be read, but not created: diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index d7dbcb107dd..c58a6ad75d0 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -250,7 +250,7 @@ since it is impossible to detect the termination of alien threads. You may override this method in a subclass. The standard :meth:`run` method invokes the callable object passed to the object's constructor as - the *target* argument, if any, with sequential and keyword arguments taken + the *target* argument, if any, with positional and keyword arguments taken from the *args* and *kwargs* arguments, respectively. .. method:: join(timeout=None) diff --git a/Doc/library/time.rst b/Doc/library/time.rst index baf92c1400e..170f8dc629b 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -153,6 +153,8 @@ Functions :c:func:`QueryPerformanceCounter`. The resolution is typically better than one microsecond. + .. availability:: Windows, Unix. Not available on VxWorks. + .. deprecated:: 3.3 The behaviour of this function depends on the platform: use :func:`perf_counter` or :func:`process_time` instead, depending on your diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index fad9dc69431..c2523ed5296 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -951,6 +951,24 @@ The module defines the following classes, functions and decorators: This wraps the decorator with something that wraps the decorated function in :func:`no_type_check`. +.. decorator:: type_check_only + + Decorator to mark a class or function to be unavailable at runtime. + + This decorator is itself not available at runtime. It is mainly + intended to mark classes that are defined in type stub files if + an implementation returns an instance of a private class:: + + @type_check_only + class Response: # private or not available at runtime + code: int + def get_header(self, name: str) -> str: ... + + def fetch_response() -> Response: ... + + Note that returning instances of private classes is not recommended. + It is usually preferable to make such classes public. + .. data:: Any Special type indicating an unconstrained type. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index d1b4f3ba0bb..8ad2abd3d89 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1000,7 +1000,7 @@ Test cases int('XYZ') .. versionadded:: 3.1 - under the name ``assertRaisesRegexp``. + Added under the name ``assertRaisesRegexp``. .. versionchanged:: 3.2 Renamed to :meth:`assertRaisesRegex`. @@ -1145,7 +1145,7 @@ Test cases +---------------------------------------+--------------------------------+--------------+ | :meth:`assertCountEqual(a, b) | *a* and *b* have the same | 3.2 | | ` | elements in the same number, | | - | | regardless of their order | | + | | regardless of their order. | | +---------------------------------------+--------------------------------+--------------+ @@ -1193,7 +1193,7 @@ Test cases expression suitable for use by :func:`re.search`. .. versionadded:: 3.1 - under the name ``assertRegexpMatches``. + Added under the name ``assertRegexpMatches``. .. versionchanged:: 3.2 The method ``assertRegexpMatches()`` has been renamed to :meth:`.assertRegex`. @@ -1516,14 +1516,14 @@ along with their deprecated aliases: ============================== ====================== ======================= .. deprecated:: 3.1 - the fail* aliases listed in the second column. + The fail* aliases listed in the second column have been deprecated. .. deprecated:: 3.2 - the assert* aliases listed in the third column. + The assert* aliases listed in the third column have been deprecated. .. deprecated:: 3.2 ``assertRegexpMatches`` and ``assertRaisesRegexp`` have been renamed to :meth:`.assertRegex` and :meth:`.assertRaisesRegex`. .. deprecated:: 3.5 - the ``assertNotRegexpMatches`` name in favor of :meth:`.assertNotRegex`. + The ``assertNotRegexpMatches`` name is deprecated in favor of :meth:`.assertNotRegex`. .. _testsuite-objects: diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 289bfcaebc3..14fa27bb08a 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -192,8 +192,8 @@ The following classes are provided: *data* must be an object specifying additional data to send to the server, or ``None`` if no such data is needed. Currently HTTP requests are the only ones that use *data*. The supported object - types include bytes, file-like objects, and iterables. If no - ``Content-Length`` nor ``Transfer-Encoding`` header field + types include bytes, file-like objects, and iterables of bytes-like objects. + If no ``Content-Length`` nor ``Transfer-Encoding`` header field has been provided, :class:`HTTPHandler` will set these headers according to the type of *data*. ``Content-Length`` will be used to send bytes objects, while ``Transfer-Encoding: chunked`` as specified in @@ -1435,6 +1435,7 @@ some point in the future. The *data* argument has the same meaning as the *data* argument of :func:`urlopen`. + This method always quotes *fullurl* using :func:`~urllib.parse.quote`. .. method:: open_unknown(fullurl, data=None) diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 412808ad448..4f083a3181e 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -234,14 +234,19 @@ creation according to their needs, the :class:`EnvBuilder` class. There is also a module-level convenience function: .. function:: create(env_dir, system_site_packages=False, clear=False, \ - symlinks=False, with_pip=False) + symlinks=False, with_pip=False, prompt=None) Create an :class:`EnvBuilder` with the given keyword arguments, and call its :meth:`~EnvBuilder.create` method with the *env_dir* argument. + .. versionadded:: 3.3 + .. versionchanged:: 3.4 Added the ``with_pip`` parameter + .. versionchanged:: 3.6 + Added the ``prompt`` parameter + An example of extending ``EnvBuilder`` -------------------------------------- diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index b04bd79e4bb..d121f320d6a 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -109,11 +109,11 @@ The following warnings category classes are currently defined: +----------------------------------+-----------------------------------------------+ .. versionchanged:: 3.7 - Previously :exc:`DeprecationWarning` and :exc:`FutureWarning` were - distinguished based on whether a feature was being removed entirely or - changing its behaviour. They are now distinguished based on their - intended audience and the way they're handled by the default warnings - filters. + Previously :exc:`DeprecationWarning` and :exc:`FutureWarning` were + distinguished based on whether a feature was being removed entirely or + changing its behaviour. They are now distinguished based on their + intended audience and the way they're handled by the default warnings + filters. .. _warning-filter: diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 40bb06adfd4..80a908bbd83 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -139,6 +139,10 @@ Extension types can easily be made to support weak references; see prevent their use as dictionary keys. *callback* is the same as the parameter of the same name to the :func:`ref` function. + .. versionchanged:: 3.8 + Extended the operator support on proxy objects to include the matrix + multiplication operators ``@`` and ``@=``. + .. function:: getweakrefcount(object) @@ -489,11 +493,14 @@ Unless you set the :attr:`~finalize.atexit` attribute to :const:`False`, a finalizer will be called when the program exits if it is still alive. For instance - >>> obj = Object() - >>> weakref.finalize(obj, print, "obj dead or exiting") #doctest:+ELLIPSIS - - >>> exit() #doctest:+SKIP - obj dead or exiting +.. doctest:: + :options: +SKIP + + >>> obj = Object() + >>> weakref.finalize(obj, print, "obj dead or exiting") + + >>> exit() + obj dead or exiting Comparing finalizers with :meth:`__del__` methods diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index ffca1fc8168..6edd0714b9d 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -767,7 +767,7 @@ This is a working "Hello World" WSGI application:: # use a function (note that you're not limited to a function, you can # use a class for example). The first argument passed to the function # is a dictionary containing CGI-style environment variables and the - # second variable is the callable object (see PEP 333). + # second variable is the callable object. def hello_world_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers @@ -781,3 +781,9 @@ This is a working "Hello World" WSGI application:: # Serve until process is killed httpd.serve_forever() + + +Example of a WSGI application serving the current directory, accept optional +directory and port number (default: 8000) on the command line: + +.. literalinclude:: ../../Tools/scripts/serve.py diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index af09ea98c81..2423a0c1569 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -238,22 +238,8 @@ The following interfaces have no implementation in :mod:`xml.dom.minidom`: * :class:`DOMTimeStamp` -* :class:`DocumentType` - -* :class:`DOMImplementation` - -* :class:`CharacterData` - -* :class:`CDATASection` - -* :class:`Notation` - -* :class:`Entity` - * :class:`EntityReference` -* :class:`DocumentFragment` - Most of these reflect information in the XML document that is not of general utility to most DOM users. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 4a7cf6f0958..c4667315793 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -399,6 +399,12 @@ module. We'll be using the ``countrydata`` XML document from the # All 'neighbor' nodes that are the second child of their parent root.findall(".//neighbor[2]") +For XML with namespaces, use the usual qualified ``{namespace}tag`` notation:: + + # All dublin-core "title" tags in the document + root.findall(".//{http://purl.org/dc/elements/1.1/}title") + + Supported XPath syntax ^^^^^^^^^^^^^^^^^^^^^^ @@ -411,9 +417,16 @@ Supported XPath syntax | | For example, ``spam`` selects all child elements | | | named ``spam``, and ``spam/egg`` selects all | | | grandchildren named ``egg`` in all children named | -| | ``spam``. | +| | ``spam``. ``{namespace}*`` selects all tags in the | +| | given namespace, ``{*}spam`` selects tags named | +| | ``spam`` in any (or no) namespace, and ``{}*`` | +| | only selects tags that are not in a namespace. | +| | | +| | .. versionchanged:: 3.8 | +| | Support for star-wildcards was added. | +-----------------------+------------------------------------------------------+ -| ``*`` | Selects all child elements. For example, ``*/egg`` | +| ``*`` | Selects all child elements, including comments and | +| | processing instructions. For example, ``*/egg`` | | | selects all grandchildren named ``egg``. | +-----------------------+------------------------------------------------------+ | ``.`` | Selects the current node. This is mostly useful | @@ -465,6 +478,53 @@ Reference Functions ^^^^^^^^^ +.. function:: canonicalize(xml_data=None, *, out=None, from_file=None, **options) + + `C14N 2.0 `_ transformation function. + + Canonicalization is a way to normalise XML output in a way that allows + byte-by-byte comparisons and digital signatures. It reduced the freedom + that XML serializers have and instead generates a more constrained XML + representation. The main restrictions regard the placement of namespace + declarations, the ordering of attributes, and ignorable whitespace. + + This function takes an XML data string (*xml_data*) or a file path or + file-like object (*from_file*) as input, converts it to the canonical + form, and writes it out using the *out* file(-like) object, if provided, + or returns it as a text string if not. The output file receives text, + not bytes. It should therefore be opened in text mode with ``utf-8`` + encoding. + + Typical uses:: + + xml_data = "..." + print(canonicalize(xml_data)) + + with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: + canonicalize(xml_data, out=out_file) + + with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: + canonicalize(from_file="inputfile.xml", out=out_file) + + The configuration *options* are as follows: + + - *with_comments*: set to true to include comments (default: false) + - *strip_text*: set to true to strip whitespace before and after text content + (default: false) + - *rewrite_prefixes*: set to true to replace namespace prefixes by "n{number}" + (default: false) + - *qname_aware_tags*: a set of qname aware tag names in which prefixes + should be replaced in text content (default: empty) + - *qname_aware_attrs*: a set of qname aware attribute names in which prefixes + should be replaced in text content (default: empty) + - *exclude_attrs*: a set of attribute names that should not be serialised + - *exclude_tags*: a set of tag names that should not be serialised + + In the option list above, "a set" refers to any collection or iterable of + strings, no ordering is expected. + + .. versionadded:: 3.8 + .. function:: Comment(text=None) @@ -523,8 +583,9 @@ Functions Parses an XML section into an element tree incrementally, and reports what's going on to the user. *source* is a filename or :term:`file object` containing XML data. *events* is a sequence of events to report back. The - supported events are the strings ``"start"``, ``"end"``, ``"start-ns"`` and - ``"end-ns"`` (the "ns" events are used to get detailed namespace + supported events are the strings ``"start"``, ``"end"``, ``"comment"``, + ``"pi"``, ``"start-ns"`` and ``"end-ns"`` + (the "ns" events are used to get detailed namespace information). If *events* is omitted, only ``"end"`` events are reported. *parser* is an optional parser instance. If not given, the standard :class:`XMLParser` parser is used. *parser* must be a subclass of @@ -549,6 +610,10 @@ Functions .. deprecated:: 3.4 The *parser* argument. + .. versionchanged:: 3.8 + The ``comment`` and ``pi`` events were added. + + .. function:: parse(source, parser=None) Parses an XML section into an element tree. *source* is a filename or file @@ -594,6 +659,7 @@ Functions .. function:: tostring(element, encoding="us-ascii", method="xml", *, \ + xml_declaration=None, default_namespace=None, short_empty_elements=True) Generates a string representation of an XML element, including all @@ -601,14 +667,19 @@ Functions the output encoding (default is US-ASCII). Use ``encoding="unicode"`` to generate a Unicode string (otherwise, a bytestring is generated). *method* is either ``"xml"``, ``"html"`` or ``"text"`` (default is ``"xml"``). - *short_empty_elements* has the same meaning as in :meth:`ElementTree.write`. - Returns an (optionally) encoded string containing the XML data. + *xml_declaration*, *default_namespace* and *short_empty_elements* has the same + meaning as in :meth:`ElementTree.write`. Returns an (optionally) encoded string + containing the XML data. .. versionadded:: 3.4 The *short_empty_elements* parameter. + .. versionadded:: 3.8 + The *xml_declaration* and *default_namespace* parameters. + .. function:: tostringlist(element, encoding="us-ascii", method="xml", *, \ + xml_declaration=None, default_namespace=None, short_empty_elements=True) Generates a string representation of an XML element, including all @@ -616,16 +687,19 @@ Functions the output encoding (default is US-ASCII). Use ``encoding="unicode"`` to generate a Unicode string (otherwise, a bytestring is generated). *method* is either ``"xml"``, ``"html"`` or ``"text"`` (default is ``"xml"``). - *short_empty_elements* has the same meaning as in :meth:`ElementTree.write`. - Returns a list of (optionally) encoded strings containing the XML data. - It does not guarantee any specific sequence, except that - ``b"".join(tostringlist(element)) == tostring(element)``. + *xml_declaration*, *default_namespace* and *short_empty_elements* has the same + meaning as in :meth:`ElementTree.write`. Returns a list of (optionally) encoded + strings containing the XML data. It does not guarantee any specific sequence, + except that ``b"".join(tostringlist(element)) == tostring(element)``. .. versionadded:: 3.2 .. versionadded:: 3.4 The *short_empty_elements* parameter. + .. versionadded:: 3.8 + The *xml_declaration* and *default_namespace* parameters. + .. function:: XML(text, parser=None) @@ -755,7 +829,8 @@ Element Objects Finds the first subelement matching *match*. *match* may be a tag name or a :ref:`path `. Returns an element instance or ``None``. *namespaces* is an optional mapping from namespace prefix - to full name. + to full name. Pass ``''`` as prefix to move all unprefixed tag names + in the expression into the given namespace. .. method:: findall(match, namespaces=None) @@ -763,7 +838,8 @@ Element Objects Finds all matching subelements, by tag name or :ref:`path `. Returns a list containing all matching elements in document order. *namespaces* is an optional mapping from - namespace prefix to full name. + namespace prefix to full name. Pass ``''`` as prefix to move all + unprefixed tag names in the expression into the given namespace. .. method:: findtext(match, default=None, namespaces=None) @@ -773,7 +849,8 @@ Element Objects of the first matching element, or *default* if no element was found. Note that if the matching element has no text content an empty string is returned. *namespaces* is an optional mapping from namespace prefix - to full name. + to full name. Pass ``''`` as prefix to move all unprefixed tag names + in the expression into the given namespace. .. method:: getchildren() @@ -1009,14 +1086,24 @@ TreeBuilder Objects ^^^^^^^^^^^^^^^^^^^ -.. class:: TreeBuilder(element_factory=None) +.. class:: TreeBuilder(element_factory=None, *, comment_factory=None, \ + pi_factory=None, insert_comments=False, insert_pis=False) Generic element structure builder. This builder converts a sequence of - start, data, and end method calls to a well-formed element structure. You - can use this class to build an element structure using a custom XML parser, - or a parser for some other XML-like format. *element_factory*, when given, - must be a callable accepting two positional arguments: a tag and - a dict of attributes. It is expected to return a new element instance. + start, data, end, comment and pi method calls to a well-formed element + structure. You can use this class to build an element structure using + a custom XML parser, or a parser for some other XML-like format. + + *element_factory*, when given, must be a callable accepting two positional + arguments: a tag and a dict of attributes. It is expected to return a new + element instance. + + The *comment_factory* and *pi_factory* functions, when given, should behave + like the :func:`Comment` and :func:`ProcessingInstruction` functions to + create comments and processing instructions. When not given, the default + factories will be used. When *insert_comments* and/or *insert_pis* is true, + comments/pis will be inserted into the tree if they appear within the root + element (but not outside of it). .. method:: close() @@ -1042,8 +1129,24 @@ TreeBuilder Objects containing element attributes. Returns the opened element. + .. method:: comment(text) + + Creates a comment with the given *text*. If ``insert_comments`` is true, + this will also add it to the tree. + + .. versionadded:: 3.8 + + + .. method:: pi(target, text) + + Creates a comment with the given *target* name and *text*. If + ``insert_pis`` is true, this will also add it to the tree. + + .. versionadded:: 3.8 + + In addition, a custom :class:`TreeBuilder` object can provide the - following method: + following methods: .. method:: doctype(name, pubid, system) @@ -1053,6 +1156,36 @@ TreeBuilder Objects .. versionadded:: 3.2 + .. method:: start_ns(prefix, uri) + + Is called whenever the parser encounters a new namespace declaration, + before the ``start()`` callback for the opening element that defines it. + *prefix* is ``''`` for the default namespace and the declared + namespace prefix name otherwise. *uri* is the namespace URI. + + .. versionadded:: 3.8 + + .. method:: end_ns(prefix) + + Is called after the ``end()`` callback of an element that declared + a namespace prefix mapping, with the name of the *prefix* that went + out of scope. + + .. versionadded:: 3.8 + + +.. class:: C14NWriterTarget(write, *, \ + with_comments=False, strip_text=False, rewrite_prefixes=False, \ + qname_aware_tags=None, qname_aware_attrs=None, \ + exclude_attrs=None, exclude_tags=None) + + A `C14N 2.0 `_ writer. Arguments are the + same as for the :func:`canonicalize` function. This class does not build a + tree but translates the callback events directly into a serialised form + using the *write* function. + + .. versionadded:: 3.8 + .. _elementtree-xmlparser-objects: @@ -1088,7 +1221,8 @@ XMLParser Objects :meth:`XMLParser.feed` calls *target*\'s ``start(tag, attrs_dict)`` method for each opening tag, its ``end(tag)`` method for each closing tag, and data - is processed by method ``data(data)``. :meth:`XMLParser.close` calls + is processed by method ``data(data)``. For further supported callback + methods, see the :class:`TreeBuilder` class. :meth:`XMLParser.close` calls *target*\'s method ``close()``. :class:`XMLParser` can be used not only for building a tree structure. This is an example of counting the maximum depth of an XML file:: @@ -1138,9 +1272,9 @@ XMLPullParser Objects callback target, :class:`XMLPullParser` collects an internal list of parsing events and lets the user read from it. *events* is a sequence of events to report back. The supported events are the strings ``"start"``, ``"end"``, - ``"start-ns"`` and ``"end-ns"`` (the "ns" events are used to get detailed - namespace information). If *events* is omitted, only ``"end"`` events are - reported. + ``"comment"``, ``"pi"``, ``"start-ns"`` and ``"end-ns"`` (the "ns" events + are used to get detailed namespace information). If *events* is omitted, + only ``"end"`` events are reported. .. method:: feed(data) @@ -1159,7 +1293,13 @@ XMLPullParser Objects data fed to the parser. The iterator yields ``(event, elem)`` pairs, where *event* is a string representing the type of event (e.g. ``"end"``) and *elem* is the - encountered :class:`Element` object. + encountered :class:`Element` object, or other context value as follows. + + * ``start``, ``end``: the current Element. + * ``comment``, ``pi``: the current comment / processing instruction + * ``start-ns``: a tuple ``(prefix, uri)`` naming the declared namespace + mapping. + * ``end-ns``: :const:`None` (this may change in a future version) Events provided in a previous call to :meth:`read_events` will not be yielded again. Events are consumed from the internal queue only when @@ -1179,6 +1319,10 @@ XMLPullParser Objects .. versionadded:: 3.4 + .. versionchanged:: 3.8 + The ``comment`` and ``pi`` events were added. + + Exceptions ^^^^^^^^^^ diff --git a/Doc/library/xml.sax.reader.rst b/Doc/library/xml.sax.reader.rst index 1b6e43145b9..113e9e93fb0 100644 --- a/Doc/library/xml.sax.reader.rst +++ b/Doc/library/xml.sax.reader.rst @@ -102,13 +102,17 @@ The :class:`XMLReader` interface supports the following methods: Process an input source, producing SAX events. The *source* object can be a system identifier (a string identifying the input source -- typically a file - name or a URL), a file-like object, or an :class:`InputSource` object. When + name or a URL), a :class:`pathlib.Path` or :term:`path-like ` + object, or an :class:`InputSource` object. When :meth:`parse` returns, the input is completely processed, and the parser object can be discarded or reset. .. versionchanged:: 3.5 Added support of character streams. + .. versionchanged:: 3.8 + Added support of path-like objects. + .. method:: XMLReader.getContentHandler() diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 4e9edff2701..9db9697105d 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -52,6 +52,15 @@ The module defines the following items: :ref:`zipfile-objects` for constructor details. +.. class:: Path + :noindex: + + A pathlib-compatible wrapper for zip files. See section + :ref:`path-objects` for details. + + .. versionadded:: 3.8 + + .. class:: PyZipFile :noindex: @@ -456,6 +465,64 @@ The following data attributes are also available: truncated. +.. _path-objects: + +Path Objects +------------ + +.. class:: Path(root, at='') + + Construct a Path object from a ``root`` zipfile (which may be a + :class:`ZipFile` instance or ``file`` suitable for passing to + the :class:`ZipFile` constructor). + + ``at`` specifies the location of this Path within the zipfile, + e.g. 'dir/file.txt', 'dir/', or ''. Defaults to the empty string, + indicating the root. + +Path objects expose the following features of :mod:`pathlib.Path` +objects: + +Path objects are traversable using the ``/`` operator. + +.. attribute:: Path.name + + The final path component. + +.. method:: Path.open(*, **) + + Invoke :meth:`ZipFile.open` on the current path. Accepts + the same arguments as :meth:`ZipFile.open`. + +.. method:: Path.listdir() + + Enumerate the children of the current directory. + +.. method:: Path.is_dir() + + Return ``True`` if the current context references a directory. + +.. method:: Path.is_file() + + Return ``True`` if the current context references a file. + +.. method:: Path.exists() + + Return ``True`` if the current context references a file or + directory in the zip file. + +.. method:: Path.read_text(*, **) + + Read the current file as unicode text. Positional and + keyword arguments are passed through to + :class:`io.TextIOWrapper` (except ``buffer``, which is + implied by the context). + +.. method:: Path.read_bytes() + + Read the current file as bytes. + + .. _pyzipfile-objects: PyZipFile Objects diff --git a/Doc/license.rst b/Doc/license.rst index a315b6f8134..bf2e4c522ce 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -561,7 +561,7 @@ SipHash24 --------- The file :file:`Python/pyhash.c` contains Marek Majkowski' implementation of -Dan Bernstein's SipHash24 algorithm. The contains the following note:: +Dan Bernstein's SipHash24 algorithm. It contains the following note:: Copyright (c) 2013 Marek Majkowski @@ -913,3 +913,40 @@ library unless the build is configured ``--with-system-libmpdec``:: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +W3C C14N test suite +------------------- + +The C14N 2.0 test suite in the :mod:`test` package +(``Lib/test/xmltestdata/c14n-20/``) was retrieved from the W3C website at +https://www.w3.org/TR/xml-c14n2-testcases/ and is distributed under the +3-clause BSD license: + + Copyright (c) 2013 W3C(R) (MIT, ERCIM, Keio, Beihang), + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of works must retain the original copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the original copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the W3C nor the names of its contributors may be + used to endorse or promote products derived from this work without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index c3e79ce6c88..9fc9f3a3848 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -475,13 +475,13 @@ Callable types | :attr:`__doc__` | The function's documentation | Writable | | | string, or ``None`` if | | | | unavailable; not inherited by | | - | | subclasses | | + | | subclasses. | | +-------------------------+-------------------------------+-----------+ - | :attr:`~definition.\ | The function's name | Writable | + | :attr:`~definition.\ | The function's name. | Writable | | __name__` | | | +-------------------------+-------------------------------+-----------+ | :attr:`~definition.\ | The function's | Writable | - | __qualname__` | :term:`qualified name` | | + | __qualname__` | :term:`qualified name`. | | | | | | | | .. versionadded:: 3.3 | | +-------------------------+-------------------------------+-----------+ @@ -493,7 +493,7 @@ Callable types | | argument values for those | | | | arguments that have defaults, | | | | or ``None`` if no arguments | | - | | have a default value | | + | | have a default value. | | +-------------------------+-------------------------------+-----------+ | :attr:`__code__` | The code object representing | Writable | | | the compiled function body. | | @@ -1311,9 +1311,9 @@ Basic customization Called by the :func:`format` built-in function, and by extension, evaluation of :ref:`formatted string literals ` and the :meth:`str.format` method, to produce a "formatted" - string representation of an object. The ``format_spec`` argument is + string representation of an object. The *format_spec* argument is a string that contains a description of the formatting options desired. - The interpretation of the ``format_spec`` argument is up to the type + The interpretation of the *format_spec* argument is up to the type implementing :meth:`__format__`, however most classes will either delegate formatting to one of the built-in types, or use a similar formatting option syntax. @@ -1857,11 +1857,11 @@ passed through to all metaclass operations described below. When a class definition is executed, the following steps occur: -* MRO entries are resolved -* the appropriate metaclass is determined -* the class namespace is prepared -* the class body is executed -* the class object is created +* MRO entries are resolved; +* the appropriate metaclass is determined; +* the class namespace is prepared; +* the class body is executed; +* the class object is created. Resolving MRO entries @@ -1885,11 +1885,11 @@ Determining the appropriate metaclass The appropriate metaclass for a class definition is determined as follows: -* if no bases and no explicit metaclass are given, then :func:`type` is used +* if no bases and no explicit metaclass are given, then :func:`type` is used; * if an explicit metaclass is given and it is *not* an instance of - :func:`type`, then it is used directly as the metaclass + :func:`type`, then it is used directly as the metaclass; * if an instance of :func:`type` is given as the explicit metaclass, or - bases are defined, then the most derived metaclass is used + bases are defined, then the most derived metaclass is used. The most derived metaclass is selected from the explicitly specified metaclass (if any) and the metaclasses (i.e. ``type(cls)``) of all specified @@ -1976,7 +1976,7 @@ invoked after creating the class object: * first, ``type.__new__`` collects all of the descriptors in the class namespace that define a :meth:`~object.__set_name__` method; * second, all of these ``__set_name__`` methods are called with the class - being defined and the assigned name of that particular descriptor; and + being defined and the assigned name of that particular descriptor; * finally, the :meth:`~object.__init_subclass__` hook is called on the immediate parent of the new class in its method resolution order. @@ -2048,7 +2048,7 @@ Emulating generic types ----------------------- One can implement the generic class syntax as specified by :pep:`484` -(for example ``List[int]``) by defining a special method +(for example ``List[int]``) by defining a special method: .. classmethod:: object.__class_getitem__(cls, key) @@ -2680,13 +2680,13 @@ Asynchronous context managers can be used in an :keyword:`async with` statement. .. method:: object.__aenter__(self) - This method is semantically similar to the :meth:`__enter__`, with only - difference that it must return an *awaitable*. + Semantically similar to :meth:`__enter__`, the only + difference being that it must return an *awaitable*. .. method:: object.__aexit__(self, exc_type, exc_value, traceback) - This method is semantically similar to the :meth:`__exit__`, with only - difference that it must return an *awaitable*. + Semantically similar to :meth:`__exit__`, the only + difference being that it must return an *awaitable*. An example of an asynchronous context manager class:: diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 9a0ab39d3b4..0228bfb7e98 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -345,12 +345,11 @@ of what happens during the loading portion of import:: _init_module_attrs(spec, module) if spec.loader is None: - if spec.submodule_search_locations is not None: - # namespace package - sys.modules[spec.name] = module - else: - # unsupported - raise ImportError + # unsupported + raise ImportError + if spec.origin is None and spec.submodule_search_locations is not None: + # namespace package + sys.modules[spec.name] = module elif not hasattr(spec.loader, 'exec_module'): module = spec.loader.load_module(spec.name) # Set __loader__ and __package__ if missing. @@ -921,6 +920,46 @@ it is sufficient to raise :exc:`ModuleNotFoundError` directly from ``None``. The latter indicates that the meta path search should continue, while raising an exception terminates it immediately. +.. _relativeimports: + +Package Relative Imports +======================== + +Relative imports use leading dots. A single leading dot indicates a relative +import, starting with the current package. Two or more leading dots indicate a +relative import to the parent(s) of the current package, one level per dot +after the first. For example, given the following package layout:: + + package/ + __init__.py + subpackage1/ + __init__.py + moduleX.py + moduleY.py + subpackage2/ + __init__.py + moduleZ.py + moduleA.py + +In either ``subpackage1/moduleX.py`` or ``subpackage1/__init__.py``, +the following are valid relative imports:: + + from .moduleY import spam + from .moduleY import spam as ham + from . import moduleY + from ..subpackage1 import moduleY + from ..subpackage2.moduleZ import eggs + from ..moduleA import foo + +Absolute imports may use either the ``import <>`` or ``from <> import <>`` +syntax, but relative imports may only use the second form; the reason +for this is that:: + + import XXX.YYY.ZZZ + +should expose ``XXX.YYY.ZZZ`` as a usable expression, but .moduleY is +not a valid expression. + Special considerations for __main__ =================================== diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index fb04ccc839a..13adc1a2e43 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -680,11 +680,12 @@ with a closing curly bracket ``'}'``. Expressions in formatted string literals are treated like regular Python expressions surrounded by parentheses, with a few exceptions. -An empty expression is not allowed, and a :keyword:`lambda` expression -must be surrounded by explicit parentheses. Replacement expressions -can contain line breaks (e.g. in triple-quoted strings), but they -cannot contain comments. Each expression is evaluated in the context -where the formatted string literal appears, in order from left to right. +An empty expression is not allowed, and both :keyword:`lambda` and +assignment expressions ``:=`` must be surrounded by explicit parentheses. +Replacement expressions can contain line breaks (e.g. in triple-quoted +strings), but they cannot contain comments. Each expression is evaluated +in the context where the formatted string literal appears, in order from +left to right. If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion ``'!s'`` calls :func:`str` on diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 00964afc6d3..af7c0caff62 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -169,12 +169,12 @@ Assignment of an object to a single target is recursively defined as follows. .. _attr-target-note: Note: If the object is a class instance and the attribute reference occurs on - both sides of the assignment operator, the RHS expression, ``a.x`` can access + both sides of the assignment operator, the right-hand side expression, ``a.x`` can access either an instance attribute or (if no instance attribute exists) a class - attribute. The LHS target ``a.x`` is always set as an instance attribute, + attribute. The left-hand side target ``a.x`` is always set as an instance attribute, creating it if necessary. Thus, the two occurrences of ``a.x`` do not - necessarily refer to the same attribute: if the RHS expression refers to a - class attribute, the LHS creates a new instance attribute as the target of the + necessarily refer to the same attribute: if the right-hand side expression refers to a + class attribute, the left-hand side creates a new instance attribute as the target of the assignment:: class Cls: @@ -828,7 +828,8 @@ exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute ``from . import mod`` from a module in the ``pkg`` package then you will end up importing ``pkg.mod``. If you execute ``from ..subpkg2 import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``. -The specification for relative imports is contained within :pep:`328`. +The specification for relative imports is contained in +the :ref:`relativeimports` section. :func:`importlib.import_module` is provided to support applications that determine dynamically the modules to be loaded. diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js index 20dad93d6a5..346b31494e6 100644 --- a/Doc/tools/static/switchers.js +++ b/Doc/tools/static/switchers.js @@ -22,6 +22,7 @@ 'fr': 'French', 'ja': 'Japanese', 'ko': 'Korean', + 'zh-cn': 'Simplified Chinese', }; function build_version_select(current_version, current_release) { diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html index 1a99b18bbb2..d9364d6ced7 100644 --- a/Doc/tools/templates/download.html +++ b/Doc/tools/templates/download.html @@ -12,8 +12,7 @@

Download Python {{ release }} Documentation

{% if last_updated %}

Last updated on: {{ last_updated }}.

{% endif %}

To download an archive containing all the documents for this version of -Python in one of various formats, follow one of links in this table. The numbers -in the table are the size of the download files in megabytes.

+Python in one of various formats, follow one of links in this table.

diff --git a/Doc/tools/templates/indexcontent.html b/Doc/tools/templates/indexcontent.html index d795c0a5586..152162ab0dd 100644 --- a/Doc/tools/templates/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -57,6 +57,7 @@

{{ docstitle|e }}

FormatPacked as .zipPacked as .tar.bz2
+ diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index b4db3f01591..01e437bb5da 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -678,18 +678,17 @@ intended. Comparing Sequences and Other Types =================================== - -Sequence objects may be compared to other objects with the same sequence type. -The comparison uses *lexicographical* ordering: first the first two items are -compared, and if they differ this determines the outcome of the comparison; if -they are equal, the next two items are compared, and so on, until either -sequence is exhausted. If two items to be compared are themselves sequences of -the same type, the lexicographical comparison is carried out recursively. If -all items of two sequences compare equal, the sequences are considered equal. -If one sequence is an initial sub-sequence of the other, the shorter sequence is -the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode -code point number to order individual characters. Some examples of comparisons -between sequences of the same type:: +Sequence objects typically may be compared to other objects with the same sequence +type. The comparison uses *lexicographical* ordering: first the first two +items are compared, and if they differ this determines the outcome of the +comparison; if they are equal, the next two items are compared, and so on, until +either sequence is exhausted. If two items to be compared are themselves +sequences of the same type, the lexicographical comparison is carried out +recursively. If all items of two sequences compare equal, the sequences are +considered equal. If one sequence is an initial sub-sequence of the other, the +shorter sequence is the smaller (lesser) one. Lexicographical ordering for +strings uses the Unicode code point number to order individual characters. +Some examples of comparisons between sequences of the same type:: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 79427860f51..fc2bd5578c4 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -322,6 +322,8 @@ equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: >>> with open('workfile') as f: ... read_data = f.read() + + >>> # We can check that the file has been automatically closed. >>> f.closed True diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 3e0c99558ed..a4dbd6351b7 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -383,7 +383,7 @@ items of different types, but usually the items all have the same type. :: >>> squares [1, 4, 9, 16, 25] -Like strings (and all other built-in :term:`sequence` type), lists can be +Like strings (and all other built-in :term:`sequence` types), lists can be indexed and sliced:: >>> squares[0] # indexing returns the item diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index accc30649f2..d0a68faa2ee 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -425,9 +425,9 @@ your package (expressed in terms of a hierarchical filesystem): When importing the package, Python searches through the directories on ``sys.path`` looking for the package subdirectory. -The :file:`__init__.py` files are required to make Python treat the directories -as containing packages; this is done to prevent directories with a common name, -such as ``string``, from unintentionally hiding valid modules that occur later +The :file:`__init__.py` files are required to make Python treat directories +containing the file as packages. This prevents directories with a common name, +such as ``string``, unintentionally hiding valid modules that occur later on the module search path. In the simplest case, :file:`__init__.py` can just be an empty file, but it can also execute initialization code for the package or set the ``__all__`` variable, described later. @@ -523,7 +523,7 @@ Although certain modules are designed to export only names that follow certain patterns when you use ``import *``, it is still considered bad practice in production code. -Remember, there is nothing wrong with using ``from Package import +Remember, there is nothing wrong with using ``from package import specific_submodule``! In fact, this is the recommended notation unless the importing module needs to use submodules with the same name from different packages. diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index d876d0740d8..3208201312b 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -39,7 +39,7 @@ More Python resources: * https://docs.python.org: Fast access to Python's documentation. * https://pypi.org: The Python Package Index, previously also nicknamed - the Cheese Shop, is an index of user-created Python modules that are available + the Cheese Shop [#]_, is an index of user-created Python modules that are available for download. Once you begin releasing code, you can register it here so that others can find it. @@ -68,3 +68,9 @@ Before posting, be sure to check the list of :ref:`Frequently Asked Questions ` (also called the FAQ). The FAQ answers many of the questions that come up again and again, and may already contain the solution for your problem. + +.. rubric:: Footnotes + +.. [#] "Cheese Shop" is a Monty Python's sketch: a customer enters a cheese shop, + but whatever cheese he asks for, the clerk says it's missing. + diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index bd3cdef5739..fd47ce2ab53 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -437,6 +437,7 @@ Miscellaneous options * Enable :ref:`asyncio debug mode `. * Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to ``True`` + * :class:`io.IOBase` destructor logs ``close()`` exceptions. * ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8 @@ -465,7 +466,8 @@ Miscellaneous options The ``-X importtime``, ``-X dev`` and ``-X utf8`` options. .. versionadded:: 3.8 - The ``-X pycache_prefix`` option. + The ``-X pycache_prefix`` option. The ``-X dev`` option now logs + ``close()`` exceptions in :class:`io.IOBase` destructor. Options you shouldn't use @@ -920,15 +922,18 @@ conflict. Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ -Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the ``--with-pydebug`` build option. +Setting these variables only has an effect in a debug build of Python. .. envvar:: PYTHONTHREADDEBUG If set, Python will print threading debug info. + Need Python configured with the ``--with-pydebug`` build option. + .. envvar:: PYTHONDUMPREFS If set, Python will dump objects and reference counts still alive after shutting down the interpreter. + + Need Python configured with the ``--with-trace-refs`` build option. diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 0165fff09cc..2f3eb0ea3f0 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -154,7 +154,9 @@ of available options is shown below. | DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ | | | just-for-me installs | Programs\\PythonXY` or | | | | :file:`%LocalAppData%\\\ | -| | | Programs\\PythonXY-32` | +| | | Programs\\PythonXY-32` or| +| | | :file:`%LocalAppData%\\\ | +| | | Programs\\PythonXY-64` | +---------------------------+--------------------------------------+--------------------------+ | DefaultCustomTargetDir | The default custom install directory | (empty) | | | displayed in the UI | | @@ -762,9 +764,16 @@ on Windows which you hope will be useful on Unix, you should use one of the shebang lines starting with ``/usr``. Any of the above virtual commands can be suffixed with an explicit version -(either just the major version, or the major and minor version) - for example -``/usr/bin/python2.7`` - which will cause that specific version to be located -and used. +(either just the major version, or the major and minor version). +Furthermore the 32-bit version can be requested by adding "-32" after the +minor version. I.e. ``/usr/bin/python2.7-32`` will request usage of the +32-bit python 2.7. + +.. versionadded:: 3.7 + + Beginning with python launcher 3.7 it is possible to request 64-bit version + by the "-64" suffix. Furthermore it is possible to specify a major and + architecture without minor (i.e. ``/usr/bin/python3-64``). The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the @@ -806,17 +815,18 @@ Customizing default Python versions In some cases, a version qualifier can be included in a command to dictate which version of Python will be used by the command. A version qualifier starts with a major version number and can optionally be followed by a period -('.') and a minor version specifier. If the minor qualifier is specified, it -may optionally be followed by "-32" to indicate the 32-bit implementation of -that version be used. +('.') and a minor version specifier. Furthermore it is possible to specifiy +if a 32 or 64 bit implementation shall be requested by adding "-32" or "-64". For example, a shebang line of ``#!python`` has no version qualifier, while ``#!python3`` has a version qualifier which specifies only a major version. -If no version qualifiers are found in a command, the environment variable -``PY_PYTHON`` can be set to specify the default version qualifier - the default -value is "2". Note this value could specify just a major version (e.g. "2") or -a major.minor qualifier (e.g. "2.6"), or even major.minor-32. +If no version qualifiers are found in a command, the environment +variable :envvar:`PY_PYTHON` can be set to specify the default version +qualifier. If it is not set, the default is "3". The variable can +specify any value that may be passed on the command line, such as "3", +"3.7", "3.7-32" or "3.7-64". (Note that the "-64" option is only +available with the launcher included with Python 3.7 or newer.) If no minor version qualifiers are found, the environment variable ``PY_PYTHON{major}`` (where ``{major}`` is the current major version qualifier @@ -834,8 +844,8 @@ of the specified version if available. This is so the behavior of the launcher can be predicted knowing only what versions are installed on the PC and without regard to the order in which they were installed (i.e., without knowing whether a 32 or 64-bit version of Python and corresponding launcher was -installed last). As noted above, an optional "-32" suffix can be used on a -version specifier to change this behaviour. +installed last). As noted above, an optional "-32" or "-64" suffix can be +used on a version specifier to change this behaviour. Examples: diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 3855d3604e1..d6388f8faab 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -67,6 +67,47 @@ Summary -- Release highlights New Features ============ +Assignment expressions +---------------------- + +There is new syntax (the "walrus operator", ``:=``) to assign values +to variables as part of an expression. Example:: + + if (n := len(a)) > 10: + print(f"List is too long ({n} elements, expected <= 10)") + +See :pep:`572` for a full description. + +(Contributed by Emily Morehouse in :issue:`35224`.) + +.. TODO: Emily will sprint on docs at PyCon US 2019. + + +Positional-only parameters +-------------------------- + +There is new syntax (``/``) to indicate that some function parameters +must be specified positionally (i.e., cannot be used as keyword +arguments). This is the same notation as shown by ``help()`` for +functions implemented in C (produced by Larry Hastings' "Argument +Clinic" tool). Example:: + + def pow(x, y, z=None, /): + r = x**y + if z is not None: + r %= z + return r + +Now ``pow(2, 10)`` and ``pow(2, 10, 17)`` are valid calls, but +``pow(x=2, y=10)`` and ``pow(2, 10, z=17)`` are invalid. + +See :pep:`570` for a full description. + +(Contributed by Pablo Galindo in :issue:`36540`.) + +.. TODO: Pablo will sprint on docs at PyCon US 2019. + + Parallel filesystem cache for compiled bytecode files ----------------------------------------------------- @@ -82,6 +123,31 @@ subdirectories). (Contributed by Carl Meyer in :issue:`33499`.) +Debug build uses the same ABI as release build +----------------------------------------------- + +Python now uses the same ABI whether it built in release or debug mode. On +Unix, when Python is built in debug mode, it is now possible to load C +extensions built in release mode and C extensions built using the stable ABI. + +Release builds and debug builds are now ABI compatible: defining the +``Py_DEBUG`` macro no longer implies the ``Py_TRACE_REFS`` macro, which +introduces the only ABI incompatibility. The ``Py_TRACE_REFS`` macro, which +adds the :func:`sys.getobjects` function and the :envvar:`PYTHONDUMPREFS` +environment variable, can be set using the new ``./configure --with-trace-refs`` +build option. +(Contributed by Victor Stinner in :issue:`36465`.) + +On Unix, C extensions are no longer linked to libpython. It is now possible +for a statically linked Python to load a C extension built using a shared +library Python. +(Contributed by Victor Stinner in :issue:`21536`.) + +On Unix, when Python is built in debug mode, import now also looks for C +extensions compiled in release mode and for C extensions compiled with the +stable ABI. +(Contributed by Victor Stinner in :issue:`36722`.) + Other Language Changes ====================== @@ -150,17 +216,6 @@ New Modules Improved Modules ================ -* The :meth:`_asdict()` method for :func:`collections.namedtuple` now returns - a :class:`dict` instead of a :class:`collections.OrderedDict`. This works because - regular dicts have guaranteed ordering in since Python 3.7. If the extra - features of :class:`OrderedDict` are required, the suggested remediation is - to cast the result to the desired type: ``OrderedDict(nt._asdict())``. - (Contributed by Raymond Hettinger in :issue:`35864`.) - -* The :mod:`unicodedata` module has been upgraded to use the `Unicode 12.0.0 - `_ - release. - asyncio ------- @@ -168,12 +223,57 @@ asyncio On Windows, the default event loop is now :class:`~asyncio.ProactorEventLoop`. +collections +----------- + +The :meth:`_asdict()` method for :func:`collections.namedtuple` now returns +a :class:`dict` instead of a :class:`collections.OrderedDict`. This works because +regular dicts have guaranteed ordering since Python 3.7. If the extra +features of :class:`OrderedDict` are required, the suggested remediation is +to cast the result to the desired type: ``OrderedDict(nt._asdict())``. +(Contributed by Raymond Hettinger in :issue:`35864`.) + + +ctypes +------ + +On Windows, :class:`~ctypes.CDLL` and subclasses now accept a *winmode* parameter +to specify flags for the underlying ``LoadLibraryEx`` call. The default flags are +set to only load DLL dependencies from trusted locations, including the path +where the DLL is stored (if a full or partial path is used to load the initial +DLL) and paths added by :func:`~os.add_dll_directory`. + + +datetime +-------- + +Added new alternate constructors :meth:`datetime.date.fromisocalendar` and +:meth:`datetime.datetime.fromisocalendar`, which construct :class:`date` and +:class:`datetime` objects respectively from ISO year, week number and weekday; +these are the inverse of each class's ``isocalendar`` method. +(Contributed by Paul Ganssle in :issue:`36004`.) + + gettext ------- Added :func:`~gettext.pgettext` and its variants. (Contributed by Franz Glasner, Éric Araujo, and Cheryl Sabella in :issue:`2504`.) +inspect +------- + +The :func:`inspect.getdoc` function can now find docstrings for ``__slots__`` +if that attribute is a :class:`dict` where the values are docstrings. +This provides documentation options similar to what we already have +for :func:`property`, :func:`classmethod`, and :func:`staticmethod`:: + + class AudioClip: + __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place', + 'duration': 'in seconds, rounded up to an integer'} + def __init__(self, bit_rate, duration): + self.bit_rate = round(bit_rate / 1000.0, 1) + self.duration = ceil(duration) gc -- @@ -224,6 +324,13 @@ Added new function, :func:`math.prod`, as analogous function to :func:`sum` that returns the product of a 'start' value (default: 1) times an iterable of numbers. (Contributed by Pablo Galindo in :issue:`35606`) +os +-- + +Added new function :func:`~os.add_dll_directory` on Windows for providing +additional search paths for native dependencies when importing extension +modules or loading DLLs using :mod:`ctypes`. + os.path ------- @@ -262,6 +369,19 @@ pathlib contain characters unrepresentable at the OS level. (Contributed by Serhiy Storchaka in :issue:`33721`.) +Added :meth:`pathlib.Path.link_to()` which creates a hard link pointing +to a path. +(Contributed by Joannah Nanjekye in :issue:`26978`) + + +socket +------ + +Added :meth:`~socket.create_server()` and :meth:`~socket.has_dualstack_ipv6()` +convenience functions to automate the necessary tasks usually involved when +creating a server socket, including accepting both IPv4 and IPv6 connections +on the same socket. (Contributed by Giampaolo Rodola in :issue:`17561`.) + shutil ------ @@ -269,6 +389,11 @@ shutil :func:`shutil.copytree` now accepts a new ``dirs_exist_ok`` keyword argument. (Contributed by Josh Bronson in :issue:`20849`.) +:func:`shutil.make_archive` now defaults to the modern pax (POSIX.1-2001) +format for new archives to improve portability and standards conformance, +inherited from the corresponding change to the :mod:`tarfile` module. +(Contributed by C.A.M. Gerlach in :issue:`30661`.) + ssl --- @@ -286,9 +411,16 @@ Added :func:`statistics.fmean` as a faster, floating point variant of :func:`statistics.mean()`. (Contributed by Raymond Hettinger and Steven D'Aprano in :issue:`35904`.) +Added :func:`statistics.geometric_mean()` +(Contributed by Raymond Hettinger in :issue:`27181`.) + Added :func:`statistics.multimode` that returns a list of the most common values. (Contributed by Raymond Hettinger in :issue:`35892`.) +Added :func:`statistics.quantiles` that divides data or a distribution +in to equiprobable intervals (e.g. quartiles, deciles, or percentiles). +(Contributed by Raymond Hettinger in :issue:`36546`.) + Added :class:`statistics.NormalDist`, a tool for creating and manipulating normal distributions of a random variable. (Contributed by Raymond Hettinger in :issue:`36018`.) @@ -296,8 +428,10 @@ and manipulating normal distributions of a random variable. :: >>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14]) - >>> temperature_feb - NormalDist(mu=6.0, sigma=6.356099432828281) + >>> temperature_feb.mean + 6.0 + >>> temperature_feb.stdev + 6.356099432828281 >>> temperature_feb.cdf(3) # Chance of being under 3 degrees 0.3184678262814532 @@ -305,8 +439,8 @@ and manipulating normal distributions of a random variable. >>> temperature_feb.pdf(7) / temperature_feb.pdf(10) 1.2039930378537762 - >>> el_nino = NormalDist(4, 2.5) - >>> temperature_feb += el_nino # Add in a climate effect + >>> el_niño = NormalDist(4, 2.5) + >>> temperature_feb += el_niño # Add in a climate effect >>> temperature_feb NormalDist(mu=10.0, sigma=6.830080526611674) @@ -348,6 +482,11 @@ Added method :meth:`~tkinter.Canvas.moveto` in the :class:`tkinter.Canvas` class. (Contributed by Juliette Monsel in :issue:`23831`.) +The :class:`tkinter.PhotoImage` class now has +:meth:`~tkinter.PhotoImage.transparency_get` and +:meth:`~tkinter.PhotoImage.transparency_set` methods. (Contributed by +Zackery Spytz in :issue:`25451`.) + time ---- @@ -357,10 +496,15 @@ Added new clock :data:`~time.CLOCK_UPTIME_RAW` for macOS 10.12. unicodedata ----------- +* The :mod:`unicodedata` module has been upgraded to use the `Unicode 12.0.0 + `_ + release. + * New function :func:`~unicodedata.is_normalized` can be used to verify a string is in a specific normal form. (Contributed by Max Belanger and David Euresti in :issue:`32285`). + unittest -------- @@ -377,6 +521,13 @@ venv activating virtual environments under PowerShell Core 6.1. (Contributed by Brett Cannon in :issue:`32718`.) +weakref +------- + +* The proxy objects returned by :func:`weakref.proxy` now support the matrix + multiplication operators ``@`` and ``@=`` in addition to the other + numeric operators. (Contributed by Mark Dickinson in :issue:`36669`.) + xml --- @@ -385,6 +536,15 @@ xml external entities by default. (Contributed by Christian Heimes in :issue:`17239`.) +* The ``.find*()`` methods in the :mod:`xml.etree.ElementTree` module + support wildcard searches like ``{*}tag`` which ignores the namespace + and ``{namespace}*`` which returns all tags in the given namespace. + (Contributed by Stefan Behnel in :issue:`28238`.) + +* The :mod:`xml.etree.ElementTree` module provides a new function + :func:`–xml.etree.ElementTree.canonicalize()` that implements C14N 2.0. + (Contributed by Stefan Behnel in :issue:`13611`.) + Optimizations ============= @@ -495,6 +655,12 @@ Build and C API Changes ``1`` for objects implementing ``__index__()``. (Contributed by Serhiy Storchaka in :issue:`36048`.) +* Heap-allocated type objects will now increase their reference count + in :c:func:`PyObject_Init` (and its parallel macro ``PyObject_INIT``) + instead of in :c:func:`PyType_GenericAlloc`. Types that modify instance + allocation or deallocation may need to be adjusted. + (Contributed by Eddie Elizondo in :issue:`35810`.) + Deprecated ========== @@ -557,6 +723,33 @@ Deprecated version they will be errors. (Contributed by Serhiy Storchaka in :issue:`36048`.) +* Deprecated passing the following arguments as keyword arguments: + + - *func* in :func:`functools.partialmethod`, :func:`weakref.finalize`, + :meth:`profile.Profile.runcall`, :meth:`cProfile.Profile.runcall`, + :meth:`bdb.Bdb.runcall`, :meth:`trace.Trace.runfunc` and + :func:`curses.wrapper`. + - *function* in :func:`unittest.addModuleCleanup` and + :meth:`unittest.TestCase.addCleanup`. + - *fn* in the :meth:`~concurrent.futures.Executor.submit` method of + :class:`concurrent.futures.ThreadPoolExecutor` and + :class:`concurrent.futures.ProcessPoolExecutor`. + - *callback* in :meth:`contextlib.ExitStack.callback`, + :meth:`contextlib.AsyncExitStack.callback` and + :meth:`contextlib.AsyncExitStack.push_async_callback`. + - *c* and *typeid* in the :meth:`~multiprocessing.managers.Server.create` + method of :class:`multiprocessing.managers.Server` and + :class:`multiprocessing.managers.SharedMemoryServer`. + - *obj* in :func:`weakref.finalize`. + + In future releases of Python they will be :ref:`positional-only + `. + (Contributed by Serhiy Storchaka in :issue:`36492`.) + +* The function :func:`~inspect.getfullargspec` in the :mod:`inspect` + module is deprecated in favor of the :func:`inspect.signature` + API. (Contributed by Pablo Galindo in :issue:`36751`.) + API and Feature Removals ======================== @@ -613,10 +806,43 @@ Changes in Python behavior to use equality tests (``==`` and ``!=``) instead. (Contributed by Serhiy Storchaka in :issue:`34850`.) +* The CPython interpreter can swallow exceptions in some circumstances. + In Python 3.8 this happens in less cases. In particular, exceptions + raised when getting the attribute from the type dictionary are no longer + ignored. (Contributed by Serhiy Storchaka in :issue:`35459`.) + +* Removed ``__str__`` implementations from builtin types :class:`bool`, + :class:`int`, :class:`float`, :class:`complex` and few classes from + the standard library. They now inherit ``__str__()`` from :class:`object`. + As result, defining the ``__repr__()`` method in the subclass of these + classes will affect they string representation. + (Contributed by Serhiy Storchaka in :issue:`36793`.) + +* On AIX, :attr:`sys.platform` doesn't contain the major version anymore. + It is always ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. Since + older Python versions include the version number, it is recommended to + always use the ``sys.platform.startswith('aix')``. + (Contributed by M. Felt in :issue:`36588`.) + +* :c:func:`PyEval_AcquireLock` and :c:func:`PyEval_AcquireThread` now + terminate the current thread if called while the interpreter is + finalizing, making them consistent with :c:func:`PyEval_RestoreThread`, + :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. If this + behaviour is not desired, guard the call by checking :c:func:`_Py_IsFinalizing` + or :c:func:`sys.is_finalizing`. Changes in the Python API ------------------------- +* :class:`subprocess.Popen` can now use :func:`os.posix_spawn` in some cases + for better performance. On Windows Subsystem for Linux and QEMU User + Emulation, Popen constructor using :func:`os.posix_spawn` no longer raise an + exception on errors like missing program, but the child process fails with a + non-zero :attr:`~Popen.returncode`. + +* The :meth:`imap.IMAP4.logout` method no longer ignores silently arbitrary + exceptions. + * The function :func:`platform.popen` has been removed, it was deprecated since Python 3.3: use :func:`os.popen` instead. @@ -707,16 +933,99 @@ Changes in the Python API environment variable and does not use :envvar:`HOME`, which is not normally set for regular user accounts. +.. _bpo-36085-whatsnew: + +* DLL dependencies for extension modules and DLLs loaded with :mod:`ctypes` on + Windows are now resolved more securely. Only the system paths, the directory + containing the DLL or PYD file, and directories added with + :func:`~os.add_dll_directory` are searched for load-time dependencies. + Specifically, :envvar:`PATH` and the current working directory are no longer + used, and modifications to these will no longer have any effect on normal DLL + resolution. If your application relies on these mechanisms, you should check + for :func:`~os.add_dll_directory` and if it exists, use it to add your DLLs + directory while loading your library. Note that Windows 7 users will need to + ensure that Windows Update KB2533625 has been installed (this is also verified + by the installer). + (See :issue:`36085`.) + +* The header files and functions related to pgen have been removed after its + replacement by a pure Python implementation. (Contributed by Pablo Galindo + in :issue:`36623`.) + Changes in the C API -------------------- +* On Unix, C extensions are no longer linked to libpython except on + Android. When Python is embedded, ``libpython`` must not be loaded with + ``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using + ``RTLD_LOCAL``, it was already not possible to load C extensions which were + not linked to ``libpython``, like C extensions of the standard library built + by the ``*shared*`` section of ``Modules/Setup``. + * Use of ``#`` variants of formats in parsing or building value (e.g. :c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`, etc.) without ``PY_SSIZE_T_CLEAN`` defined raises ``DeprecationWarning`` now. It will be removed in 3.10 or 4.0. Read :ref:`arg-parsing` for detail. (Contributed by Inada Naoki in :issue:`36381`.) +* Instances of heap-allocated types (such as those created with + :c:func:`PyType_FromSpec`) hold a reference to their type object. + Increasing the reference count of these type objects has been moved from + :c:func:`PyType_GenericAlloc` to the more low-level functions, + :c:func:`PyObject_Init` and :c:func:`PyObject_INIT`. + This makes types created through :c:func:`PyType_FromSpec` behave like + other classes in managed code. + + Statically allocated types are not affected. + + For the vast majority of cases, there should be no side effect. + However, types that manually increase the reference count after allocating + an instance (perhaps to work around the bug) may now become immortal. + To avoid this, these classes need to call Py_DECREF on the type object + during instance deallocation. + + To correctly port these types into 3.8, please apply the following + changes: + + * Remove :c:macro:`Py_INCREF` on the type object after allocating an + instance - if any. + This may happen after calling :c:func:`PyObject_New`, + :c:func:`PyObject_NewVar`, :c:func:`PyObject_GC_New`, + :c:func:`PyObject_GC_NewVar`, or any other custom allocator that uses + :c:func:`PyObject_Init` or :c:func:`PyObject_INIT`. + + Example:: + + static foo_struct * + foo_new(PyObject *type) { + foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type); + if (foo == NULL) + return NULL; + #if PY_VERSION_HEX < 0x03080000 + // Workaround for Python issue 35810; no longer necessary in Python 3.8 + PY_INCREF(type) + #endif + return foo; + } + + * Ensure that all custom ``tp_dealloc`` functions of heap-allocated types + decrease the type's reference count. + + Example:: + + static void + foo_dealloc(foo_struct *instance) { + PyObject *type = Py_TYPE(instance); + PyObject_GC_Del(instance); + #if PY_VERSION_HEX >= 0x03080000 + // This was not needed before Python 3.8 (Python issue 35810) + Py_DECREF(type); + #endif + } + + (Contributed by Eddie Elizondo in :issue:`35810`.) + CPython bytecode changes ------------------------ diff --git a/Grammar/Grammar b/Grammar/Grammar index eaebdc4340f..0cacfb648e9 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -22,13 +22,55 @@ async_funcdef: ASYNC funcdef funcdef: 'def' NAME parameters ['->' test] ':' [TYPE_COMMENT] func_body_suite parameters: '(' [typedargslist] ')' -typedargslist: (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ + +# The following definition for typedarglist is equivalent to this set of rules: +# +# arguments = argument (',' [TYPE_COMMENT] argument)* +# argument = tfpdef ['=' test] +# kwargs = '**' tfpdef [','] [TYPE_COMMENT] +# args = '*' [tfpdef] +# kwonly_kwargs = (',' [TYPE_COMMENT] argument)* (TYPE_COMMENT | [',' [TYPE_COMMENT] [kwargs]]) +# args_kwonly_kwargs = args kwonly_kwargs | kwargs +# poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [',' [TYPE_COMMENT] [args_kwonly_kwargs]]) +# typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs +# typedarglist = (arguments ',' [TYPE_COMMENT] '/' [',' [[TYPE_COMMENT] typedargslist_no_posonly]])|(typedargslist_no_posonly)" +# +# It needs to be fully expanded to allow our LL(1) parser to work on it. + +typedargslist: ( + (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* ',' [TYPE_COMMENT] '/' [',' [ [TYPE_COMMENT] tfpdef ['=' test] ( + ',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) + | '**' tfpdef [','] [TYPE_COMMENT]]] ) +| (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ + '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) + | '**' tfpdef [','] [TYPE_COMMENT]]]) + | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] [TYPE_COMMENT]) +) tfpdef: NAME [':' test] -varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ + +# The following definition for varargslist is equivalent to this set of rules: +# +# arguments = argument (',' argument )* +# argument = vfpdef ['=' test] +# kwargs = '**' vfpdef [','] +# args = '*' [vfpdef] +# kwonly_kwargs = (',' argument )* [',' [kwargs]] +# args_kwonly_kwargs = args kwonly_kwargs | kwargs +# poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]] +# vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs +# varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | (vararglist_no_posonly) +# +# It needs to be fully expanded to allow our LL(1) parser to work on it. + +varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ + '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']]] + | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] diff --git a/Include/Python-ast.h b/Include/Python-ast.h index a5742ff0485..0c739db6d14 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -427,6 +427,7 @@ struct _excepthandler { struct _arguments { asdl_seq *args; + asdl_seq *posonlyargs; arg_ty vararg; asdl_seq *kwonlyargs; asdl_seq *kw_defaults; @@ -684,10 +685,11 @@ excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); -#define arguments(a0, a1, a2, a3, a4, a5, a6) _Py_arguments(a0, a1, a2, a3, a4, a5, a6) -arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq * - kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, - asdl_seq * defaults, PyArena *arena); +#define arguments(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7) +arguments_ty _Py_arguments(asdl_seq * args, asdl_seq * posonlyargs, arg_ty + vararg, asdl_seq * kwonlyargs, asdl_seq * + kw_defaults, arg_ty kwarg, asdl_seq * defaults, + PyArena *arena); #define arg(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arg(a0, a1, a2, a3, a4, a5, a6, a7) arg_ty _Py_arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, diff --git a/Include/bitset.h b/Include/bitset.h index b22fa77815c..6a2ac9787ea 100644 --- a/Include/bitset.h +++ b/Include/bitset.h @@ -8,23 +8,14 @@ extern "C" { /* Bitset interface */ #define BYTE char - typedef BYTE *bitset; -bitset newbitset(int nbits); -void delbitset(bitset bs); #define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0) -int addbit(bitset bs, int ibit); /* Returns 0 if already set */ -int samebitset(bitset bs1, bitset bs2, int nbits); -void mergebitset(bitset bs1, bitset bs2, int nbits); #define BITSPERBYTE (8*sizeof(BYTE)) -#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE) - #define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE) #define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE) #define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit)) -#define BYTE2BIT(ibyte) ((ibyte) * BITSPERBYTE) #ifdef __cplusplus } diff --git a/Include/code.h b/Include/code.h index 2e661e8b36b..933de97d078 100644 --- a/Include/code.h +++ b/Include/code.h @@ -21,6 +21,7 @@ typedef uint16_t _Py_CODEUNIT; typedef struct { PyObject_HEAD int co_argcount; /* #arguments, except *args */ + int co_posonlyargcount; /* #positional only arguments */ int co_kwonlyargcount; /* #keyword only arguments */ int co_nlocals; /* #local variables */ int co_stacksize; /* #entries needed for evaluation stack */ @@ -102,7 +103,7 @@ PyAPI_DATA(PyTypeObject) PyCode_Type; /* Public interface */ PyAPI_FUNC(PyCodeObject *) PyCode_New( - int, int, int, int, int, PyObject *, PyObject *, + int, int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *); /* same as struct above */ diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index bd28c371ce5..47a6baa1118 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -5,23 +5,21 @@ extern "C" { #endif -/* --- _PyArgv ---------------------------------------------------- */ - -typedef struct { - int argc; - int use_bytes_argv; - char **bytes_argv; - wchar_t **wchar_argv; -} _PyArgv; - - /* --- _PyInitError ----------------------------------------------- */ typedef struct { - const char *prefix; - const char *msg; - int user_err; + enum { + _Py_INIT_ERR_TYPE_OK=0, + _Py_INIT_ERR_TYPE_ERROR=1, + _Py_INIT_ERR_TYPE_EXIT=2 + } _type; + const char *_func; + const char *err_msg; +#ifdef MS_WINDOWS + unsigned int exitcode; +#else int exitcode; +#endif } _PyInitError; /* Almost all errors causing Python initialization to fail */ @@ -33,18 +31,25 @@ typedef struct { #endif #define _Py_INIT_OK() \ - (_PyInitError){.prefix = NULL, .msg = NULL, .user_err = 0, .exitcode = -1} -#define _Py_INIT_ERR(MSG) \ - (_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 0, .exitcode = -1} -/* Error that can be fixed by the user like invalid input parameter. - Don't abort() the process on such error. */ -#define _Py_INIT_USER_ERR(MSG) \ - (_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 1, .exitcode = -1} -#define _Py_INIT_NO_MEMORY() _Py_INIT_USER_ERR("memory allocation failed") + (_PyInitError){._type = _Py_INIT_ERR_TYPE_OK,} + /* other fields are set to 0 */ +#define _Py_INIT_ERR(ERR_MSG) \ + (_PyInitError){ \ + ._type = _Py_INIT_ERR_TYPE_ERROR, \ + ._func = _Py_INIT_GET_FUNC(), \ + .err_msg = (ERR_MSG)} + /* other fields are set to 0 */ +#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed") #define _Py_INIT_EXIT(EXITCODE) \ - (_PyInitError){.prefix = NULL, .msg = NULL, .user_err = 0, .exitcode = (EXITCODE)} + (_PyInitError){ \ + ._type = _Py_INIT_ERR_TYPE_EXIT, \ + .exitcode = (EXITCODE)} +#define _Py_INIT_IS_ERROR(err) \ + (err._type == _Py_INIT_ERR_TYPE_ERROR) +#define _Py_INIT_IS_EXIT(err) \ + (err._type == _Py_INIT_ERR_TYPE_EXIT) #define _Py_INIT_FAILED(err) \ - (err.msg != NULL || err.exitcode != -1) + (err._type != _Py_INIT_ERR_TYPE_OK) /* --- _PyWstrList ------------------------------------------------ */ @@ -60,7 +65,12 @@ typedef struct { /* --- _PyPreConfig ----------------------------------------------- */ +#define _Py_CONFIG_VERSION 1 + typedef struct { + int _config_version; /* Internal configuration version, + used for ABI compatibility */ + /* If greater than 0, enable isolated mode: sys.path contains neither the script's directory nor the user's site-packages directory. @@ -73,8 +83,20 @@ typedef struct { set to !Py_IgnoreEnvironmentFlag. */ int use_environment; - int coerce_c_locale; /* PYTHONCOERCECLOCALE, -1 means unknown */ - int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */ + /* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538) + + Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1. + Set to 2 if the user preferred LC_CTYPE locale is "C". + + If it is equal to 1, LC_CTYPE locale is read to decide it it should be + coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2 + if the LC_CTYPE locale must be coerced. */ + int coerce_c_locale; + + /* Emit a warning if the LC_CTYPE locale is coerced? + + Disabled by default. Set to 1 by PYTHONCOERCECLOCALE=warn. */ + int coerce_c_locale_warn; #ifdef MS_WINDOWS /* If greater than 1, use the "mbcs" encoding instead of the UTF-8 @@ -88,9 +110,17 @@ typedef struct { int legacy_windows_fs_encoding; #endif - /* Enable UTF-8 mode? - Set by -X utf8 command line option and PYTHONUTF8 environment variable. - If set to -1 (default), inherit Py_UTF8Mode value. */ + /* Enable UTF-8 mode? (PEP 540) + + Disabled by default (equals to 0). + + Set to 1 by "-X utf8" and "-X utf8=1" command line options. + Set to 1 by PYTHONUTF8=1 environment variable. + + Set to 0 by "-X utf8=0" and PYTHONUTF8=0. + + If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or + "POSIX", otherwise inherit Py_UTF8Mode value. */ int utf8_mode; int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */ @@ -107,16 +137,22 @@ typedef struct { #define _PyPreConfig_INIT \ (_PyPreConfig){ \ _PyPreConfig_WINDOWS_INIT \ + ._config_version = _Py_CONFIG_VERSION, \ .isolated = -1, \ .use_environment = -1, \ - .coerce_c_locale = -1, \ - .utf8_mode = -1} + .dev_mode = -1, \ + .allocator = NULL} /* --- _PyCoreConfig ---------------------------------------------- */ typedef struct { - _PyPreConfig preconfig; + int _config_version; /* Internal configuration version, + used for ABI compatibility */ + + int isolated; /* Isolated mode? see _PyPreConfig.isolated */ + int use_environment; /* Use environment variables? see _PyPreConfig.use_environment */ + int dev_mode; /* Development mode? See _PyPreConfig.dev_mode */ /* Install signal handlers? Yes by default. */ int install_signal_handlers; @@ -171,8 +207,8 @@ typedef struct { See Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors. */ - char *filesystem_encoding; - char *filesystem_errors; + wchar_t *filesystem_encoding; + wchar_t *filesystem_errors; wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ wchar_t *program_name; /* Program name, see also Py_GetProgramName() */ @@ -298,13 +334,13 @@ typedef struct { Value set from PYTHONIOENCODING environment variable and Py_SetStandardStreamEncoding() function. See also 'stdio_errors' attribute. */ - char *stdio_encoding; + wchar_t *stdio_encoding; /* Error handler of sys.stdin and sys.stdout. Value set from PYTHONIOENCODING environment variable and Py_SetStandardStreamEncoding() function. See also 'stdio_encoding' attribute. */ - char *stdio_errors; + wchar_t *stdio_errors; #ifdef MS_WINDOWS /* If greater than zero, use io.FileIO instead of WindowsConsoleIO for sys @@ -336,7 +372,7 @@ typedef struct { Needed by freeze_importlib. */ int _install_importlib; - /* Value of the --check-hash-based-pycs configure option. Valid values: + /* Value of the --check-hash-based-pycs command line option: - "default" means the 'check_source' flag in hash-based pycs determines invalidation @@ -345,11 +381,10 @@ typedef struct { - "never" causes the interpreter to always assume hash-based pycs are valid - Set by the --check-hash-based-pycs command line option. The default value is "default". See PEP 552 "Deterministic pycs" for more details. */ - const char *_check_hash_pycs_mode; + wchar_t *check_hash_pycs_mode; /* If greater than 0, suppress _PyPathConfig_Calculate() warnings. @@ -368,7 +403,10 @@ typedef struct { #define _PyCoreConfig_INIT \ (_PyCoreConfig){ \ _PyCoreConfig_WINDOWS_INIT \ - .preconfig = _PyPreConfig_INIT, \ + ._config_version = _Py_CONFIG_VERSION, \ + .isolated = -1, \ + .use_environment = -1, \ + .dev_mode = -1, \ .install_signal_handlers = 1, \ .use_hash_seed = -1, \ .faulthandler = -1, \ @@ -386,16 +424,10 @@ typedef struct { .user_site_directory = -1, \ .buffered_stdio = -1, \ ._install_importlib = 1, \ - ._check_hash_pycs_mode = "default", \ + .check_hash_pycs_mode = NULL, \ ._frozen = -1} /* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ - -/* --- Function used for testing ---------------------------------- */ - -PyAPI_FUNC(PyObject *) _Py_GetGlobalVariablesAsDict(void); -PyAPI_FUNC(PyObject *) _PyCoreConfig_AsDict(const _PyCoreConfig *config); - #ifdef __cplusplus } #endif diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 64d196a722e..ba52a483582 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -446,6 +446,21 @@ PyAPI_FUNC(void) _PyObject_AssertFailed( int line, const char *function); +/* Check if an object is consistent. For example, ensure that the reference + counter is greater than or equal to 1, and ensure that ob_type is not NULL. + + Call _PyObject_AssertFailed() if the object is inconsistent. + + If check_content is zero, only check header fields: reduce the overhead. + + The function always return 1. The return value is just here to be able to + write: + + assert(_PyObject_CheckConsistency(obj, 1)); */ +PyAPI_FUNC(int) _PyObject_CheckConsistency( + PyObject *op, + int check_content); + #ifdef __cplusplus } #endif diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 1caeb98e993..2366c774e7f 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -14,35 +14,36 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, /* PEP 432 Multi-phase initialization API (Private while provisional!) */ -PyAPI_FUNC(_PyInitError) _Py_PreInitialize(void); -PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig( - _PyPreConfig *preconfig); +PyAPI_FUNC(_PyInitError) _Py_PreInitialize( + const _PyPreConfig *src_config); +PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromArgs( + const _PyPreConfig *src_config, + int argc, + char **argv); +PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromWideArgs( + const _PyPreConfig *src_config, + int argc, + wchar_t **argv); -PyAPI_FUNC(_PyInitError) _Py_InitializeCore( - PyInterpreterState **interp, - const _PyCoreConfig *); PyAPI_FUNC(int) _Py_IsCoreInitialized(void); -PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read( - _PyMainInterpreterConfig *config, - const _PyCoreConfig *core_config); -PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *); -PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy( - _PyMainInterpreterConfig *config, - const _PyMainInterpreterConfig *config2); -/* Used by _testcapi.get_main_config() */ -PyAPI_FUNC(PyObject*) _PyMainInterpreterConfig_AsDict( - const _PyMainInterpreterConfig *config); - -PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter( - PyInterpreterState *interp, - const _PyMainInterpreterConfig *); - /* Initialization and finalization */ PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig( const _PyCoreConfig *config); +PyAPI_FUNC(_PyInitError) _Py_InitializeFromArgs( + const _PyCoreConfig *config, + int argc, + char **argv); +PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs( + const _PyCoreConfig *config, + int argc, + wchar_t **argv); + +PyAPI_FUNC(int) _Py_RunMain(void); + + PyAPI_FUNC(void) _Py_NO_RETURN _Py_ExitInitError(_PyInitError err); /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level diff --git a/Include/cpython/pymem.h b/Include/cpython/pymem.h new file mode 100644 index 00000000000..bd66506639a --- /dev/null +++ b/Include/cpython/pymem.h @@ -0,0 +1,99 @@ +#ifndef Py_CPYTHON_PYMEM_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); +PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyMem_RawFree(void *ptr); + +/* Configure the Python memory allocators. Pass NULL to use default + allocators. */ +PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt); + +/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ +PyAPI_FUNC(const char*) _PyMem_GetAllocatorsName(void); + +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); + +/* strdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); + +/* strdup() using PyMem_Malloc() */ +PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); + +/* wcsdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); + + +typedef enum { + /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ + PYMEM_DOMAIN_RAW, + + /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ + PYMEM_DOMAIN_MEM, + + /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ + PYMEM_DOMAIN_OBJ +} PyMemAllocatorDomain; + +typedef struct { + /* user context passed as the first argument to the 4 functions */ + void *ctx; + + /* allocate a memory block */ + void* (*malloc) (void *ctx, size_t size); + + /* allocate a memory block initialized by zeros */ + void* (*calloc) (void *ctx, size_t nelem, size_t elsize); + + /* allocate or resize a memory block */ + void* (*realloc) (void *ctx, void *ptr, size_t new_size); + + /* release a memory block */ + void (*free) (void *ctx, void *ptr); +} PyMemAllocatorEx; + +/* Get the memory block allocator of the specified domain. */ +PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Set the memory block allocator of the specified domain. + + The new allocator must return a distinct non-NULL pointer when requesting + zero bytes. + + For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL + is not held when the allocator is called. + + If the new allocator is not a hook (don't call the previous allocator), the + PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks + on top on the new allocator. */ +PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Setup hooks to detect bugs in the following Python memory allocator + functions: + + - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() + - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() + - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() + + Newly allocated memory is filled with the byte 0xCB, freed memory is filled + with the byte 0xDB. Additional checks: + + - detect API violations, ex: PyObject_Free() called on a buffer allocated + by PyMem_Malloc() + - detect write before the start of the buffer (buffer underflow) + - detect write after the end of the buffer (buffer overflow) + + The function does nothing if Python is not compiled is debug mode. */ +PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); + +#ifdef __cplusplus +} +#endif diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 5439d07e6af..94331f35e1b 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -8,33 +8,10 @@ extern "C" { #include "cpython/coreconfig.h" -/* Placeholders while working on the new configuration API - * - * See PEP 432 for final anticipated contents - */ -typedef struct { - int install_signal_handlers; /* Install signal handlers? -1 means unset */ - PyObject *argv; /* sys.argv list, can be NULL */ - PyObject *executable; /* sys.executable str */ - PyObject *prefix; /* sys.prefix str */ - PyObject *base_prefix; /* sys.base_prefix str, can be NULL */ - PyObject *exec_prefix; /* sys.exec_prefix str */ - PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */ - PyObject *warnoptions; /* sys.warnoptions list, can be NULL */ - PyObject *xoptions; /* sys._xoptions dict, can be NULL */ - PyObject *module_search_path; /* sys.path list */ - PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */ -} _PyMainInterpreterConfig; - -#define _PyMainInterpreterConfig_INIT \ - (_PyMainInterpreterConfig){.install_signal_handlers = -1} -/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ - PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(PyInterpreterState *); -PyAPI_FUNC(_PyMainInterpreterConfig *) _PyInterpreterState_GetMainConfig(PyInterpreterState *); PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); @@ -178,9 +155,6 @@ PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(void) _PyState_ClearModules(void); PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); -PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); -PyAPI_FUNC(void) _PyGILState_Reinit(void); /* Similar to PyThreadState_Get(), but don't issue a fatal error * if it is NULL. */ diff --git a/Include/grammar.h b/Include/grammar.h index 68b928c9718..4b66b1e9b97 100644 --- a/Include/grammar.h +++ b/Include/grammar.h @@ -13,7 +13,7 @@ extern "C" { typedef struct { int lb_type; - char *lb_str; + const char *lb_str; } label; #define EMPTY 0 /* Label number 0 is by definition the empty label */ @@ -22,7 +22,7 @@ typedef struct { typedef struct { int ll_nlabels; - label *ll_label; + const label *ll_label; } labellist; /* An arc from one state to another */ @@ -36,7 +36,7 @@ typedef struct { typedef struct { int s_narcs; - arc *s_arc; /* Array of arcs */ + const arc *s_arc; /* Array of arcs */ /* Optional accelerators */ int s_lower; /* Lowest label index */ @@ -59,34 +59,18 @@ typedef struct { typedef struct { int g_ndfas; - dfa *g_dfa; /* Array of DFAs */ - labellist g_ll; + const dfa *g_dfa; /* Array of DFAs */ + const labellist g_ll; int g_start; /* Start symbol of the grammar */ int g_accel; /* Set if accelerators present */ } grammar; /* FUNCTIONS */ - -grammar *newgrammar(int start); -void freegrammar(grammar *g); -dfa *adddfa(grammar *g, int type, const char *name); -int addstate(dfa *d); -void addarc(dfa *d, int from, int to, int lbl); -dfa *PyGrammar_FindDFA(grammar *g, int type); - -int addlabel(labellist *ll, int type, const char *str); -int findlabel(labellist *ll, int type, const char *str); +const dfa *PyGrammar_FindDFA(grammar *g, int type); const char *PyGrammar_LabelRepr(label *lb); -void translatelabels(grammar *g); - -void addfirstsets(grammar *g); - void PyGrammar_AddAccelerators(grammar *g); void PyGrammar_RemoveAccelerators(grammar *); -void printgrammar(grammar *g, FILE *fp); -void printnonterminals(grammar *g, FILE *fp); - #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_accu.h b/Include/internal/pycore_accu.h index 4350db58a26..d346222e4dd 100644 --- a/Include/internal/pycore_accu.h +++ b/Include/internal/pycore_accu.h @@ -9,8 +9,8 @@ extern "C" { *** Its definition may be changed or removed at any moment. ***/ -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif /* diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 7aa7eed6f7c..336bc3fec27 100644 --- a/Include/internal/pycore_atomic.h +++ b/Include/internal/pycore_atomic.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "dynamic_annotations.h" @@ -261,13 +261,13 @@ typedef struct _Py_atomic_int { #define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ switch (ORDER) { \ case _Py_memory_order_acquire: \ - _InterlockedExchange64_HLEAcquire((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + _InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ break; \ case _Py_memory_order_release: \ - _InterlockedExchange64_HLERelease((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + _InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ break; \ default: \ - _InterlockedExchange64((__int64 volatile*)ATOMIC_VAL, (__int64)NEW_VAL); \ + _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ break; \ } #else @@ -277,13 +277,13 @@ typedef struct _Py_atomic_int { #define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ switch (ORDER) { \ case _Py_memory_order_acquire: \ - _InterlockedExchange_HLEAcquire((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + _InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ break; \ case _Py_memory_order_release: \ - _InterlockedExchange_HLERelease((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + _InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ break; \ default: \ - _InterlockedExchange((volatile long*)ATOMIC_VAL, (int)NEW_VAL); \ + _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ break; \ } @@ -292,7 +292,7 @@ typedef struct _Py_atomic_int { gil_created() uses -1 as a sentinel value, if this returns a uintptr_t it will do an unsigned compare and crash */ -inline intptr_t _Py_atomic_load_64bit(volatile uintptr_t* value, int order) { +inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { __int64 old; switch (order) { case _Py_memory_order_acquire: @@ -323,11 +323,14 @@ inline intptr_t _Py_atomic_load_64bit(volatile uintptr_t* value, int order) { return old; } +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) + #else -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) *(ATOMIC_VAL) +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) #endif -inline int _Py_atomic_load_32bit(volatile int* value, int order) { +inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { long old; switch (order) { case _Py_memory_order_acquire: @@ -358,16 +361,19 @@ inline int _Py_atomic_load_32bit(volatile int* value, int order) { return old; } +#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) + #define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ if (sizeof((ATOMIC_VAL)->_value) == 8) { \ - _Py_atomic_store_64bit((volatile long long*)&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) } else { \ - _Py_atomic_store_32bit((volatile long*)&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) } + _Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \ + _Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) } #define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ ( \ sizeof((ATOMIC_VAL)->_value) == 8 ? \ - _Py_atomic_load_64bit((volatile long long*)&((ATOMIC_VAL)->_value), ORDER) : \ - _Py_atomic_load_32bit((volatile long*)&((ATOMIC_VAL)->_value), ORDER) \ + _Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \ + _Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \ ) #elif defined(_M_ARM) || defined(_M_ARM64) typedef enum _Py_memory_order { @@ -422,7 +428,7 @@ typedef struct _Py_atomic_int { gil_created() uses -1 as a sentinel value, if this returns a uintptr_t it will do an unsigned compare and crash */ -inline intptr_t _Py_atomic_load_64bit(volatile uintptr_t* value, int order) { +inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { uintptr_t old; switch (order) { case _Py_memory_order_acquire: @@ -453,11 +459,14 @@ inline intptr_t _Py_atomic_load_64bit(volatile uintptr_t* value, int order) { return old; } +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) + #else -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) *(ATOMIC_VAL) +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) #endif -inline int _Py_atomic_load_32bit(volatile int* value, int order) { +inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { int old; switch (order) { case _Py_memory_order_acquire: @@ -488,16 +497,19 @@ inline int _Py_atomic_load_32bit(volatile int* value, int order) { return old; } +#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) + #define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ if (sizeof((ATOMIC_VAL)->_value) == 8) { \ - _Py_atomic_store_64bit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) } else { \ - _Py_atomic_store_32bit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) } + _Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \ + _Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } #define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ ( \ sizeof((ATOMIC_VAL)->_value) == 8 ? \ - _Py_atomic_load_64bit(&((ATOMIC_VAL)->_value), ORDER) : \ - _Py_atomic_load_32bit(&((ATOMIC_VAL)->_value), ORDER) \ + _Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \ + _Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \ ) #endif #else /* !gcc x86 !_msc_ver */ @@ -529,16 +541,16 @@ typedef struct _Py_atomic_int { /* Standardized shortcuts. */ #define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ - _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, _Py_memory_order_seq_cst) + _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst) #define _Py_atomic_load(ATOMIC_VAL) \ - _Py_atomic_load_explicit(ATOMIC_VAL, _Py_memory_order_seq_cst) + _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst) /* Python-local extensions */ #define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ - _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, _Py_memory_order_relaxed) + _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed) #define _Py_atomic_load_relaxed(ATOMIC_VAL) \ - _Py_atomic_load_explicit(ATOMIC_VAL, _Py_memory_order_relaxed) + _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed) #ifdef __cplusplus } diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 2ead96c7abe..0bb19f1aa3b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "pycore_atomic.h" diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h index a12b6994ad5..8b89d709510 100644 --- a/Include/internal/pycore_condvar.h +++ b/Include/internal/pycore_condvar.h @@ -1,8 +1,8 @@ #ifndef Py_INTERNAL_CONDVAR_H #define Py_INTERNAL_CONDVAR_H -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #ifndef _POSIX_THREADS diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h index 70701cdd11d..5e1ba0d0393 100644 --- a/Include/internal/pycore_context.h +++ b/Include/internal/pycore_context.h @@ -1,8 +1,8 @@ #ifndef Py_INTERNAL_CONTEXT_H #define Py_INTERNAL_CONTEXT_H -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "pycore_hamt.h" diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index 29261df5af7..d48904e482a 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -4,33 +4,11 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif - -/* --- _PyPreCmdline ------------------------------------------------- */ - -typedef struct { - _PyWstrList argv; - _PyWstrList xoptions; /* "-X value" option */ - int use_environment; /* -E option */ - int isolated; /* -I option */ -} _PyPreCmdline; - -#define _PyPreCmdline_INIT \ - (_PyPreCmdline){ \ - .use_environment = -1, \ - .isolated = -1} -/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ - -PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline); -PyAPI_FUNC(_PyInitError) _PyPreCmdline_Init(_PyPreCmdline *cmdline, - const _PyArgv *args); -PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline); -PyAPI_FUNC(void) _PyPreCmdline_SetPreConfig( - const _PyPreCmdline *cmdline, - _PyPreConfig *config); +#include "pycore_pystate.h" /* _PyRuntimeState */ /* --- _PyWstrList ------------------------------------------------ */ @@ -44,20 +22,24 @@ PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list, PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list, const wchar_t *item); PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list); +PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list, + const _PyWstrList *list2); /* --- _PyArgv ---------------------------------------------------- */ +typedef struct { + int argc; + int use_bytes_argv; + char **bytes_argv; + wchar_t **wchar_argv; +} _PyArgv; + PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list); -/* --- Py_GetArgcArgv() helpers ----------------------------------- */ - -PyAPI_FUNC(void) _Py_ClearArgcArgv(void); - - -/* --- _PyPreConfig ----------------------------------------------- */ +/* --- Helper functions ------------------------------------------- */ PyAPI_FUNC(int) _Py_str_to_int( const char *str, @@ -65,21 +47,54 @@ PyAPI_FUNC(int) _Py_str_to_int( PyAPI_FUNC(const wchar_t*) _Py_get_xoption( const _PyWstrList *xoptions, const wchar_t *name); +PyAPI_FUNC(const char*) _Py_GetEnv( + int use_environment, + const char *name); +PyAPI_FUNC(void) _Py_get_env_flag( + int use_environment, + int *flag, + const char *name); + +/* Py_GetArgcArgv() helper */ +PyAPI_FUNC(void) _Py_ClearArgcArgv(void); + + +/* --- _PyPreCmdline ------------------------------------------------- */ + +typedef struct { + _PyWstrList argv; + _PyWstrList xoptions; /* "-X value" option */ + int isolated; /* -I option */ + int use_environment; /* -E option */ + int dev_mode; /* -X dev and PYTHONDEVMODE */ +} _PyPreCmdline; + +#define _PyPreCmdline_INIT \ + (_PyPreCmdline){ \ + .use_environment = -1, \ + .isolated = -1, \ + .dev_mode = -1} +/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ + +PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline); +PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, + const _PyArgv *args); +PyAPI_FUNC(int) _PyPreCmdline_SetCoreConfig( + const _PyPreCmdline *cmdline, + _PyCoreConfig *config); +PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline, + const _PyPreConfig *preconfig); + + +/* --- _PyPreConfig ----------------------------------------------- */ PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config); PyAPI_FUNC(int) _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2); -PyAPI_FUNC(void) _PyPreConfig_GetGlobalConfig(_PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_SetGlobalConfig(const _PyPreConfig *config); -PyAPI_FUNC(const char*) _PyPreConfig_GetEnv(const _PyPreConfig *config, - const char *name); -PyAPI_FUNC(void) _Py_get_env_flag(_PyPreConfig *config, - int *flag, - const char *name); -PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config); -PyAPI_FUNC(int) _PyPreConfig_AsDict(const _PyPreConfig *config, - PyObject *dict); -PyAPI_FUNC(_PyInitError) _PyPreConfig_ReadFromArgv(_PyPreConfig *config, +PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config); +PyAPI_FUNC(void) _PyCoreConfig_GetCoreConfig(_PyPreConfig *config, + const _PyCoreConfig *core_config); +PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args); PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config); @@ -87,28 +102,36 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config); /* --- _PyCoreConfig ---------------------------------------------- */ PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); -PyAPI_FUNC(int) _PyCoreConfig_Copy( +PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy( _PyCoreConfig *config, const _PyCoreConfig *config2); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString( + wchar_t **config_str, + const wchar_t *str); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale( + wchar_t **config_str, + const char *str); PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig( const _PyCoreConfig *config); -PyAPI_FUNC(void) _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config); -PyAPI_FUNC(void) _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config); -PyAPI_FUNC(const char*) _PyCoreConfig_GetEnv( - const _PyCoreConfig *config, - const char *name); -PyAPI_FUNC(int) _PyCoreConfig_GetEnvDup( - const _PyCoreConfig *config, - wchar_t **dest, - wchar_t *wname, - char *name); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config, - const _PyPreConfig *preconfig); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, - const _PyArgv *args, - const _PyPreConfig *preconfig); -PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); +PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config, + _PyRuntimeState *runtime); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPyArgv( + _PyCoreConfig *config, + const _PyArgv *args); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv( + _PyCoreConfig *config, + int argc, + char **argv); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, + int argc, + wchar_t **argv); + + +/* --- Function used for testing ---------------------------------- */ + +PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); #ifdef __cplusplus } diff --git a/Include/internal/pycore_getopt.h b/Include/internal/pycore_getopt.h index 0d1897c75a6..834b8c8a140 100644 --- a/Include/internal/pycore_getopt.h +++ b/Include/internal/pycore_getopt.h @@ -1,8 +1,8 @@ #ifndef Py_INTERNAL_PYGETOPT_H #define Py_INTERNAL_PYGETOPT_H -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif extern int _PyOS_opterr; diff --git a/Include/internal/pycore_gil.h b/Include/internal/pycore_gil.h index 014e75fd182..7de316397b1 100644 --- a/Include/internal/pycore_gil.h +++ b/Include/internal/pycore_gil.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "pycore_condvar.h" diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h index 8b2ce1fc96c..e65aef5e21a 100644 --- a/Include/internal/pycore_hamt.h +++ b/Include/internal/pycore_hamt.h @@ -1,8 +1,8 @@ #ifndef Py_INTERNAL_HAMT_H #define Py_INTERNAL_HAMT_H -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #define _Py_HAMT_MAX_TREE_DEPTH 7 diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index a88b626332f..81548f81919 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -4,12 +4,16 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "pycore_pystate.h" /* _PyRuntime */ +PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); +PyAPI_FUNC(int) _PyUnicode_CheckConsistency(PyObject *op, int check_content); +PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); + /* Tell the GC to track this object. * * NB: While the object is tracked by the collector, it must be safe to call the diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index 80d86a0dd1b..9eb8e88df76 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif typedef struct _PyPathConfig { diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h index babbc95b879..a229f8d8b7f 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -1,8 +1,8 @@ #ifndef Py_INTERNAL_HASH_H #define Py_INTERNAL_HASH_H -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 9514b1c46a2..adb1f5d90a5 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -4,20 +4,27 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_coreconfig.h" /* _PyArgv */ +#include "pycore_pystate.h" /* _PyRuntimeState */ + /* True if the main interpreter thread exited due to an unhandled * KeyboardInterrupt exception, suggesting the user pressed ^C. */ PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv); -PyAPI_FUNC(int) _Py_SetFileSystemEncoding( +extern int _Py_SetFileSystemEncoding( const char *encoding, const char *errors); -PyAPI_FUNC(void) _Py_ClearFileSystemEncoding(void); +extern void _Py_ClearFileSystemEncoding(void); +extern _PyInitError _PyUnicode_InitEncodings(PyInterpreterState *interp); +#ifdef MS_WINDOWS +extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void); +#endif PyAPI_FUNC(void) _Py_ClearStandardStreamEncoding(void); @@ -32,10 +39,13 @@ extern _PyInitError _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(void); extern _PyInitError _PySys_Create( + _PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p); extern _PyInitError _PySys_SetPreliminaryStderr(PyObject *sysdict); -extern int _PySys_InitMain(PyInterpreterState *interp); +extern int _PySys_InitMain( + _PyRuntimeState *runtime, + PyInterpreterState *interp); extern _PyInitError _PyImport_Init(PyInterpreterState *interp); extern _PyInitError _PyExc_Init(void); extern _PyInitError _PyBuiltins_AddExceptions(PyObject * bltinmod); @@ -63,7 +73,7 @@ extern void PyAsyncGen_Fini(void); extern void _PyExc_Fini(void); extern void _PyImport_Fini(void); extern void _PyImport_Fini2(void); -extern void _PyGC_Fini(void); +extern void _PyGC_Fini(_PyRuntimeState *runtime); extern void _PyType_Fini(void); extern void _Py_HashRandomization_Fini(void); extern void _PyUnicode_Fini(void); @@ -71,11 +81,22 @@ extern void PyLong_Fini(void); extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); extern int _PyTraceMalloc_Fini(void); +extern void _PyWarnings_Fini(_PyRuntimeState *runtime); -extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); -extern void _PyGILState_Fini(void); +extern void _PyGILState_Init( + _PyRuntimeState *runtime, + PyInterpreterState *interp, + PyThreadState *tstate); +extern void _PyGILState_Fini(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void); +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); + +PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPyArgv( + const _PyPreConfig *src_config, + const _PyArgv *args); +PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig( + const _PyCoreConfig *coreconfig, + const _PyArgv *args); #ifdef __cplusplus } diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 1e7da87cd75..20f3b5e4006 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "objimpl.h" @@ -155,6 +155,30 @@ PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( PyMemAllocatorDomain domain, PyMemAllocatorEx *old_alloc); +/* Heuristic checking if a pointer value is newly allocated + (uninitialized) or newly freed. The pointer is not dereferenced, only the + pointer value is checked. + + The heuristic relies on the debug hooks on Python memory allocators which + fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory + with DEADBYTE (0xDD). Detect also "untouchable bytes" marked + with FORBIDDENBYTE (0xFD). */ +static inline int _PyMem_IsPtrFreed(void *ptr) +{ + uintptr_t value = (uintptr_t)ptr; +#if SIZEOF_VOID_P == 8 + return (value == (uintptr_t)0xCDCDCDCDCDCDCDCD + || value == (uintptr_t)0xDDDDDDDDDDDDDDDD + || value == (uintptr_t)0xFDFDFDFDFDFDFDFD); +#elif SIZEOF_VOID_P == 4 + return (value == (uintptr_t)0xCDCDCDCD + || value == (uintptr_t)0xDDDDDDDD + || value == (uintptr_t)0xFDFDFDFD); +#else +# error "unknown pointer size" +#endif +} + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 27c6eea6aa8..67bcd147e28 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "cpython/coreconfig.h" @@ -56,10 +56,16 @@ struct _is { PyObject *codec_search_cache; PyObject *codec_error_registry; int codecs_initialized; - int fscodec_initialized; + + /* fs_codec.encoding is initialized to NULL. + Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ + struct { + char *encoding; /* Filesystem encoding (encoded to UTF-8) */ + char *errors; /* Filesystem errors (encoded to UTF-8) */ + _Py_error_handler error_handler; + } fs_codec; _PyCoreConfig core_config; - _PyMainInterpreterConfig config; #ifdef HAVE_DLOPEN int dlopenflags; #endif @@ -186,9 +192,9 @@ typedef struct pyruntimestate { /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */ PyAPI_DATA(_PyRuntimeState) _PyRuntime; -PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *); -PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *); -PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(void); +PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); /* Initialize _PyRuntimeState. Return NULL on success, or return an error message on failure. */ @@ -232,8 +238,15 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); /* Other */ -PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *); -PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(void); +PyAPI_FUNC(void) _PyThreadState_Init( + _PyRuntimeState *runtime, + PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); + +PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); + +PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); #ifdef __cplusplus } diff --git a/Include/internal/pycore_tupleobject.h b/Include/internal/pycore_tupleobject.h index d0c5b620d35..9fcfc5c6ec7 100644 --- a/Include/internal/pycore_tupleobject.h +++ b/Include/internal/pycore_tupleobject.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "tupleobject.h" diff --git a/Include/internal/pycore_warnings.h b/Include/internal/pycore_warnings.h index 91bf90232f5..73e5350aff1 100644 --- a/Include/internal/pycore_warnings.h +++ b/Include/internal/pycore_warnings.h @@ -4,8 +4,8 @@ extern "C" { #endif -#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) -# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN define" +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" #endif #include "object.h" diff --git a/Include/object.h b/Include/object.h index a729335750c..13e88a6dc6f 100644 --- a/Include/object.h +++ b/Include/object.h @@ -54,13 +54,8 @@ A standard interface exists for objects that contain an array of items whose size is determined when the object is allocated. */ -/* Py_DEBUG implies Py_TRACE_REFS. */ -#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS) -#define Py_TRACE_REFS -#endif - -/* Py_TRACE_REFS implies Py_REF_DEBUG. */ -#if defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +/* Py_DEBUG implies Py_REF_DEBUG. */ +#if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) #define Py_REF_DEBUG #endif @@ -440,6 +435,7 @@ static inline void _Py_NewReference(PyObject *op) static inline void _Py_ForgetReference(PyObject *op) { + (void)op; /* may be unused, shut up -Wunused-parameter */ _Py_INC_TPFREES(op); } #endif /* !Py_TRACE_REFS */ @@ -458,6 +454,8 @@ static inline void _Py_INCREF(PyObject *op) static inline void _Py_DECREF(const char *filename, int lineno, PyObject *op) { + (void)filename; /* may be unused, shut up -Wunused-parameter */ + (void)lineno; /* may be unused, shut up -Wunused-parameter */ _Py_DEC_REFTOTAL; if (--op->ob_refcnt != 0) { #ifdef Py_REF_DEBUG diff --git a/Include/objimpl.h b/Include/objimpl.h index f475ed001d0..2337d8a56c7 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -138,6 +138,9 @@ _PyObject_INIT(PyObject *op, PyTypeObject *typeobj) { assert(op != NULL); Py_TYPE(op) = typeobj; + if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(typeobj); + } _Py_NewReference(op); return op; } diff --git a/Include/patchlevel.h b/Include/patchlevel.h index e9edf462b14..da787f27cc8 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 8 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 2 +#define PY_RELEASE_SERIAL 4 /* Version as a string */ -#define PY_VERSION "3.8.0a2+" +#define PY_VERSION "3.8.0a4+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/pgenheaders.h b/Include/pgenheaders.h deleted file mode 100644 index dbc5e0a5f13..00000000000 --- a/Include/pgenheaders.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Py_PGENHEADERS_H -#define Py_PGENHEADERS_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Include files and extern declarations used by most of the parser. */ - -#include "Python.h" - -PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) - Py_GCC_ATTRIBUTE((format(printf, 1, 2))); -PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) - Py_GCC_ATTRIBUTE((format(printf, 1, 2))); - -#define addarc _Py_addarc -#define addbit _Py_addbit -#define adddfa _Py_adddfa -#define addfirstsets _Py_addfirstsets -#define addlabel _Py_addlabel -#define addstate _Py_addstate -#define delbitset _Py_delbitset -#define dumptree _Py_dumptree -#define findlabel _Py_findlabel -#define freegrammar _Py_freegrammar -#define mergebitset _Py_mergebitset -#define meta_grammar _Py_meta_grammar -#define newbitset _Py_newbitset -#define newgrammar _Py_newgrammar -#define pgen _Py_pgen -#define printgrammar _Py_printgrammar -#define printnonterminals _Py_printnonterminals -#define printtree _Py_printtree -#define samebitset _Py_samebitset -#define showtree _Py_showtree -#define tok_dump _Py_tok_dump -#define translatelabels _Py_translatelabels - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PGENHEADERS_H */ diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 5c6751868df..94af3cb3420 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -21,17 +21,6 @@ PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); #endif -#if defined(__clang__) || \ - (defined(__GNUC__) && \ - ((__GNUC__ >= 3) || \ - (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) -# define _Py_NO_RETURN __attribute__((__noreturn__)) -#elif defined(_MSC_VER) -# define _Py_NO_RETURN __declspec(noreturn) -#else -# define _Py_NO_RETURN -#endif - /* Defined in Python/pylifecycle.c */ PyAPI_FUNC(void) _Py_NO_RETURN Py_FatalError(const char *message); diff --git a/Include/pymacro.h b/Include/pymacro.h index 3f6ddbe9977..546f9c6e702 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -67,7 +67,7 @@ /* Define macros for inline documentation. */ -#define PyDoc_VAR(name) static char name[] +#define PyDoc_VAR(name) static const char name[] #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) #ifdef WITH_DOC_STRINGS #define PyDoc_STR(str) str diff --git a/Include/pymem.h b/Include/pymem.h index 23457adb5a4..07b380aa6e7 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -11,23 +11,6 @@ extern "C" { #endif -#ifndef Py_LIMITED_API -PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); -PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); -PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); -PyAPI_FUNC(void) PyMem_RawFree(void *ptr); - -/* Configure the Python memory allocators. Pass NULL to use default - allocators. */ -PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt); - -/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ -PyAPI_FUNC(const char*) _PyMem_GetAllocatorsName(void); - -PyAPI_FUNC(int) _PyMem_IsFreed(void *ptr, size_t size); -#endif /* !defined(Py_LIMITED_API) */ - - /* BEWARE: Each interface exports both functions and macros. Extension modules should @@ -67,23 +50,9 @@ PyAPI_FUNC(int) _PyMem_IsFreed(void *ptr, size_t size); */ PyAPI_FUNC(void *) PyMem_Malloc(size_t size); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); -#endif PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_Free(void *ptr); -#ifndef Py_LIMITED_API -/* strdup() using PyMem_RawMalloc() */ -PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); - -/* strdup() using PyMem_Malloc() */ -PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); - -/* wcsdup() using PyMem_RawMalloc() */ -PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); -#endif - /* Macros. */ /* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL @@ -132,72 +101,6 @@ PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); #define PyMem_Del PyMem_Free #define PyMem_DEL PyMem_FREE -#ifndef Py_LIMITED_API -typedef enum { - /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ - PYMEM_DOMAIN_RAW, - - /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ - PYMEM_DOMAIN_MEM, - - /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ - PYMEM_DOMAIN_OBJ -} PyMemAllocatorDomain; - -typedef struct { - /* user context passed as the first argument to the 4 functions */ - void *ctx; - - /* allocate a memory block */ - void* (*malloc) (void *ctx, size_t size); - - /* allocate a memory block initialized by zeros */ - void* (*calloc) (void *ctx, size_t nelem, size_t elsize); - - /* allocate or resize a memory block */ - void* (*realloc) (void *ctx, void *ptr, size_t new_size); - - /* release a memory block */ - void (*free) (void *ctx, void *ptr); -} PyMemAllocatorEx; - -/* Get the memory block allocator of the specified domain. */ -PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, - PyMemAllocatorEx *allocator); - -/* Set the memory block allocator of the specified domain. - - The new allocator must return a distinct non-NULL pointer when requesting - zero bytes. - - For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL - is not held when the allocator is called. - - If the new allocator is not a hook (don't call the previous allocator), the - PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks - on top on the new allocator. */ -PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, - PyMemAllocatorEx *allocator); - -/* Setup hooks to detect bugs in the following Python memory allocator - functions: - - - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() - - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() - - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() - - Newly allocated memory is filled with the byte 0xCB, freed memory is filled - with the byte 0xDB. Additional checks: - - - detect API violations, ex: PyObject_Free() called on a buffer allocated - by PyMem_Malloc() - - detect write before the start of the buffer (buffer underflow) - - detect write after the end of the buffer (buffer overflow) - - The function does nothing if Python is not compiled is debug mode. */ -PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); -#endif /* Py_LIMITED_API */ - /* bpo-35053: expose _Py_tracemalloc_config for performance: _Py_NewReference() needs an efficient check to test if tracemalloc is tracing. @@ -233,6 +136,13 @@ PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; .max_nframe = 1, \ .use_domain = 0} + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYMEM_H +# include "cpython/pymem.h" +# undef Py_CPYTHON_PYMEM_H +#endif + #ifdef __cplusplus } #endif diff --git a/Include/pyport.h b/Include/pyport.h index 4971a493cce..ab88a9ac5c5 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -5,6 +5,27 @@ #include + +/* Defines to build Python and its standard library: + * + * - Py_BUILD_CORE: Build Python core. Give access to Python internals, but + * should not be used by third-party modules. + * - Py_BUILD_CORE_BUILTIN: Build a Python stdlib module as a built-in module. + * - Py_BUILD_CORE_MODULE: Build a Python stdlib module as a dynamic library. + * + * Py_BUILD_CORE_BUILTIN and Py_BUILD_CORE_MODULE imply Py_BUILD_CORE. + * + * On Windows, Py_BUILD_CORE_MODULE exports "PyInit_xxx" symbol, whereas + * Py_BUILD_CORE_BUILTIN does not. + */ +#if defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE) +# define Py_BUILD_CORE +#endif +#if defined(Py_BUILD_CORE_MODULE) && !defined(Py_BUILD_CORE) +# define Py_BUILD_CORE +#endif + + /************************************************************************** Symbols and macros to supply platform-independent interfaces to basic C language & library operations whose spellings vary across platforms. @@ -406,7 +427,7 @@ extern "C" { #endif /* get and set x87 control word for VisualStudio/x86 */ -#if defined(_MSC_VER) && defined(_M_IX86) /* x87 only supported in x86 */ +#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) /* x87 not supported in 64-bit or ARM */ #define HAVE_PY_SET_53BIT_PRECISION 1 #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned int old_387controlword, new_387controlword, out_387controlword @@ -623,7 +644,7 @@ extern char * _getpty(int *, int, mode_t, int); /* only get special linkage if built as shared or platform is Cygwin */ #if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) # if defined(HAVE_DECLSPEC_DLL) -# if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) +# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) # define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE # define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE /* module init functions inside the core need no external linkage */ @@ -755,7 +776,7 @@ extern char * _getpty(int *, int, mode_t, int); #define PY_LITTLE_ENDIAN 1 #endif -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) +#ifdef Py_BUILD_CORE /* * Macros to protect CRT calls against instant termination when passed an * invalid parameter (issue23524). @@ -776,9 +797,9 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #endif /* Py_BUILD_CORE */ #ifdef __ANDROID__ -/* The Android langinfo.h header is not used. */ -#undef HAVE_LANGINFO_H -#undef CODESET + /* The Android langinfo.h header is not used. */ +# undef HAVE_LANGINFO_H +# undef CODESET #endif /* Maximum value of the Windows DWORD type */ @@ -789,7 +810,37 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; * for compatibility. */ #ifndef WITH_THREAD -#define WITH_THREAD +# define WITH_THREAD +#endif + +/* Check that ALT_SOABI is consistent with Py_TRACE_REFS: + ./configure --with-trace-refs should must be used to define Py_TRACE_REFS */ +#if defined(ALT_SOABI) && defined(Py_TRACE_REFS) +# error "Py_TRACE_REFS ABI is not compatible with release and debug ABI" +#endif + +#if defined(__ANDROID__) || defined(__VXWORKS__) + /* Ignore the locale encoding: force UTF-8 */ +# define _Py_FORCE_UTF8_LOCALE +#endif + +#if defined(_Py_FORCE_UTF8_LOCALE) || defined(__APPLE__) + /* Use UTF-8 as filesystem encoding */ +# define _Py_FORCE_UTF8_FS_ENCODING +#endif + +/* Mark a function which cannot return. Example: + + PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); */ +#if defined(__clang__) || \ + (defined(__GNUC__) && \ + ((__GNUC__ >= 3) || \ + (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) +# define _Py_NO_RETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +# define _Py_NO_RETURN __declspec(noreturn) +#else +# define _Py_NO_RETURN #endif #endif /* Py_PYPORT_H */ diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 6f0c6fc6554..e83846add98 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -165,7 +165,7 @@ PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; to an 8k margin. */ #define PYOS_STACK_MARGIN 2048 -#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1300 +#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 /* Enable stack checking under Microsoft C */ #define USE_STACKCHECK #endif diff --git a/Include/pythread.h b/Include/pythread.h index eb61033b2d9..bc1d92cd1ff 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -23,7 +23,7 @@ typedef enum PyLockStatus { PyAPI_FUNC(void) PyThread_init_thread(void); PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); -PyAPI_FUNC(void) PyThread_exit_thread(void); +PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 44ea5b41b2a..c14d8ca86a1 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -5631,8 +5631,6 @@ def __init__(self, value=None): def __repr__(self): return "(%r, %r, %r)" % (self.sign, self.int, self.exp) - __str__ = __repr__ - def _normalize(op1, op2, prec = 0): diff --git a/Lib/_pyio.py b/Lib/_pyio.py index b0593c3d3ab..af2ce30c278 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -292,16 +292,15 @@ class IOBase(metaclass=abc.ABCMeta): derived classes can override selectively; the default implementations represent a file that cannot be read, written or seeked. - Even though IOBase does not declare read, readinto, or write because + Even though IOBase does not declare read or write because their signatures will vary, implementations and clients should consider those methods part of the interface. Also, implementations may raise UnsupportedOperation when operations they do not support are called. The basic type used for binary data read from or written to a file is - bytes. Other bytes-like objects are accepted as method arguments too. In - some cases (such as readinto), a writable object is required. Text I/O - classes work with str data. + bytes. Other bytes-like objects are accepted as method arguments too. + Text I/O classes work with str data. Note that calling any method (even inquiries) on a closed stream is undefined. Implementations may raise OSError in this case. @@ -552,6 +551,11 @@ def readlines(self, hint=None): return lines def writelines(self, lines): + """Write a list of lines to the stream. + + Line separators are not added, so it is usual for each of the lines + provided to have a line separator at the end. + """ self._checkClosed() for line in lines: self.write(line) @@ -1763,8 +1767,7 @@ class TextIOBase(IOBase): """Base class for text I/O. This class provides a character and line based interface to stream - I/O. There is no readinto method because Python's character strings - are immutable. There is no public constructor. + I/O. There is no public constructor. """ def read(self, size=-1): diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 36fe7e0076c..9613ac2a114 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -16,10 +16,12 @@ import collections import collections.abc import concurrent.futures +import functools import heapq import itertools import os import socket +import stat import subprocess import threading import time @@ -40,6 +42,7 @@ from . import futures from . import protocols from . import sslproto +from . import staggered from . import tasks from . import transports from .log import logger @@ -158,6 +161,28 @@ def _ipaddr_info(host, port, family, type, proto): return None +def _interleave_addrinfos(addrinfos, first_address_family_count=1): + """Interleave list of addrinfo tuples by family.""" + # Group addresses by family + addrinfos_by_family = collections.OrderedDict() + for addr in addrinfos: + family = addr[0] + if family not in addrinfos_by_family: + addrinfos_by_family[family] = [] + addrinfos_by_family[family].append(addr) + addrinfos_lists = list(addrinfos_by_family.values()) + + reordered = [] + if first_address_family_count > 1: + reordered.extend(addrinfos_lists[0][:first_address_family_count - 1]) + del addrinfos_lists[0][:first_address_family_count - 1] + reordered.extend( + a for a in itertools.chain.from_iterable( + itertools.zip_longest(*addrinfos_lists) + ) if a is not None) + return reordered + + def _run_until_complete_cb(fut): if not fut.cancelled(): exc = fut.exception() @@ -870,12 +895,49 @@ def _check_sendfile_params(self, sock, file, offset, count): "offset must be a non-negative integer (got {!r})".format( offset)) + async def _connect_sock(self, exceptions, addr_info, local_addr_infos=None): + """Create, bind and connect one socket.""" + my_exceptions = [] + exceptions.append(my_exceptions) + family, type_, proto, _, address = addr_info + sock = None + try: + sock = socket.socket(family=family, type=type_, proto=proto) + sock.setblocking(False) + if local_addr_infos is not None: + for _, _, _, _, laddr in local_addr_infos: + try: + sock.bind(laddr) + break + except OSError as exc: + msg = ( + f'error while attempting to bind on ' + f'address {laddr!r}: ' + f'{exc.strerror.lower()}' + ) + exc = OSError(exc.errno, msg) + my_exceptions.append(exc) + else: # all bind attempts failed + raise my_exceptions.pop() + await self.sock_connect(sock, address) + return sock + except OSError as exc: + my_exceptions.append(exc) + if sock is not None: + sock.close() + raise + except: + if sock is not None: + sock.close() + raise + async def create_connection( self, protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + happy_eyeballs_delay=None, interleave=None): """Connect to a TCP server. Create a streaming transport connection to a given Internet host and @@ -910,6 +972,10 @@ async def create_connection( raise ValueError( 'ssl_handshake_timeout is only meaningful with ssl') + if happy_eyeballs_delay is not None and interleave is None: + # If using happy eyeballs, default to interleave addresses by family + interleave = 1 + if host is not None or port is not None: if sock is not None: raise ValueError( @@ -928,43 +994,31 @@ async def create_connection( flags=flags, loop=self) if not laddr_infos: raise OSError('getaddrinfo() returned empty list') + else: + laddr_infos = None + + if interleave: + infos = _interleave_addrinfos(infos, interleave) exceptions = [] - for family, type, proto, cname, address in infos: - try: - sock = socket.socket(family=family, type=type, proto=proto) - sock.setblocking(False) - if local_addr is not None: - for _, _, _, _, laddr in laddr_infos: - try: - sock.bind(laddr) - break - except OSError as exc: - msg = ( - f'error while attempting to bind on ' - f'address {laddr!r}: ' - f'{exc.strerror.lower()}' - ) - exc = OSError(exc.errno, msg) - exceptions.append(exc) - else: - sock.close() - sock = None - continue - if self._debug: - logger.debug("connect %r to %r", sock, address) - await self.sock_connect(sock, address) - except OSError as exc: - if sock is not None: - sock.close() - exceptions.append(exc) - except: - if sock is not None: - sock.close() - raise - else: - break - else: + if happy_eyeballs_delay is None: + # not using happy eyeballs + for addrinfo in infos: + try: + sock = await self._connect_sock( + exceptions, addrinfo, laddr_infos) + break + except OSError: + continue + else: # using happy eyeballs + sock, _, _ = await staggered.staggered_race( + (functools.partial(self._connect_sock, + exceptions, addrinfo, laddr_infos) + for addrinfo in infos), + happy_eyeballs_delay, loop=self) + + if sock is None: + exceptions = [exc for sub in exceptions for exc in sub] if len(exceptions) == 1: raise exceptions[0] else: @@ -1183,6 +1237,19 @@ async def create_datagram_endpoint(self, protocol_factory, for addr in (local_addr, remote_addr): if addr is not None and not isinstance(addr, str): raise TypeError('string is expected') + + if local_addr and local_addr[0] not in (0, '\x00'): + try: + if stat.S_ISSOCK(os.stat(local_addr).st_mode): + os.remove(local_addr) + except FileNotFoundError: + pass + except OSError as err: + # Directory may have permissions only to create socket. + logger.error('Unable to check or remove stale UNIX ' + 'socket %r: %r', + local_addr, err) + addr_pairs_info = (((family, proto), (local_addr, remote_addr)), ) else: @@ -1239,7 +1306,8 @@ async def create_datagram_endpoint(self, protocol_factory, if local_addr: sock.bind(local_address) if remote_addr: - await self.sock_connect(sock, remote_address) + if not allow_broadcast: + await self.sock_connect(sock, remote_address) r_addr = remote_address except OSError as exc: if sock is not None: diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 163b868afee..9a923514db0 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -298,7 +298,8 @@ async def create_connection( *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + happy_eyeballs_delay=None, interleave=None): raise NotImplementedError async def create_server( diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 93b68895094..29968214f8e 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -587,7 +587,10 @@ class _SelectorTransport(transports._FlowControlMixin, def __init__(self, loop, sock, protocol, extra=None, server=None): super().__init__(extra, loop) self._extra['socket'] = sock - self._extra['sockname'] = sock.getsockname() + try: + self._extra['sockname'] = sock.getsockname() + except OSError: + self._extra['sockname'] = None if 'peername' not in self._extra: try: self._extra['peername'] = sock.getpeername() @@ -976,9 +979,11 @@ def sendto(self, data, addr=None): if not data: return - if self._address and addr not in (None, self._address): - raise ValueError( - f'Invalid address: must be None or {self._address}') + if self._address: + if addr not in (None, self._address): + raise ValueError( + f'Invalid address: must be None or {self._address}') + addr = self._address if self._conn_lost and self._address: if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES: @@ -989,7 +994,7 @@ def sendto(self, data, addr=None): if not self._buffer: # Attempt to send it right away first. try: - if self._address: + if self._extra['peername']: self._sock.send(data) else: self._sock.sendto(data, addr) @@ -1012,7 +1017,7 @@ def _sendto_ready(self): while self._buffer: data, addr = self._buffer.popleft() try: - if self._address: + if self._extra['peername']: self._sock.send(data) else: self._sock.sendto(data, addr) diff --git a/Lib/asyncio/staggered.py b/Lib/asyncio/staggered.py new file mode 100644 index 00000000000..feec681b437 --- /dev/null +++ b/Lib/asyncio/staggered.py @@ -0,0 +1,147 @@ +"""Support for running coroutines in parallel with staggered start times.""" + +__all__ = 'staggered_race', + +import contextlib +import typing + +from . import events +from . import futures +from . import locks +from . import tasks + + +async def staggered_race( + coro_fns: typing.Iterable[typing.Callable[[], typing.Awaitable]], + delay: typing.Optional[float], + *, + loop: events.AbstractEventLoop = None, +) -> typing.Tuple[ + typing.Any, + typing.Optional[int], + typing.List[typing.Optional[Exception]] +]: + """Run coroutines with staggered start times and take the first to finish. + + This method takes an iterable of coroutine functions. The first one is + started immediately. From then on, whenever the immediately preceding one + fails (raises an exception), or when *delay* seconds has passed, the next + coroutine is started. This continues until one of the coroutines complete + successfully, in which case all others are cancelled, or until all + coroutines fail. + + The coroutines provided should be well-behaved in the following way: + + * They should only ``return`` if completed successfully. + + * They should always raise an exception if they did not complete + successfully. In particular, if they handle cancellation, they should + probably reraise, like this:: + + try: + # do work + except asyncio.CancelledError: + # undo partially completed work + raise + + Args: + coro_fns: an iterable of coroutine functions, i.e. callables that + return a coroutine object when called. Use ``functools.partial`` or + lambdas to pass arguments. + + delay: amount of time, in seconds, between starting coroutines. If + ``None``, the coroutines will run sequentially. + + loop: the event loop to use. + + Returns: + tuple *(winner_result, winner_index, exceptions)* where + + - *winner_result*: the result of the winning coroutine, or ``None`` + if no coroutines won. + + - *winner_index*: the index of the winning coroutine in + ``coro_fns``, or ``None`` if no coroutines won. If the winning + coroutine may return None on success, *winner_index* can be used + to definitively determine whether any coroutine won. + + - *exceptions*: list of exceptions returned by the coroutines. + ``len(exceptions)`` is equal to the number of coroutines actually + started, and the order is the same as in ``coro_fns``. The winning + coroutine's entry is ``None``. + + """ + # TODO: when we have aiter() and anext(), allow async iterables in coro_fns. + loop = loop or events.get_running_loop() + enum_coro_fns = enumerate(coro_fns) + winner_result = None + winner_index = None + exceptions = [] + running_tasks = [] + + async def run_one_coro( + previous_failed: typing.Optional[locks.Event]) -> None: + # Wait for the previous task to finish, or for delay seconds + if previous_failed is not None: + with contextlib.suppress(futures.TimeoutError): + # Use asyncio.wait_for() instead of asyncio.wait() here, so + # that if we get cancelled at this point, Event.wait() is also + # cancelled, otherwise there will be a "Task destroyed but it is + # pending" later. + await tasks.wait_for(previous_failed.wait(), delay) + # Get the next coroutine to run + try: + this_index, coro_fn = next(enum_coro_fns) + except StopIteration: + return + # Start task that will run the next coroutine + this_failed = locks.Event() + next_task = loop.create_task(run_one_coro(this_failed)) + running_tasks.append(next_task) + assert len(running_tasks) == this_index + 2 + # Prepare place to put this coroutine's exceptions if not won + exceptions.append(None) + assert len(exceptions) == this_index + 1 + + try: + result = await coro_fn() + except Exception as e: + exceptions[this_index] = e + this_failed.set() # Kickstart the next coroutine + else: + # Store winner's results + nonlocal winner_index, winner_result + assert winner_index is None + winner_index = this_index + winner_result = result + # Cancel all other tasks. We take care to not cancel the current + # task as well. If we do so, then since there is no `await` after + # here and CancelledError are usually thrown at one, we will + # encounter a curious corner case where the current task will end + # up as done() == True, cancelled() == False, exception() == + # asyncio.CancelledError. This behavior is specified in + # https://bugs.python.org/issue30048 + for i, t in enumerate(running_tasks): + if i != this_index: + t.cancel() + + first_task = loop.create_task(run_one_coro(None)) + running_tasks.append(first_task) + try: + # Wait for a growing list of tasks to all finish: poor man's version of + # curio's TaskGroup or trio's nursery + done_count = 0 + while done_count != len(running_tasks): + done, _ = await tasks.wait(running_tasks) + done_count = len(done) + # If run_one_coro raises an unhandled exception, it's probably a + # programming error, and I want to see it. + if __debug__: + for d in done: + if d.done() and not d.cancelled() and d.exception(): + raise d.exception() + return winner_result, winner_index, exceptions + finally: + # Make sure no tasks are left running if we leave this function + for t in running_tasks: + t.cancel() diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 33fc303a6ff..79adf028212 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -4,6 +4,7 @@ import socket import sys +import warnings import weakref if hasattr(socket, 'AF_UNIX'): @@ -42,11 +43,14 @@ async def open_connection(host=None, port=None, *, """ if loop is None: loop = events.get_event_loop() - reader = StreamReader(limit=limit, loop=loop) - protocol = StreamReaderProtocol(reader, loop=loop) + reader = StreamReader(limit=limit, loop=loop, + _asyncio_internal=True) + protocol = StreamReaderProtocol(reader, loop=loop, + _asyncio_internal=True) transport, _ = await loop.create_connection( lambda: protocol, host, port, **kwds) - writer = StreamWriter(transport, protocol, reader, loop) + writer = StreamWriter(transport, protocol, reader, loop, + _asyncio_internal=True) return reader, writer @@ -77,9 +81,11 @@ async def start_server(client_connected_cb, host=None, port=None, *, loop = events.get_event_loop() def factory(): - reader = StreamReader(limit=limit, loop=loop) + reader = StreamReader(limit=limit, loop=loop, + _asyncio_internal=True) protocol = StreamReaderProtocol(reader, client_connected_cb, - loop=loop) + loop=loop, + _asyncio_internal=True) return protocol return await loop.create_server(factory, host, port, **kwds) @@ -93,11 +99,14 @@ async def open_unix_connection(path=None, *, """Similar to `open_connection` but works with UNIX Domain Sockets.""" if loop is None: loop = events.get_event_loop() - reader = StreamReader(limit=limit, loop=loop) - protocol = StreamReaderProtocol(reader, loop=loop) + reader = StreamReader(limit=limit, loop=loop, + _asyncio_internal=True) + protocol = StreamReaderProtocol(reader, loop=loop, + _asyncio_internal=True) transport, _ = await loop.create_unix_connection( lambda: protocol, path, **kwds) - writer = StreamWriter(transport, protocol, reader, loop) + writer = StreamWriter(transport, protocol, reader, loop, + _asyncio_internal=True) return reader, writer async def start_unix_server(client_connected_cb, path=None, *, @@ -107,9 +116,11 @@ async def start_unix_server(client_connected_cb, path=None, *, loop = events.get_event_loop() def factory(): - reader = StreamReader(limit=limit, loop=loop) + reader = StreamReader(limit=limit, loop=loop, + _asyncio_internal=True) protocol = StreamReaderProtocol(reader, client_connected_cb, - loop=loop) + loop=loop, + _asyncio_internal=True) return protocol return await loop.create_unix_server(factory, path, **kwds) @@ -125,11 +136,20 @@ class FlowControlMixin(protocols.Protocol): StreamWriter.drain() must wait for _drain_helper() coroutine. """ - def __init__(self, loop=None): + def __init__(self, loop=None, *, _asyncio_internal=False): if loop is None: self._loop = events.get_event_loop() else: self._loop = loop + if not _asyncio_internal: + # NOTE: + # Avoid inheritance from FlowControlMixin + # Copy-paste the code to your project + # if you need flow control helpers + warnings.warn(f"{self.__class__} should be instaniated " + "by asyncio internals only, " + "please avoid its creation from user code", + DeprecationWarning) self._paused = False self._drain_waiter = None self._connection_lost = False @@ -179,6 +199,9 @@ async def _drain_helper(self): self._drain_waiter = waiter await waiter + def _get_close_waiter(self, stream): + raise NotImplementedError + class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): """Helper class to adapt between Protocol and StreamReader. @@ -191,8 +214,9 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): _source_traceback = None - def __init__(self, stream_reader, client_connected_cb=None, loop=None): - super().__init__(loop=loop) + def __init__(self, stream_reader, client_connected_cb=None, loop=None, + *, _asyncio_internal=False): + super().__init__(loop=loop, _asyncio_internal=_asyncio_internal) if stream_reader is not None: self._stream_reader_wr = weakref.ref(stream_reader, self._on_reader_gc) @@ -253,7 +277,8 @@ def connection_made(self, transport): if self._client_connected_cb is not None: self._stream_writer = StreamWriter(transport, self, reader, - self._loop) + self._loop, + _asyncio_internal=True) res = self._client_connected_cb(reader, self._stream_writer) if coroutines.iscoroutine(res): @@ -293,6 +318,9 @@ def eof_received(self): return False return True + def _get_close_waiter(self, stream): + return self._closed + def __del__(self): # Prevent reports about unhandled exceptions. # Better than self._closed._log_traceback = False hack @@ -311,7 +339,13 @@ class StreamWriter: directly. """ - def __init__(self, transport, protocol, reader, loop): + def __init__(self, transport, protocol, reader, loop, + *, _asyncio_internal=False): + if not _asyncio_internal: + warnings.warn(f"{self.__class__} should be instaniated " + "by asyncio internals only, " + "please avoid its creation from user code", + DeprecationWarning) self._transport = transport self._protocol = protocol # drain() expects that the reader has an exception() method @@ -348,7 +382,7 @@ def is_closing(self): return self._transport.is_closing() async def wait_closed(self): - await self._protocol._closed + await self._protocol._get_close_waiter(self) def get_extra_info(self, name, default=None): return self._transport.get_extra_info(name, default) @@ -366,13 +400,12 @@ async def drain(self): if exc is not None: raise exc if self._transport.is_closing(): - # Yield to the event loop so connection_lost() may be - # called. Without this, _drain_helper() would return - # immediately, and code that calls - # write(...); await drain() - # in a loop would never call connection_lost(), so it - # would not see an error when the socket is closed. - await sleep(0, loop=self._loop) + # Wait for protocol.connection_lost() call + # Raise connection closing error if any, + # ConnectionResetError otherwise + fut = self._protocol._get_close_waiter(self) + await fut + raise ConnectionResetError('Connection lost') await self._protocol._drain_helper() async def aclose(self): @@ -388,7 +421,14 @@ class StreamReader: _source_traceback = None - def __init__(self, limit=_DEFAULT_LIMIT, loop=None): + def __init__(self, limit=_DEFAULT_LIMIT, loop=None, + *, _asyncio_internal=False): + if not _asyncio_internal: + warnings.warn(f"{self.__class__} should be instaniated " + "by asyncio internals only, " + "please avoid its creation from user code", + DeprecationWarning) + # The line length limit is a security feature; # it also doubles as half the buffer limit. diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index 90fc00de833..d34b6118fdc 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -1,6 +1,7 @@ __all__ = 'create_subprocess_exec', 'create_subprocess_shell' import subprocess +import warnings from . import events from . import protocols @@ -18,13 +19,14 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, protocols.SubprocessProtocol): """Like StreamReaderProtocol, but for a subprocess.""" - def __init__(self, limit, loop): - super().__init__(loop=loop) + def __init__(self, limit, loop, *, _asyncio_internal=False): + super().__init__(loop=loop, _asyncio_internal=_asyncio_internal) self._limit = limit self.stdin = self.stdout = self.stderr = None self._transport = None self._process_exited = False self._pipe_fds = [] + self._stdin_closed = self._loop.create_future() def __repr__(self): info = [self.__class__.__name__] @@ -42,14 +44,16 @@ def connection_made(self, transport): stdout_transport = transport.get_pipe_transport(1) if stdout_transport is not None: self.stdout = streams.StreamReader(limit=self._limit, - loop=self._loop) + loop=self._loop, + _asyncio_internal=True) self.stdout.set_transport(stdout_transport) self._pipe_fds.append(1) stderr_transport = transport.get_pipe_transport(2) if stderr_transport is not None: self.stderr = streams.StreamReader(limit=self._limit, - loop=self._loop) + loop=self._loop, + _asyncio_internal=True) self.stderr.set_transport(stderr_transport) self._pipe_fds.append(2) @@ -58,7 +62,8 @@ def connection_made(self, transport): self.stdin = streams.StreamWriter(stdin_transport, protocol=self, reader=None, - loop=self._loop) + loop=self._loop, + _asyncio_internal=True) def pipe_data_received(self, fd, data): if fd == 1: @@ -76,6 +81,10 @@ def pipe_connection_lost(self, fd, exc): if pipe is not None: pipe.close() self.connection_lost(exc) + if exc is None: + self._stdin_closed.set_result(None) + else: + self._stdin_closed.set_exception(exc) return if fd == 1: reader = self.stdout @@ -102,9 +111,19 @@ def _maybe_close_transport(self): self._transport.close() self._transport = None + def _get_close_waiter(self, stream): + if stream is self.stdin: + return self._stdin_closed + class Process: - def __init__(self, transport, protocol, loop): + def __init__(self, transport, protocol, loop, *, _asyncio_internal=False): + if not _asyncio_internal: + warnings.warn(f"{self.__class__} should be instaniated " + "by asyncio internals only, " + "please avoid its creation from user code", + DeprecationWarning) + self._transport = transport self._protocol = protocol self._loop = loop @@ -195,12 +214,13 @@ async def create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, if loop is None: loop = events.get_event_loop() protocol_factory = lambda: SubprocessStreamProtocol(limit=limit, - loop=loop) + loop=loop, + _asyncio_internal=True) transport, protocol = await loop.subprocess_shell( protocol_factory, cmd, stdin=stdin, stdout=stdout, stderr=stderr, **kwds) - return Process(transport, protocol, loop) + return Process(transport, protocol, loop, _asyncio_internal=True) async def create_subprocess_exec(program, *args, stdin=None, stdout=None, @@ -209,10 +229,11 @@ async def create_subprocess_exec(program, *args, stdin=None, stdout=None, if loop is None: loop = events.get_event_loop() protocol_factory = lambda: SubprocessStreamProtocol(limit=limit, - loop=loop) + loop=loop, + _asyncio_internal=True) transport, protocol = await loop.subprocess_exec( protocol_factory, program, *args, stdin=stdin, stdout=stdout, stderr=stderr, **kwds) - return Process(transport, protocol, loop) + return Process(transport, protocol, loop, _asyncio_internal=True) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index d8508376d92..211b9126b01 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -495,10 +495,11 @@ def _on_completion(f): finally: if timeout_handle is not None: timeout_handle.cancel() + for f in fs: + f.remove_done_callback(_on_completion) done, pending = set(), set() for f in fs: - f.remove_done_callback(_on_completion) if f.done(): done.add(f) else: @@ -627,7 +628,8 @@ def ensure_future(coro_or_future, *, loop=None): return task elif futures.isfuture(coro_or_future): if loop is not None and loop is not futures._get_loop(coro_or_future): - raise ValueError('loop argument must agree with Future') + raise ValueError('The future belongs to a different loop than ' + 'the one specified as the loop argument') return coro_or_future elif inspect.isawaitable(coro_or_future): return ensure_future(_wrap_awaitable(coro_or_future), loop=loop) @@ -816,7 +818,7 @@ def shield(arg, *, loop=None): loop = futures._get_loop(inner) outer = loop.create_future() - def _done_callback(inner): + def _inner_done_callback(inner): if outer.cancelled(): if not inner.cancelled(): # Mark inner's result as retrieved. @@ -832,7 +834,13 @@ def _done_callback(inner): else: outer.set_result(inner.result()) - inner.add_done_callback(_done_callback) + + def _outer_done_callback(outer): + if not inner.done(): + inner.remove_done_callback(_inner_done_callback) + + inner.add_done_callback(_inner_done_callback) + outer.add_done_callback(_outer_done_callback) return outer diff --git a/Lib/asyncore.py b/Lib/asyncore.py index 828f4d4fe78..0e92be3ad19 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -262,8 +262,6 @@ def __repr__(self): status.append(repr(self.addr)) return '<%s at %#x>' % (' '.join(status), id(self)) - __str__ = __repr__ - def add_channel(self, map=None): #self.log_info('adding channel %s' % self) if map is None: diff --git a/Lib/bdb.py b/Lib/bdb.py index ec0f92c06a7..69174364c46 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -618,11 +618,26 @@ def runctx(self, cmd, globals, locals): # This method is more useful to debug a single function call. - def runcall(self, func, *args, **kwds): + def runcall(*args, **kwds): """Debug a single function call. Return the result of the function call. """ + if len(args) >= 2: + self, func, *args = args + elif not args: + raise TypeError("descriptor 'runcall' of 'Bdb' object " + "needs an argument") + elif 'func' in kwds: + func = kwds.pop('func') + self, *args = args + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('runcall expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + self.reset() sys.settrace(self.trace_dispatch) res = None @@ -634,6 +649,7 @@ def runcall(self, func, *args, **kwds): self.quitting = True sys.settrace(None) return res + runcall.__text_signature__ = '($self, func, /, *args, **kwds)' def set_trace(): diff --git a/Lib/bisect.py b/Lib/bisect.py index 7732c639e38..9786fc9d87c 100644 --- a/Lib/bisect.py +++ b/Lib/bisect.py @@ -9,14 +9,7 @@ def insort_right(a, x, lo=0, hi=None): slice of a to be searched. """ - if lo < 0: - raise ValueError('lo must be non-negative') - if hi is None: - hi = len(a) - while lo < hi: - mid = (lo+hi)//2 - if x < a[mid]: hi = mid - else: lo = mid+1 + lo = bisect_right(a, x, lo, hi) a.insert(lo, x) def bisect_right(a, x, lo=0, hi=None): @@ -49,14 +42,7 @@ def insort_left(a, x, lo=0, hi=None): slice of a to be searched. """ - if lo < 0: - raise ValueError('lo must be non-negative') - if hi is None: - hi = len(a) - while lo < hi: - mid = (lo+hi)//2 - if a[mid] < x: lo = mid+1 - else: hi = mid + lo = bisect_left(a, x, lo, hi) a.insert(lo, x) diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 305e79e2804..369d02e22e2 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -103,12 +103,28 @@ def runctx(self, cmd, globals, locals): return self # This method is more useful to profile a single function call. - def runcall(self, func, *args, **kw): + def runcall(*args, **kw): + if len(args) >= 2: + self, func, *args = args + elif not args: + raise TypeError("descriptor 'runcall' of 'Profile' object " + "needs an argument") + elif 'func' in kw: + func = kw.pop('func') + self, *args = args + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('runcall expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + self.enable() try: return func(*args, **kw) finally: self.disable() + runcall.__text_signature__ = '($self, func, /, *args, **kw)' def __enter__(self): self.enable() diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index cff75a48d62..706907ad4a2 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1016,8 +1016,10 @@ def __init__(*args, **kwargs): self.data = {} if dict is not None: self.update(dict) - if len(kwargs): + if kwargs: self.update(kwargs) + __init__.__text_signature__ = '($self, dict=None, /, **kwargs)' + def __len__(self): return len(self.data) def __getitem__(self, key): if key in self.data: @@ -1083,7 +1085,11 @@ def __cast(self, other): return other.data if isinstance(other, UserList) else other def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) - def __getitem__(self, i): return self.data[i] + def __getitem__(self, i): + if isinstance(i, slice): + return self.__class__(self.data[i]) + else: + return self.data[i] def __setitem__(self, i, item): self.data[i] = item def __delitem__(self, i): del self.data[i] def __add__(self, other): diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 8b9dc507138..8f155f0ea82 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -544,7 +544,7 @@ def set_exception(self, exception): class Executor(object): """This is an abstract base class for concrete asynchronous executors.""" - def submit(self, fn, *args, **kwargs): + def submit(*args, **kwargs): """Submits a callable to be executed with the given arguments. Schedules the callable to be executed as fn(*args, **kwargs) and returns @@ -553,7 +553,21 @@ def submit(self, fn, *args, **kwargs): Returns: A Future representing the given call. """ + if len(args) >= 2: + pass + elif not args: + raise TypeError("descriptor 'submit' of 'Executor' object " + "needs an argument") + elif 'fn' in kwargs: + import warnings + warnings.warn("Passing 'fn' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('submit expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + raise NotImplementedError() + submit.__text_signature__ = '($self, fn, /, *args, **kwargs)' def map(self, fn, *iterables, timeout=None, chunksize=1): """Returns an iterator equivalent to map(fn, iter). diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 9b85e7f3376..d7e2478d922 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -3,7 +3,7 @@ """Implements ProcessPoolExecutor. -The follow diagram and text describe the data-flow through the system: +The following diagram and text describe the data-flow through the system: |======================= In-process =====================|== Out-of-process ==| @@ -51,7 +51,7 @@ import queue from queue import Full import multiprocessing as mp -from multiprocessing.connection import wait +import multiprocessing.connection from multiprocessing.queues import Queue import threading import weakref @@ -352,7 +352,7 @@ def shutdown_worker(): # submitted, from the executor being shutdown/gc-ed, or from the # shutdown of the python interpreter. worker_sentinels = [p.sentinel for p in processes.values()] - ready = wait(readers + worker_sentinels) + ready = mp.connection.wait(readers + worker_sentinels) cause = None is_broken = True @@ -594,7 +594,22 @@ def _adjust_process_count(self): p.start() self._processes[p.pid] = p - def submit(self, fn, *args, **kwargs): + def submit(*args, **kwargs): + if len(args) >= 2: + self, fn, *args = args + elif not args: + raise TypeError("descriptor 'submit' of 'ProcessPoolExecutor' object " + "needs an argument") + elif 'fn' in kwargs: + fn = kwargs.pop('fn') + self, *args = args + import warnings + warnings.warn("Passing 'fn' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('submit expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + with self._shutdown_lock: if self._broken: raise BrokenProcessPool(self._broken) @@ -615,6 +630,7 @@ def submit(self, fn, *args, **kwargs): self._start_queue_management_thread() return f + submit.__text_signature__ = _base.Executor.submit.__text_signature__ submit.__doc__ = _base.Executor.submit.__doc__ def map(self, fn, *iterables, timeout=None, chunksize=1): diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 78359711d5d..2af31a106dd 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -142,7 +142,22 @@ def __init__(self, max_workers=None, thread_name_prefix='', self._initializer = initializer self._initargs = initargs - def submit(self, fn, *args, **kwargs): + def submit(*args, **kwargs): + if len(args) >= 2: + self, fn, *args = args + elif not args: + raise TypeError("descriptor 'submit' of 'ThreadPoolExecutor' object " + "needs an argument") + elif 'fn' in kwargs: + fn = kwargs.pop('fn') + self, *args = args + import warnings + warnings.warn("Passing 'fn' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('submit expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + with self._shutdown_lock: if self._broken: raise BrokenThreadPool(self._broken) @@ -159,6 +174,7 @@ def submit(self, fn, *args, **kwargs): self._work_queue.put(w) self._adjust_thread_count() return f + submit.__text_signature__ = _base.Executor.submit.__text_signature__ submit.__doc__ = _base.Executor.submit.__doc__ def _adjust_thread_count(self): diff --git a/Lib/contextlib.py b/Lib/contextlib.py index c06ec73f489..de989a001c6 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -377,7 +377,8 @@ def _create_exit_wrapper(cm, cm_exit): return MethodType(cm_exit, cm) @staticmethod - def _create_cb_wrapper(callback, *args, **kwds): + def _create_cb_wrapper(*args, **kwds): + callback, *args = args def _exit_wrapper(exc_type, exc, tb): callback(*args, **kwds) return _exit_wrapper @@ -426,11 +427,26 @@ def enter_context(self, cm): self._push_cm_exit(cm, _exit) return result - def callback(self, callback, *args, **kwds): + def callback(*args, **kwds): """Registers an arbitrary callback and arguments. Cannot suppress exceptions. """ + if len(args) >= 2: + self, callback, *args = args + elif not args: + raise TypeError("descriptor 'callback' of '_BaseExitStack' object " + "needs an argument") + elif 'callback' in kwds: + callback = kwds.pop('callback') + self, *args = args + import warnings + warnings.warn("Passing 'callback' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('callback expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + _exit_wrapper = self._create_cb_wrapper(callback, *args, **kwds) # We changed the signature, so using @wraps is not appropriate, but @@ -438,6 +454,7 @@ def callback(self, callback, *args, **kwds): _exit_wrapper.__wrapped__ = callback self._push_exit_callback(_exit_wrapper) return callback # Allow use as a decorator + callback.__text_signature__ = '($self, callback, /, *args, **kwds)' def _push_cm_exit(self, cm, cm_exit): """Helper to correctly register callbacks to __exit__ methods.""" @@ -536,7 +553,8 @@ def _create_async_exit_wrapper(cm, cm_exit): return MethodType(cm_exit, cm) @staticmethod - def _create_async_cb_wrapper(callback, *args, **kwds): + def _create_async_cb_wrapper(*args, **kwds): + callback, *args = args async def _exit_wrapper(exc_type, exc, tb): await callback(*args, **kwds) return _exit_wrapper @@ -571,11 +589,26 @@ def push_async_exit(self, exit): self._push_async_cm_exit(exit, exit_method) return exit # Allow use as a decorator - def push_async_callback(self, callback, *args, **kwds): + def push_async_callback(*args, **kwds): """Registers an arbitrary coroutine function and arguments. Cannot suppress exceptions. """ + if len(args) >= 2: + self, callback, *args = args + elif not args: + raise TypeError("descriptor 'push_async_callback' of " + "'AsyncExitStack' object needs an argument") + elif 'callback' in kwds: + callback = kwds.pop('callback') + self, *args = args + import warnings + warnings.warn("Passing 'callback' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('push_async_callback expected at least 1 ' + 'positional argument, got %d' % (len(args)-1)) + _exit_wrapper = self._create_async_cb_wrapper(callback, *args, **kwds) # We changed the signature, so using @wraps is not appropriate, but @@ -583,6 +616,7 @@ def push_async_callback(self, callback, *args, **kwds): _exit_wrapper.__wrapped__ = callback self._push_exit_callback(_exit_wrapper, False) return callback # Allow use as a decorator + push_async_callback.__text_signature__ = '($self, callback, /, *args, **kwds)' async def aclose(self): """Immediately unwind the context stack.""" diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 5f78beda586..4107db3e397 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -326,7 +326,8 @@ class CDLL(object): def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, - use_last_error=False): + use_last_error=False, + winmode=None): self._name = name flags = self._func_flags_ if use_errno: @@ -341,6 +342,15 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None, """ if name and name.endswith(")") and ".a(" in name: mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW ) + if _os.name == "nt": + if winmode is not None: + mode = winmode + else: + import nt + mode = nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + if '/' in name or '\\' in name: + self._name = nt._getfullpathname(self._name) + mode |= nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR class _FuncPtr(_CFuncPtr): _flags_ = flags diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index 6cfda8b7d2e..0fc5d7ebf84 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -197,6 +197,12 @@ class T(Array): _type_ = c_int _length_ = 0 + def test_bpo36504_signed_int_overflow(self): + # The overflow check in PyCArrayType_new() could cause signed integer + # overflow. + with self.assertRaises(OverflowError): + c_char * sys.maxsize * 2 + @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') @bigmemtest(size=_2G, memuse=1, dry_run=False) def test_large_array(self, size): diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index f3b65b9d6e7..9b97d800860 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -1,6 +1,9 @@ from ctypes import * import os +import shutil +import subprocess import sys +import sysconfig import unittest import test.support from ctypes.util import find_library @@ -112,5 +115,66 @@ def test_1703286_B(self): # This is the real test: call the function via 'call_function' self.assertEqual(0, call_function(proc, (None,))) + @unittest.skipUnless(os.name == "nt", + 'test specific to Windows') + def test_load_dll_with_flags(self): + _sqlite3 = test.support.import_module("_sqlite3") + src = _sqlite3.__file__ + if src.lower().endswith("_d.pyd"): + ext = "_d.dll" + else: + ext = ".dll" + + with test.support.temp_dir() as tmp: + # We copy two files and load _sqlite3.dll (formerly .pyd), + # which has a dependency on sqlite3.dll. Then we test + # loading it in subprocesses to avoid it starting in memory + # for each test. + target = os.path.join(tmp, "_sqlite3.dll") + shutil.copy(src, target) + shutil.copy(os.path.join(os.path.dirname(src), "sqlite3" + ext), + os.path.join(tmp, "sqlite3" + ext)) + + def should_pass(command): + with self.subTest(command): + subprocess.check_output( + [sys.executable, "-c", + "from ctypes import *; import nt;" + command], + cwd=tmp + ) + + def should_fail(command): + with self.subTest(command): + with self.assertRaises(subprocess.CalledProcessError): + subprocess.check_output( + [sys.executable, "-c", + "from ctypes import *; import nt;" + command], + cwd=tmp, stderr=subprocess.STDOUT, + ) + + # Default load should not find this in CWD + should_fail("WinDLL('_sqlite3.dll')") + + # Relative path (but not just filename) should succeed + should_pass("WinDLL('./_sqlite3.dll')") + + # Insecure load flags should succeed + should_pass("WinDLL('_sqlite3.dll', winmode=0)") + + # Full path load without DLL_LOAD_DIR shouldn't find dependency + should_fail("WinDLL(nt._getfullpathname('_sqlite3.dll'), " + + "winmode=nt._LOAD_LIBRARY_SEARCH_SYSTEM32)") + + # Full path load with DLL_LOAD_DIR should succeed + should_pass("WinDLL(nt._getfullpathname('_sqlite3.dll'), " + + "winmode=nt._LOAD_LIBRARY_SEARCH_SYSTEM32|" + + "nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)") + + # User-specified directory should succeed + should_pass("import os; p = os.add_dll_directory(os.getcwd());" + + "WinDLL('_sqlite3.dll'); p.close()") + + + if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py index b38b63f870a..87eb9198ade 100644 --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -80,9 +80,9 @@ class struct_frozen(Structure): continue items.append((entry.name.decode("ascii"), entry.size)) - expected = [("__hello__", 139), - ("__phello__", -139), - ("__phello__.spam", 139), + expected = [("__hello__", 141), + ("__phello__", -141), + ("__phello__.spam", 141), ] self.assertEqual(items, expected, "PyImport_FrozenModules example " "in Doc/library/ctypes.rst may be out of date") diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py index a2941f3fe07..e51bdc8ad6b 100644 --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -6,35 +6,6 @@ import _ctypes_test -# Only windows 32-bit has different calling conventions. -@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') -@unittest.skipUnless(sizeof(c_void_p) == sizeof(c_int), - "sizeof c_void_p and c_int differ") -class WindowsTestCase(unittest.TestCase): - def test_callconv_1(self): - # Testing stdcall function - - IsWindow = windll.user32.IsWindow - # ValueError: Procedure probably called with not enough arguments - # (4 bytes missing) - self.assertRaises(ValueError, IsWindow) - - # This one should succeed... - self.assertEqual(0, IsWindow(0)) - - # ValueError: Procedure probably called with too many arguments - # (8 bytes in excess) - self.assertRaises(ValueError, IsWindow, 0, 0, 0) - - def test_callconv_2(self): - # Calling stdcall function as cdecl - - IsWindow = cdll.user32.IsWindow - - # ValueError: Procedure called with not enough arguments - # (4 bytes missing) or wrong calling convention - self.assertRaises(ValueError, IsWindow, None) - @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') class FunctionCallTestCase(unittest.TestCase): @unittest.skipUnless('MSC' in sys.version, "SEH only supported by MSC") diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py index 47378741acc..24ff3ca93a8 100644 --- a/Lib/curses/__init__.py +++ b/Lib/curses/__init__.py @@ -60,7 +60,7 @@ def start_color(): # raises an exception, wrapper() will restore the terminal to a sane state so # you can read the resulting traceback. -def wrapper(func, *args, **kwds): +def wrapper(*args, **kwds): """Wrapper function that initializes curses and calls another function, restoring normal keyboard/screen behavior on error. The callable object 'func' is then passed the main window 'stdscr' @@ -68,6 +68,17 @@ def wrapper(func, *args, **kwds): wrapper(). """ + if args: + func, *args = args + elif 'func' in kwds: + func = kwds.pop('func') + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('wrapper expected at least 1 positional argument, ' + 'got %d' % len(args)) + try: # Initialize curses stdscr = initscr() @@ -99,3 +110,4 @@ def wrapper(func, *args, **kwds): echo() nocbreak() endwin() +wrapper.__text_signature__ = '(func, /, *args, **kwds)' diff --git a/Lib/datetime.py b/Lib/datetime.py index 85bfa48e05d..0e64815944d 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -884,6 +884,40 @@ def fromisoformat(cls, date_string): except Exception: raise ValueError(f'Invalid isoformat string: {date_string!r}') + @classmethod + def fromisocalendar(cls, year, week, day): + """Construct a date from the ISO year, week number and weekday. + + This is the inverse of the date.isocalendar() function""" + # Year is bounded this way because 9999-12-31 is (9999, 52, 5) + if not MINYEAR <= year <= MAXYEAR: + raise ValueError(f"Year is out of range: {year}") + + if not 0 < week < 53: + out_of_range = True + + if week == 53: + # ISO years have 53 weeks in them on years starting with a + # Thursday and leap years starting on a Wednesday + first_weekday = _ymd2ord(year, 1, 1) % 7 + if (first_weekday == 4 or (first_weekday == 3 and + _is_leap(year))): + out_of_range = False + + if out_of_range: + raise ValueError(f"Invalid week: {week}") + + if not 0 < day < 8: + raise ValueError(f"Invalid weekday: {day} (range is [1, 7])") + + # Now compute the offset from (Y, 1, 1) in days: + day_offset = (week - 1) * 7 + (day - 1) + + # Calculate the ordinal day for monday, week 1 + day_1 = _isoweek1monday(year) + ord_day = day_1 + day_offset + + return cls(*_ord2ymd(ord_day)) # Conversions to string @@ -2141,6 +2175,7 @@ def _isoweek1monday(year): week1monday += 7 return week1monday + class timezone(tzinfo): __slots__ = '_offset', '_name' diff --git a/Lib/dbm/__init__.py b/Lib/dbm/__init__.py index 6831a844073..f65da521af4 100644 --- a/Lib/dbm/__init__.py +++ b/Lib/dbm/__init__.py @@ -82,7 +82,8 @@ def open(file, flag='r', mode=0o666): # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: - raise error[0]("need 'c' or 'n' flag to open new db") + raise error[0]("db file doesn't exist; " + "use 'c' or 'n' flag to create a new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") diff --git a/Lib/dis.py b/Lib/dis.py index b2b0003203a..a25fb2b4176 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -157,6 +157,7 @@ def _format_code_info(co): lines.append("Name: %s" % co.co_name) lines.append("Filename: %s" % co.co_filename) lines.append("Argument count: %s" % co.co_argcount) + lines.append("Positional-only arguments: %s" % co.co_posonlyargcount) lines.append("Kw-only arguments: %s" % co.co_kwonlyargcount) lines.append("Number of locals: %s" % co.co_nlocals) lines.append("Stack size: %s" % co.co_stacksize) diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py index 58b20a21024..c7ac3f049eb 100644 --- a/Lib/distutils/_msvccompiler.py +++ b/Lib/distutils/_msvccompiler.py @@ -89,13 +89,24 @@ def _find_vc2017(): return None, None +PLAT_SPEC_TO_RUNTIME = { + 'x86' : 'x86', + 'x86_amd64' : 'x64', + 'x86_arm' : 'arm', +} + def _find_vcvarsall(plat_spec): _, best_dir = _find_vc2017() vcruntime = None - vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' + + if plat_spec in PLAT_SPEC_TO_RUNTIME: + vcruntime_plat = PLAT_SPEC_TO_RUNTIME[plat_spec] + else: + vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' + if best_dir: vcredist = os.path.join(best_dir, "..", "..", "redist", "MSVC", "**", - "Microsoft.VC141.CRT", "vcruntime140.dll") + vcruntime_plat, "Microsoft.VC141.CRT", "vcruntime140.dll") try: import glob vcruntime = glob.glob(vcredist, recursive=True)[-1] @@ -178,6 +189,7 @@ def _find_exe(exe, paths=None): PLAT_TO_VCVARS = { 'win32' : 'x86', 'win-amd64' : 'x86_amd64', + 'win-arm32' : 'x86_arm', } # A set containing the DLLs that are guaranteed to be available for diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py index 02f10dd89d9..20ca7ac6dcf 100644 --- a/Lib/distutils/command/bdist_rpm.py +++ b/Lib/distutils/command/bdist_rpm.py @@ -537,7 +537,8 @@ def _make_spec_file(self): '', '%' + rpm_opt,]) if val: - spec_file.extend(open(val, 'r').read().split('\n')) + with open(val) as f: + spec_file.extend(f.read().split('\n')) else: spec_file.append(default) diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py index fde56754e89..3a616883bee 100644 --- a/Lib/distutils/command/bdist_wininst.py +++ b/Lib/distutils/command/bdist_wininst.py @@ -247,47 +247,49 @@ def create_exe(self, arcname, fullname, bitmap=None): self.announce("creating %s" % installer_name) if bitmap: - bitmapdata = open(bitmap, "rb").read() + with open(bitmap, "rb") as f: + bitmapdata = f.read() bitmaplen = len(bitmapdata) else: bitmaplen = 0 - file = open(installer_name, "wb") - file.write(self.get_exe_bytes()) - if bitmap: - file.write(bitmapdata) + with open(installer_name, "wb") as file: + file.write(self.get_exe_bytes()) + if bitmap: + file.write(bitmapdata) - # Convert cfgdata from unicode to ascii, mbcs encoded - if isinstance(cfgdata, str): - cfgdata = cfgdata.encode("mbcs") + # Convert cfgdata from unicode to ascii, mbcs encoded + if isinstance(cfgdata, str): + cfgdata = cfgdata.encode("mbcs") - # Append the pre-install script - cfgdata = cfgdata + b"\0" - if self.pre_install_script: - # We need to normalize newlines, so we open in text mode and - # convert back to bytes. "latin-1" simply avoids any possible - # failures. - with open(self.pre_install_script, "r", - encoding="latin-1") as script: - script_data = script.read().encode("latin-1") - cfgdata = cfgdata + script_data + b"\n\0" - else: - # empty pre-install script + # Append the pre-install script cfgdata = cfgdata + b"\0" - file.write(cfgdata) + if self.pre_install_script: + # We need to normalize newlines, so we open in text mode and + # convert back to bytes. "latin-1" simply avoids any possible + # failures. + with open(self.pre_install_script, "r", + encoding="latin-1") as script: + script_data = script.read().encode("latin-1") + cfgdata = cfgdata + script_data + b"\n\0" + else: + # empty pre-install script + cfgdata = cfgdata + b"\0" + file.write(cfgdata) - # The 'magic number' 0x1234567B is used to make sure that the - # binary layout of 'cfgdata' is what the wininst.exe binary - # expects. If the layout changes, increment that number, make - # the corresponding changes to the wininst.exe sources, and - # recompile them. - header = struct.pack("> 24, (sys.hexversion >> 16) & 0xff, - sysconfig.get_config_var('ABIFLAGS')) - return ext.libraries + [pythonlib] - else: - return ext.libraries + from distutils.sysconfig import get_config_var + if get_config_var('Py_ENABLE_SHARED'): + # Either a native build on an Android device or the + # cross-compilation of Python. + if (hasattr(sys, 'getandroidapilevel') or + ('_PYTHON_HOST_PLATFORM' in os.environ and + get_config_var('ANDROID_API_LEVEL') != 0)): + ldversion = get_config_var('LDVERSION') + return ext.libraries + ['python' + ldversion] + + return ext.libraries diff --git a/Lib/distutils/command/check.py b/Lib/distutils/command/check.py index 7ebe707cff4..04c2f9642d7 100644 --- a/Lib/distutils/command/check.py +++ b/Lib/distutils/command/check.py @@ -120,7 +120,8 @@ def check_restructuredtext(self): def _check_rst_data(self, data): """Returns warnings when the provided data doesn't compile.""" - source_path = StringIO() + # the include and csv_table directives need this to be a path + source_path = self.distribution.script_name or 'setup.py' parser = Parser() settings = frontend.OptionParser(components=(Parser,)).get_default_values() settings.tab_width = 4 diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py index 613ea711296..11afa24b777 100644 --- a/Lib/distutils/command/upload.py +++ b/Lib/distutils/command/upload.py @@ -125,8 +125,9 @@ def upload_file(self, command, pyversion, filename): data['comment'] = '' if self.sign: - data['gpg_signature'] = (os.path.basename(filename) + ".asc", - open(filename+".asc", "rb").read()) + with open(filename + ".asc", "rb") as f: + data['gpg_signature'] = (os.path.basename(filename) + ".asc", + f.read()) # set up the authentication user_pass = (self.username + ":" + self.password).encode('ascii') diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py index 53876880932..ceb94945dc8 100644 --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -81,7 +81,6 @@ def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0): "command %r failed with exit status %d" % (cmd, rc)) if sys.platform == 'darwin': - from distutils import sysconfig _cfg_target = None _cfg_target_split = None @@ -95,6 +94,7 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): if sys.platform == 'darwin': global _cfg_target, _cfg_target_split if _cfg_target is None: + from distutils import sysconfig _cfg_target = sysconfig.get_config_var( 'MACOSX_DEPLOYMENT_TARGET') or '' if _cfg_target: @@ -172,21 +172,32 @@ def find_executable(executable, path=None): A string listing directories separated by 'os.pathsep'; defaults to os.environ['PATH']. Returns the complete filename or None if not found. """ - if path is None: - path = os.environ.get('PATH', os.defpath) - - paths = path.split(os.pathsep) - base, ext = os.path.splitext(executable) - + _, ext = os.path.splitext(executable) if (sys.platform == 'win32') and (ext != '.exe'): executable = executable + '.exe' - if not os.path.isfile(executable): - for p in paths: - f = os.path.join(p, executable) - if os.path.isfile(f): - # the file exists, we have a shot at spawn working - return f - return None - else: + if os.path.isfile(executable): return executable + + if path is None: + path = os.environ.get('PATH', None) + if path is None: + try: + path = os.confstr("CS_PATH") + except (AttributeError, ValueError): + # os.confstr() or CS_PATH is not available + path = os.defpath + # bpo-35755: Don't use os.defpath if the PATH environment variable is + # set to an empty string + + # PATH='' doesn't match, whereas PATH=':' looks in the current directory + if not path: + return None + + paths = path.split(os.pathsep) + for p in paths: + f = os.path.join(p, executable) + if os.path.isfile(f): + # the file exists, we have a shot at spawn working + return f + return None diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index a3494670db1..b51629eb94f 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -15,6 +15,7 @@ import sys from .errors import DistutilsPlatformError +from .util import get_platform, get_host_platform # These are needed in a couple of spots, so just compute them once. PREFIX = os.path.normpath(sys.prefix) @@ -28,7 +29,12 @@ if "_PYTHON_PROJECT_BASE" in os.environ: project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"]) else: - project_base = os.path.dirname(os.path.abspath(sys.executable)) + if sys.executable: + project_base = os.path.dirname(os.path.abspath(sys.executable)) + else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + project_base = os.getcwd() # python_build: (Boolean) if true, we're either building Python or diff --git a/Lib/distutils/tests/includetest.rst b/Lib/distutils/tests/includetest.rst new file mode 100644 index 00000000000..d7b4ae38b09 --- /dev/null +++ b/Lib/distutils/tests/includetest.rst @@ -0,0 +1 @@ +This should be included. diff --git a/Lib/distutils/tests/test_check.py b/Lib/distutils/tests/test_check.py index 3d22868e313..e534aca1d47 100644 --- a/Lib/distutils/tests/test_check.py +++ b/Lib/distutils/tests/test_check.py @@ -1,4 +1,5 @@ """Tests for distutils.command.check.""" +import os import textwrap import unittest from test.support import run_unittest @@ -13,13 +14,19 @@ pygments = None +HERE = os.path.dirname(__file__) + + class CheckTestCase(support.LoggingSilencer, support.TempdirManager, unittest.TestCase): - def _run(self, metadata=None, **options): + def _run(self, metadata=None, cwd=None, **options): if metadata is None: metadata = {} + if cwd is not None: + old_dir = os.getcwd() + os.chdir(cwd) pkg_info, dist = self.create_dist(**metadata) cmd = check(dist) cmd.initialize_options() @@ -27,6 +34,8 @@ def _run(self, metadata=None, **options): setattr(cmd, name, value) cmd.ensure_finalized() cmd.run() + if cwd is not None: + os.chdir(old_dir) return cmd def test_check_metadata(self): @@ -99,6 +108,11 @@ def test_check_restructuredtext(self): cmd = self._run(metadata, strict=1, restructuredtext=1) self.assertEqual(cmd._warnings, 0) + # check that includes work to test #31292 + metadata['long_description'] = 'title\n=====\n\n.. include:: includetest.rst' + cmd = self._run(metadata, cwd=HERE, strict=1, restructuredtext=1) + self.assertEqual(cmd._warnings, 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") def test_check_restructuredtext_with_syntax_highlight(self): # Don't fail if there is a `code` or `code-block` directive diff --git a/Lib/distutils/tests/test_spawn.py b/Lib/distutils/tests/test_spawn.py index 0d455385d8a..f9ae69ef86b 100644 --- a/Lib/distutils/tests/test_spawn.py +++ b/Lib/distutils/tests/test_spawn.py @@ -87,11 +87,52 @@ def test_find_executable(self): rv = find_executable(dont_exist_program , path=tmp_dir) self.assertIsNone(rv) - # test os.defpath: missing PATH environment variable + # PATH='': no match, except in the current directory with test_support.EnvironmentVarGuard() as env: - with mock.patch('distutils.spawn.os.defpath', tmp_dir): - env.pop('PATH') + env['PATH'] = '' + with unittest.mock.patch('distutils.spawn.os.confstr', + return_value=tmp_dir, create=True), \ + unittest.mock.patch('distutils.spawn.os.defpath', + tmp_dir): + rv = find_executable(program) + self.assertIsNone(rv) + # look in current directory + with test_support.change_cwd(tmp_dir): + rv = find_executable(program) + self.assertEqual(rv, program) + + # PATH=':': explicitly looks in the current directory + with test_support.EnvironmentVarGuard() as env: + env['PATH'] = os.pathsep + with unittest.mock.patch('distutils.spawn.os.confstr', + return_value='', create=True), \ + unittest.mock.patch('distutils.spawn.os.defpath', ''): + rv = find_executable(program) + self.assertIsNone(rv) + + # look in current directory + with test_support.change_cwd(tmp_dir): + rv = find_executable(program) + self.assertEqual(rv, program) + + # missing PATH: test os.confstr("CS_PATH") and os.defpath + with test_support.EnvironmentVarGuard() as env: + env.pop('PATH', None) + + # without confstr + with unittest.mock.patch('distutils.spawn.os.confstr', + side_effect=ValueError, + create=True), \ + unittest.mock.patch('distutils.spawn.os.defpath', + tmp_dir): + rv = find_executable(program) + self.assertEqual(rv, filename) + + # with confstr + with unittest.mock.patch('distutils.spawn.os.confstr', + return_value=tmp_dir, create=True), \ + unittest.mock.patch('distutils.spawn.os.defpath', ''): rv = find_executable(program) self.assertEqual(rv, filename) diff --git a/Lib/distutils/tests/test_sysconfig.py b/Lib/distutils/tests/test_sysconfig.py index 245a6c86b11..236755d0952 100644 --- a/Lib/distutils/tests/test_sysconfig.py +++ b/Lib/distutils/tests/test_sysconfig.py @@ -92,6 +92,9 @@ def set_executables(self, **kw): 'CCSHARED': '--sc-ccshared', 'LDSHARED': 'sc_ldshared', 'SHLIB_SUFFIX': 'sc_shutil_suffix', + + # On macOS, disable _osx_support.customize_compiler() + 'CUSTOMIZED_OSX_COMPILER': 'True', } comp = compiler() diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py index 15cd2ad9a9a..50550e18934 100644 --- a/Lib/distutils/util.py +++ b/Lib/distutils/util.py @@ -15,7 +15,7 @@ from distutils import log from distutils.errors import DistutilsByteCompileError -def get_platform (): +def get_host_platform(): """Return a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the @@ -38,6 +38,8 @@ def get_platform (): if os.name == 'nt': if 'amd64' in sys.version.lower(): return 'win-amd64' + if '(arm)' in sys.version.lower(): + return 'win-arm32' return sys.platform # Set for cross builds explicitly @@ -90,8 +92,16 @@ def get_platform (): return "%s-%s-%s" % (osname, release, machine) -# get_platform () - +def get_platform(): + if os.name == 'nt': + TARGET_TO_PLAT = { + 'x86' : 'win32', + 'x64' : 'win-amd64', + 'arm' : 'win-arm32', + } + return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform() + else: + return get_host_platform() def convert_path (pathname): """Return 'pathname' as a name that will work on the native filesystem, diff --git a/Lib/doctest.py b/Lib/doctest.py index 79d91a040c2..bf4889f59e0 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -2300,7 +2300,7 @@ def __repr__(self): name = self._dt_test.name.split('.') return "%s (%s)" % (name[-1], '.'.join(name[:-1])) - __str__ = __repr__ + __str__ = object.__str__ def shortDescription(self): return "Doctest: " + self._dt_test.name @@ -2399,7 +2399,6 @@ def id(self): def __repr__(self): return self._dt_test.filename - __str__ = __repr__ def format_failure(self, err): return ('Failed doctest test for %s\n File "%s", line 0\n\n%s' diff --git a/Lib/email/charset.py b/Lib/email/charset.py index ee564040c68..d3d759ad911 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -241,11 +241,9 @@ def __init__(self, input_charset=DEFAULT_CHARSET): self.output_codec = CODEC_MAP.get(self.output_charset, self.output_charset) - def __str__(self): + def __repr__(self): return self.input_charset.lower() - __repr__ = __str__ - def __eq__(self, other): return str(self) == str(other).lower() diff --git a/Lib/fileinput.py b/Lib/fileinput.py index 4a71cc5ff31..0764aa5e4d2 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -222,6 +222,7 @@ def __init__(self, files=None, inplace=False, backup="", bufsize=0, warnings.warn("'U' mode is deprecated", DeprecationWarning, 2) self._mode = mode + self._write_mode = mode.replace('r', 'w') if 'U' not in mode else 'w' if openhook: if inplace: raise ValueError("FileInput cannot use an opening hook in inplace mode") @@ -348,14 +349,14 @@ def _readline(self): try: perm = os.fstat(self._file.fileno()).st_mode except OSError: - self._output = open(self._filename, "w") + self._output = open(self._filename, self._write_mode) else: mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC if hasattr(os, 'O_BINARY'): mode |= os.O_BINARY fd = os.open(self._filename, mode, perm) - self._output = os.fdopen(fd, "w") + self._output = os.fdopen(fd, self._write_mode) try: os.chmod(self._filename, perm) except OSError: diff --git a/Lib/fractions.py b/Lib/fractions.py index 4bbfc434f7d..7443bd3e0c6 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -512,16 +512,16 @@ def __trunc__(a): return a._numerator // a._denominator def __floor__(a): - """Will be math.floor(a) in 3.0.""" + """math.floor(a)""" return a.numerator // a.denominator def __ceil__(a): - """Will be math.ceil(a) in 3.0.""" + """math.ceil(a)""" # The negations cleverly convince floordiv to return the ceiling. return -(-a.numerator // a.denominator) def __round__(self, ndigits=None): - """Will be round(self, ndigits) in 3.0. + """round(self, ndigits) Rounds half toward even. """ diff --git a/Lib/ftplib.py b/Lib/ftplib.py index 9611282ecac..a9b1aee39e4 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -302,26 +302,7 @@ def sendeprt(self, host, port): def makeport(self): '''Create a new socket and send a PORT command for it.''' - err = None - sock = None - for res in socket.getaddrinfo(None, 0, self.af, socket.SOCK_STREAM, 0, socket.AI_PASSIVE): - af, socktype, proto, canonname, sa = res - try: - sock = socket.socket(af, socktype, proto) - sock.bind(sa) - except OSError as _: - err = _ - if sock: - sock.close() - sock = None - continue - break - if sock is None: - if err is not None: - raise err - else: - raise OSError("getaddrinfo returns an empty list") - sock.listen(1) + sock = socket.create_server(("", 0), family=self.af, backlog=1) port = sock.getsockname()[1] # Get proper port host = self.sock.getsockname()[0] # Get proper host if self.af == socket.AF_INET: diff --git a/Lib/functools.py b/Lib/functools.py index fe47600caa1..28d9f6f75fd 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -285,10 +285,7 @@ def __new__(*args, **keywords): if hasattr(func, "func"): args = func.args + args - tmpkw = func.keywords.copy() - tmpkw.update(keywords) - keywords = tmpkw - del tmpkw + keywords = {**func.keywords, **keywords} func = func.func self = super(partial, cls).__new__(cls) @@ -302,9 +299,8 @@ def __call__(*args, **keywords): if not args: raise TypeError("descriptor '__call__' of partial needs an argument") self, *args = args - newkeywords = self.keywords.copy() - newkeywords.update(keywords) - return self.func(*self.args, *args, **newkeywords) + keywords = {**self.keywords, **keywords} + return self.func(*self.args, *args, **keywords) @recursive_repr() def __repr__(self): @@ -358,7 +354,23 @@ class partialmethod(object): callables as instance methods. """ - def __init__(self, func, *args, **keywords): + def __init__(*args, **keywords): + if len(args) >= 2: + self, func, *args = args + elif not args: + raise TypeError("descriptor '__init__' of partialmethod " + "needs an argument") + elif 'func' in keywords: + func = keywords.pop('func') + self, *args = args + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError("type 'partialmethod' takes at least one argument, " + "got %d" % (len(args)-1)) + args = tuple(args) + if not callable(func) and not hasattr(func, "__get__"): raise TypeError("{!r} is not callable or a descriptor" .format(func)) @@ -371,12 +383,12 @@ def __init__(self, func, *args, **keywords): # it's also more efficient since only one function will be called self.func = func.func self.args = func.args + args - self.keywords = func.keywords.copy() - self.keywords.update(keywords) + self.keywords = {**func.keywords, **keywords} else: self.func = func self.args = args self.keywords = keywords + __init__.__text_signature__ = '($self, func, /, *args, **keywords)' def __repr__(self): args = ", ".join(map(repr, self.args)) @@ -391,11 +403,9 @@ def __repr__(self): def _make_unbound_method(self): def _method(*args, **keywords): - call_keywords = self.keywords.copy() - call_keywords.update(keywords) - cls_or_self, *rest = args - call_args = (cls_or_self,) + self.args + tuple(rest) - return self.func(*call_args, **call_keywords) + cls_or_self, *args = args + keywords = {**self.keywords, **keywords} + return self.func(cls_or_self, *self.args, *args, **keywords) _method.__isabstractmethod__ = self.__isabstractmethod__ _method._partialmethod = self return _method diff --git a/Lib/gzip.py b/Lib/gzip.py index 948fec293e2..7c861874198 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -283,7 +283,7 @@ def read(self, size=-1): def read1(self, size=-1): """Implements BufferedIOBase.read1() - Reads up to a buffer's worth of data is size is negative.""" + Reads up to a buffer's worth of data if size is negative.""" self._check_not_closed() if self.mode != READ: import errno diff --git a/Lib/http/client.py b/Lib/http/client.py index 5aa178d7b12..82908ebe3af 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -105,9 +105,6 @@ # Mapping status codes to official W3C names responses = {v: v.phrase for v in http.HTTPStatus.__members__.values()} -# maximal amount of data to read at one time in _safe_read -MAXAMOUNT = 1048576 - # maximal line length when calling readline(). _MAXLINE = 65536 _MAXHEADERS = 100 @@ -140,6 +137,16 @@ _is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch _is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search +# These characters are not allowed within HTTP URL paths. +# See https://tools.ietf.org/html/rfc3986#section-3.3 and the +# https://tools.ietf.org/html/rfc3986#appendix-A pchar definition. +# Prevents CVE-2019-9740. Includes control characters such as \r\n. +# We don't restrict chars above \x7f as putrequest() limits us to ASCII. +_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]') +# Arguably only these _should_ allowed: +# _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$") +# We are more lenient for assumed real world compatibility purposes. + # We always set the Content-Length header for these methods because some # servers will otherwise respond with a 411 _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} @@ -320,8 +327,8 @@ def begin(self): self.headers = self.msg = parse_headers(self.fp) if self.debuglevel > 0: - for hdr in self.headers: - print("header:", hdr + ":", self.headers.get(hdr)) + for hdr, val in self.headers.items(): + print("header:", hdr + ":", val) # are we using the chunked-style of transfer encoding? tr_enc = self.headers.get("transfer-encoding") @@ -592,43 +599,24 @@ def _readinto_chunked(self, b): raise IncompleteRead(bytes(b[0:total_bytes])) def _safe_read(self, amt): - """Read the number of bytes requested, compensating for partial reads. - - Normally, we have a blocking socket, but a read() can be interrupted - by a signal (resulting in a partial read). - - Note that we cannot distinguish between EOF and an interrupt when zero - bytes have been read. IncompleteRead() will be raised in this - situation. + """Read the number of bytes requested. This function should be used when bytes "should" be present for reading. If the bytes are truly not available (due to EOF), then the IncompleteRead exception can be used to detect the problem. """ - s = [] - while amt > 0: - chunk = self.fp.read(min(amt, MAXAMOUNT)) - if not chunk: - raise IncompleteRead(b''.join(s), amt) - s.append(chunk) - amt -= len(chunk) - return b"".join(s) + data = self.fp.read(amt) + if len(data) < amt: + raise IncompleteRead(data, amt-len(data)) + return data def _safe_readinto(self, b): """Same as _safe_read, but for reading into a buffer.""" - total_bytes = 0 - mvb = memoryview(b) - while total_bytes < len(b): - if MAXAMOUNT < len(mvb): - temp_mvb = mvb[0:MAXAMOUNT] - n = self.fp.readinto(temp_mvb) - else: - n = self.fp.readinto(mvb) - if not n: - raise IncompleteRead(bytes(mvb[0:total_bytes]), len(b)) - mvb = mvb[n:] - total_bytes += n - return total_bytes + amt = len(b) + n = self.fp.readinto(b) + if n < amt: + raise IncompleteRead(bytes(b[:n]), amt-n) + return n def read1(self, n=-1): """Read with at most one underlying system call. If at least one @@ -1101,6 +1089,10 @@ def putrequest(self, method, url, skip_host=False, self._method = method if not url: url = '/' + # Prevent CVE-2019-9740. + if match := _contains_disallowed_url_pchar_re.search(url): + raise InvalidURL(f"URL can't contain control characters. {url!r} " + f"(found at least {match.group()!r})") request = '%s %s %s' % (method, url, self._http_vsn_str) # Non-ASCII characters should have been eliminated earlier @@ -1427,8 +1419,7 @@ def __repr__(self): e = '' return '%s(%i bytes read%s)' % (self.__class__.__name__, len(self.partial), e) - def __str__(self): - return repr(self) + __str__ = object.__str__ class ImproperConnectionState(HTTPException): pass diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index dbb3653bb4f..be855bc4671 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,15 @@ Released on 2019-10-20? ====================================== +bpo-36429: Fix starting IDLE with pyshell. +Add idlelib.pyshell alias at top; remove pyshell alias at bottom. +Remove obsolete __name__=='__main__' command. + +bpo-30348: Increase test coverage of idlelib.autocomplete by 30%. +Patch by Louie Lu. + +bpo-23205: Add tests and refactor grep's findfiles. + bpo-36405: Use dict unpacking in idlelib. bpo-36396: Remove fgBg param of idlelib.config.GetHighlight(). diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 31520a3b0d1..4aaec1321f7 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -2225,7 +2225,7 @@ def detach(self): 'General': ''' General: -AutoComplete: Popupwait is milleseconds to wait after key char, without +AutoComplete: Popupwait is milliseconds to wait after key char, without cursor movement, before popping up completion box. Key char is '.' after identifier or a '/' (or '\\' on Windows) within a string. diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index b654ab7f2c5..ba44331e87b 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -6,7 +6,7 @@ - IDLE — Python 3.8.0a1 documentation + IDLE — Python 3.8.0a3 documentation @@ -19,7 +19,7 @@ @@ -72,7 +72,7 @@
  • - 3.8.0a1 Documentation » + 3.8.0a3 Documentation »
  • @@ -372,8 +372,8 @@ debugger. Breakpoints for a file are saved in the user’s .idlerc directory.Go to file/line
    Same as in Debug menu.
    -

    The Shell window also has an output squeezing facility explained in the -the Python Shell window subsection below.

    +

    The Shell window also has an output squeezing facility explained in the Python +Shell window subsection below.

    Squeeze
    If the cursor is over an output line, squeeze all the output between @@ -673,24 +673,22 @@ output to Shell will eventually fill memory, resulting in a memory error. In contrast, some system text windows only keep the last n lines of output. A Windows console, for instance, keeps a user-settable 1 to 9999 lines, with 300 the default.

    -

    A Tk Text widget, and hence IDLE’s Shell, displays characters (codepoints) -in the the BMP (Basic Multilingual Plane) subset of Unicode. -Which characters are displayed with a proper glyph and which with a -replacement box depends on the operating system and installed fonts. -Tab characters cause the following text to begin after -the next tab stop. (They occur every 8 ‘characters’). -Newline characters cause following text to appear on a new line. -Other control characters are ignored or displayed as a space, box, or -something else, depending on the operating system and font. -(Moving the text cursor through such output with arrow keys may exhibit -some surprising spacing behavior.)

    -
    >>> s = 'a\tb\a<\x02><\r>\bc\nd'
    ->>> len(s)
    -14
    ->>> s  # Display repr(s)
    -'a\tb\x07<\x02><\r>\x08c\nd'
    ->>> print(s, end='')  # Display s as is.
    -# Result varies by OS and font.  Try it.
    +

    A Tk Text widget, and hence IDLE’s Shell, displays characters (codepoints) in +the BMP (Basic Multilingual Plane) subset of Unicode. Which characters are +displayed with a proper glyph and which with a replacement box depends on the +operating system and installed fonts. Tab characters cause the following text +to begin after the next tab stop. (They occur every 8 ‘characters’). Newline +characters cause following text to appear on a new line. Other control +characters are ignored or displayed as a space, box, or something else, +depending on the operating system and font. (Moving the text cursor through +such output with arrow keys may exhibit some surprising spacing behavior.)

    +
    >>> s = 'a\tb\a<\x02><\r>\bc\nd'  # Enter 22 chars.
    +>>> len(s)
    +14
    +>>> s  # Display repr(s)
    +'a\tb\x07<\x02><\r>\x08c\nd'
    +>>> print(s, end='')  # Display s as is.
    +# Result varies by OS and font.  Try it.
     

    The repr function is used for interactive echo of expression @@ -723,7 +721,7 @@ facilitate development of tkinter programs. Enter root = tk.Tk() in standard Python and nothing appears. Enter the same in IDLE and a tk window appears. In standard Python, one must also enter root.update() to see the window. IDLE does the equivalent in the -background, about 20 times a second, which is about every 50 milleseconds. +background, about 20 times a second, which is about every 50 milliseconds. Next enter b = tk.Button(root, text='button'); b.pack(). Again, nothing visibly changes in standard Python until one enters root.update().

    Most tkinter programs run root.mainloop(), which usually does not @@ -912,7 +910,7 @@ also used for testing.

  • - 3.8.0a1 Documentation » + 3.8.0a3 Documentation »
  • @@ -943,7 +941,7 @@ also used for testing.



    - Last updated on Feb 23, 2019. + Last updated on Apr 26, 2019. Found a bug?
    diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py index 0603ede822b..652444a7f14 100644 --- a/Lib/idlelib/help.py +++ b/Lib/idlelib/help.py @@ -2,7 +2,7 @@ Contents are subject to revision at any time, without notice. -Help => About IDLE: diplay About Idle dialog +Help => About IDLE: display About Idle dialog diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py index 7e2c1fd2958..255210df7d9 100644 --- a/Lib/idlelib/idle_test/test_config.py +++ b/Lib/idlelib/idle_test/test_config.py @@ -521,7 +521,7 @@ def test_get_current_keyset(self): def test_get_keyset(self): conf = self.mock_config() - # Conflic with key set, should be disable to '' + # Conflict with key set, should be disable to '' conf.defaultCfg['extensions'].add_section('Foobar') conf.defaultCfg['extensions'].add_section('Foobar_cfgBindings') conf.defaultCfg['extensions'].set('Foobar', 'enable', 'True') diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 11bafdb49aa..2de42658b01 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1,6 +1,8 @@ #! /usr/bin/env python3 import sys +if __name__ == "__main__": + sys.modules['idlelib.pyshell'] = sys.modules['__main__'] try: from tkinter import * @@ -416,10 +418,7 @@ def build_subprocess_arglist(self): # run from the IDLE source directory. del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc', default=False, type='bool') - if __name__ == 'idlelib.pyshell': - command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) - else: - command = "__import__('run').main(%r)" % (del_exitf,) + command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) return [sys.executable] + w + ["-c", command, str(self.port)] def start_subprocess(self): @@ -1574,7 +1573,6 @@ def main(): capture_warnings(False) if __name__ == "__main__": - sys.modules['pyshell'] = sys.modules['__main__'] main() capture_warnings(False) # Make sure turned off; see issue 18081 diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 9962477cc56..f035bde4a0a 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -64,8 +64,7 @@ def dumps(obj, protocol=None): class CodePickler(pickle.Pickler): - dispatch_table = {types.CodeType: pickle_code} - dispatch_table.update(copyreg.dispatch_table) + dispatch_table = {types.CodeType: pickle_code, **copyreg.dispatch_table} BUFSIZE = 8*1024 diff --git a/Lib/imaplib.py b/Lib/imaplib.py index dd237f7704a..341ee25ae96 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -272,6 +272,9 @@ def __enter__(self): return self def __exit__(self, *args): + if self.state == "LOGOUT": + return + try: self.logout() except OSError: @@ -625,11 +628,8 @@ def logout(self): Returns server 'BYE' response. """ self.state = 'LOGOUT' - try: typ, dat = self._simple_command('LOGOUT') - except: typ, dat = 'NO', ['%s: %s' % sys.exc_info()[:2]] + typ, dat = self._simple_command('LOGOUT') self.shutdown() - if 'BYE' in self.untagged_responses: - return 'BYE', self.untagged_responses['BYE'] return typ, dat @@ -1012,16 +1012,17 @@ def _command(self, name, *args): def _command_complete(self, name, tag): + logout = (name == 'LOGOUT') # BYE is expected after LOGOUT - if name != 'LOGOUT': + if not logout: self._check_bye() try: - typ, data = self._get_tagged_response(tag) + typ, data = self._get_tagged_response(tag, expect_bye=logout) except self.abort as val: raise self.abort('command: %s => %s' % (name, val)) except self.error as val: raise self.error('command: %s => %s' % (name, val)) - if name != 'LOGOUT': + if not logout: self._check_bye() if typ == 'BAD': raise self.error('%s command error: %s %s' % (name, typ, data)) @@ -1117,7 +1118,7 @@ def _get_response(self): return resp - def _get_tagged_response(self, tag): + def _get_tagged_response(self, tag, expect_bye=False): while 1: result = self.tagged_commands[tag] @@ -1125,9 +1126,15 @@ def _get_tagged_response(self, tag): del self.tagged_commands[tag] return result + if expect_bye: + typ = 'BYE' + bye = self.untagged_responses.pop(typ, None) + if bye is not None: + # Server replies to the "LOGOUT" command with "BYE" + return (typ, bye) + # If we've seen a BYE at this point, the socket will be # closed, so report the BYE now. - self._check_bye() # Some have reported "unexpected response" exceptions. diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 146c6472f70..f8ff5f4f2c5 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -265,6 +265,7 @@ def _write_atomic(path, data, mode=0o666): # this might affected the first line number #32911) # Python 3.8a1 3400 (move frame block handling to compiler #17611) # Python 3.8a1 3401 (add END_ASYNC_FOR #33041) +# Python 3.8a1 3410 (PEP570 Python Positional-Only Parameters #36540) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually @@ -273,7 +274,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3401).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3410).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/inspect.py b/Lib/inspect.py index b8a142232b8..6c3027987b3 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -168,23 +168,30 @@ def isfunction(object): __kwdefaults__ dict of keyword only parameters with defaults""" return isinstance(object, types.FunctionType) +def _has_code_flag(f, flag): + """Return true if ``f`` is a function (or a method or functools.partial + wrapper wrapping a function) whose code object has the given ``flag`` + set in its flags.""" + while ismethod(f): + f = f.__func__ + f = functools._unwrap_partial(f) + if not isfunction(f): + return False + return bool(f.__code__.co_flags & flag) + def isgeneratorfunction(obj): """Return true if the object is a user-defined generator function. Generator function objects provide the same attributes as functions. See help(isfunction) for a list of attributes.""" - obj = functools._unwrap_partial(obj) - return bool((isfunction(obj) or ismethod(obj)) and - obj.__code__.co_flags & CO_GENERATOR) + return _has_code_flag(obj, CO_GENERATOR) def iscoroutinefunction(obj): """Return true if the object is a coroutine function. Coroutine functions are defined with "async def" syntax. """ - obj = functools._unwrap_partial(obj) - return bool(((isfunction(obj) or ismethod(obj)) and - obj.__code__.co_flags & CO_COROUTINE)) + return _has_code_flag(obj, CO_COROUTINE) def isasyncgenfunction(obj): """Return true if the object is an asynchronous generator function. @@ -192,9 +199,7 @@ def isasyncgenfunction(obj): Asynchronous generator functions are defined with "async def" syntax and have "yield" expressions in their body. """ - obj = functools._unwrap_partial(obj) - return bool((isfunction(obj) or ismethod(obj)) and - obj.__code__.co_flags & CO_ASYNC_GENERATOR) + return _has_code_flag(obj, CO_ASYNC_GENERATOR) def isasyncgen(object): """Return true if the object is an asynchronous generator.""" @@ -267,6 +272,7 @@ def iscode(object): | 16=nested | 32=generator | 64=nofree | 128=coroutine | 256=iterable_coroutine | 512=async_generator co_freevars tuple of names of free variables + co_posonlyargcount number of positional only arguments co_kwonlyargcount number of keyword only arguments (not including ** arg) co_lnotab encoded mapping of line numbers to bytecode indices co_name name with which this code object was defined @@ -582,9 +588,12 @@ def _finddoc(obj): cls = obj.__objclass__ if getattr(cls, name) is not obj: return None + if ismemberdescriptor(obj): + slots = getattr(cls, '__slots__', None) + if isinstance(slots, dict) and name in slots: + return slots[name] else: return None - for base in cls.__mro__: try: doc = getattr(base, name).__doc__ @@ -1023,26 +1032,20 @@ def getargs(co): 'args' is the list of argument names. Keyword-only arguments are appended. 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" - args, varargs, kwonlyargs, varkw = _getfullargs(co) - return Arguments(args + kwonlyargs, varargs, varkw) - -def _getfullargs(co): - """Get information about the arguments accepted by a code object. - - Four things are returned: (args, varargs, kwonlyargs, varkw), where - 'args' and 'kwonlyargs' are lists of argument names, and 'varargs' - and 'varkw' are the names of the * and ** arguments or None.""" - if not iscode(co): raise TypeError('{!r} is not a code object'.format(co)) - nargs = co.co_argcount names = co.co_varnames + nargs = co.co_argcount + nposonlyargs = co.co_posonlyargcount nkwargs = co.co_kwonlyargcount - args = list(names[:nargs]) - kwonlyargs = list(names[nargs:nargs+nkwargs]) + nposargs = nargs + nposonlyargs + posonlyargs = list(names[:nposonlyargs]) + args = list(names[nposonlyargs:nposonlyargs+nargs]) + kwonlyargs = list(names[nposargs:nposargs+nkwargs]) step = 0 + nargs += nposonlyargs nargs += nkwargs varargs = None if co.co_flags & CO_VARARGS: @@ -1051,8 +1054,7 @@ def _getfullargs(co): varkw = None if co.co_flags & CO_VARKEYWORDS: varkw = co.co_varnames[nargs] - return args, varargs, kwonlyargs, varkw - + return Arguments(posonlyargs + args + kwonlyargs, varargs, varkw) ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') @@ -1083,7 +1085,7 @@ def getargspec(func): getfullargspec(func) if kwonlyargs or ann: raise ValueError("Function has keyword-only parameters or annotations" - ", use getfullargspec() API which can support them") + ", use inspect.signature() API which can support them") return ArgSpec(args, varargs, varkw, defaults) FullArgSpec = namedtuple('FullArgSpec', @@ -1101,11 +1103,16 @@ def getfullargspec(func): 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults. 'annotations' is a dictionary mapping parameter names to annotations. + .. deprecated:: 3.8 + Use inspect.signature() instead of inspect.getfullargspec(). + Notable differences from inspect.signature(): - the "self" parameter is always reported, even for bound methods - wrapper chains defined by __wrapped__ *not* unwrapped automatically """ + warnings.warn("Use inspect.signature() instead of inspect.getfullargspec()", + DeprecationWarning, stacklevel=2) try: # Re: `skip_bound_arg=False` # @@ -1137,6 +1144,7 @@ def getfullargspec(func): args = [] varargs = None varkw = None + posonlyargs = [] kwonlyargs = [] defaults = () annotations = {} @@ -1151,7 +1159,9 @@ def getfullargspec(func): name = param.name if kind is _POSITIONAL_ONLY: - args.append(name) + posonlyargs.append(name) + if param.default is not param.empty: + defaults += (param.default,) elif kind is _POSITIONAL_OR_KEYWORD: args.append(name) if param.default is not param.empty: @@ -1176,7 +1186,7 @@ def getfullargspec(func): # compatibility with 'func.__defaults__' defaults = None - return FullArgSpec(args, varargs, varkw, defaults, + return FullArgSpec(posonlyargs + args, varargs, varkw, defaults, kwonlyargs, kwdefaults, annotations) @@ -2111,7 +2121,7 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True): return _signature_fromstr(cls, func, s, skip_bound_arg) -def _signature_from_function(cls, func): +def _signature_from_function(cls, func, skip_bound_arg=True): """Private helper: constructs Signature for the given python function.""" is_duck_function = False @@ -2123,15 +2133,22 @@ def _signature_from_function(cls, func): # of pure function: raise TypeError('{!r} is not a Python function'.format(func)) + s = getattr(func, "__text_signature__", None) + if s: + return _signature_fromstr(cls, func, s, skip_bound_arg) + Parameter = cls._parameter_cls # Parameter information. func_code = func.__code__ pos_count = func_code.co_argcount arg_names = func_code.co_varnames - positional = tuple(arg_names[:pos_count]) + posonly_count = func_code.co_posonlyargcount + positional_count = posonly_count + pos_count + positional_only = tuple(arg_names[:posonly_count]) + positional = tuple(arg_names[posonly_count:positional_count]) keyword_only_count = func_code.co_kwonlyargcount - keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)] + keyword_only = arg_names[positional_count:(positional_count + keyword_only_count)] annotations = func.__annotations__ defaults = func.__defaults__ kwdefaults = func.__kwdefaults__ @@ -2143,23 +2160,33 @@ def _signature_from_function(cls, func): parameters = [] + non_default_count = positional_count - pos_default_count + all_positional = positional_only + positional + + posonly_left = posonly_count + # Non-keyword-only parameters w/o defaults. - non_default_count = pos_count - pos_default_count - for name in positional[:non_default_count]: + for name in all_positional[:non_default_count]: + kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, - kind=_POSITIONAL_OR_KEYWORD)) + kind=kind)) + if posonly_left: + posonly_left -= 1 # ... w/ defaults. - for offset, name in enumerate(positional[non_default_count:]): + for offset, name in enumerate(all_positional[non_default_count:]): + kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, - kind=_POSITIONAL_OR_KEYWORD, + kind=kind, default=defaults[offset])) + if posonly_left: + posonly_left -= 1 # *args if func_code.co_flags & CO_VARARGS: - name = arg_names[pos_count + keyword_only_count] + name = arg_names[positional_count + keyword_only_count] annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, kind=_VAR_POSITIONAL)) @@ -2176,7 +2203,7 @@ def _signature_from_function(cls, func): default=default)) # **kwargs if func_code.co_flags & CO_VARKEYWORDS: - index = pos_count + keyword_only_count + index = positional_count + keyword_only_count if func_code.co_flags & CO_VARARGS: index += 1 @@ -2278,7 +2305,8 @@ def _signature_from_callable(obj, *, if isfunction(obj) or _signature_is_functionlike(obj): # If it's a pure Python function, or an object that is duck type # of a Python function (Cython functions, for instance), then: - return _signature_from_function(sigcls, obj) + return _signature_from_function(sigcls, obj, + skip_bound_arg=skip_bound_arg) if _signature_is_builtin(obj): return _signature_from_builtin(sigcls, obj, diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 15507d61dec..662d7373890 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -532,6 +532,30 @@ def _prefix_from_ip_string(cls, ip_str): except ValueError: cls._report_invalid_netmask(ip_str) + @classmethod + def _split_addr_prefix(cls, address): + """Helper function to parse address of Network/Interface. + + Arg: + address: Argument of Network/Interface. + + Returns: + (addr, prefix) tuple. + """ + # a packed address or integer + if isinstance(address, (bytes, int)): + return address, cls._max_prefixlen + + if not isinstance(address, tuple): + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + address = _split_optional_netmask(address) + + # Constructing from a tuple (addr, [mask]) + if len(address) > 1: + return address + return address[0], cls._max_prefixlen + def __reduce__(self): return self.__class__, (str(self),) @@ -597,15 +621,11 @@ def __reduce__(self): @functools.total_ordering class _BaseNetwork(_IPAddressBase): - """A generic IP network object. This IP class contains the version independent methods which are used by networks. - """ - def __init__(self, address): - self._cache = {} def __repr__(self): return '%s(%r)' % (self.__class__.__name__, str(self)) @@ -677,8 +697,7 @@ def __contains__(self, other): # dealing with another address else: # address - return (int(self.network_address) <= int(other._ip) <= - int(self.broadcast_address)) + return other._ip & self.netmask._ip == self.network_address._ip def overlaps(self, other): """Tell if self is partly contained in other.""" @@ -687,22 +706,14 @@ def overlaps(self, other): other.network_address in self or ( other.broadcast_address in self))) - @property + @functools.cached_property def broadcast_address(self): - x = self._cache.get('broadcast_address') - if x is None: - x = self._address_class(int(self.network_address) | - int(self.hostmask)) - self._cache['broadcast_address'] = x - return x + return self._address_class(int(self.network_address) | + int(self.hostmask)) - @property + @functools.cached_property def hostmask(self): - x = self._cache.get('hostmask') - if x is None: - x = self._address_class(int(self.netmask) ^ self._ALL_ONES) - self._cache['hostmask'] = x - return x + return self._address_class(int(self.netmask) ^ self._ALL_ONES) @property def with_prefixlen(self): @@ -1077,9 +1088,6 @@ class _BaseV4: # Equivalent to 255.255.255.255 or 32 bits of 1's. _ALL_ONES = (2**IPV4LENGTH) - 1 - # the valid octets for host and netmasks. only useful for IPv4. - _valid_mask_octets = frozenset({255, 254, 252, 248, 240, 224, 192, 128, 0}) - _max_prefixlen = IPV4LENGTH # There are only a handful of valid v4 netmasks, so we cache them all # when constructed (see _make_netmask()). @@ -1165,12 +1173,6 @@ def _parse_octet(cls, octet_str): raise ValueError(msg % octet_str) # Convert to integer (we know digits are legal) octet_int = int(octet_str, 10) - # Any octets that look like they *might* be written in octal, - # and which don't look exactly the same in both octal and - # decimal are rejected as ambiguous - if octet_int > 7 and octet_str[0] == '0': - msg = "Ambiguous (octal/decimal) value in %r not permitted" - raise ValueError(msg % octet_str) if octet_int > 255: raise ValueError("Octet %d (> 255) not permitted" % octet_int) return octet_int @@ -1188,58 +1190,6 @@ def _string_from_ip_int(cls, ip_int): """ return '.'.join(map(str, ip_int.to_bytes(4, 'big'))) - def _is_valid_netmask(self, netmask): - """Verify that the netmask is valid. - - Args: - netmask: A string, either a prefix or dotted decimal - netmask. - - Returns: - A boolean, True if the prefix represents a valid IPv4 - netmask. - - """ - mask = netmask.split('.') - if len(mask) == 4: - try: - for x in mask: - if int(x) not in self._valid_mask_octets: - return False - except ValueError: - # Found something that isn't an integer or isn't valid - return False - for idx, y in enumerate(mask): - if idx > 0 and y > mask[idx - 1]: - return False - return True - try: - netmask = int(netmask) - except ValueError: - return False - return 0 <= netmask <= self._max_prefixlen - - def _is_hostmask(self, ip_str): - """Test if the IP string is a hostmask (rather than a netmask). - - Args: - ip_str: A string, the potential hostmask. - - Returns: - A boolean, True if the IP string is a hostmask. - - """ - bits = ip_str.split('.') - try: - parts = [x for x in map(int, bits) if x in self._valid_mask_octets] - except ValueError: - return False - if len(parts) != len(bits): - return False - if parts[0] < parts[-1]: - return True - return False - def _reverse_pointer(self): """Return the reverse DNS pointer name for the IPv4 address. @@ -1378,36 +1328,20 @@ def is_link_local(self): class IPv4Interface(IPv4Address): def __init__(self, address): - if isinstance(address, (bytes, int)): - IPv4Address.__init__(self, address) - self.network = IPv4Network(self._ip) - self._prefixlen = self._max_prefixlen - return + addr, mask = self._split_addr_prefix(address) - if isinstance(address, tuple): - IPv4Address.__init__(self, address[0]) - if len(address) > 1: - self._prefixlen = int(address[1]) - else: - self._prefixlen = self._max_prefixlen - - self.network = IPv4Network(address, strict=False) - self.netmask = self.network.netmask - self.hostmask = self.network.hostmask - return - - addr = _split_optional_netmask(address) - IPv4Address.__init__(self, addr[0]) - - self.network = IPv4Network(address, strict=False) + IPv4Address.__init__(self, addr) + self.network = IPv4Network((addr, mask), strict=False) + self.netmask = self.network.netmask self._prefixlen = self.network._prefixlen - self.netmask = self.network.netmask - self.hostmask = self.network.hostmask + @functools.cached_property + def hostmask(self): + return self.network.hostmask def __str__(self): return '%s/%d' % (self._string_from_ip_int(self._ip), - self.network.prefixlen) + self._prefixlen) def __eq__(self, other): address_equal = IPv4Address.__eq__(self, other) @@ -1474,7 +1408,6 @@ class IPv4Network(_BaseV4, _BaseNetwork): _address_class = IPv4Address def __init__(self, address, strict=True): - """Instantiate a new IPv4 network object. Args: @@ -1508,24 +1441,8 @@ def __init__(self, address, strict=True): an IPv4 address. ValueError: If strict is True and a network address is not supplied. - """ - _BaseNetwork.__init__(self, address) - - # Constructing from a packed address or integer - if isinstance(address, (int, bytes)): - addr = address - mask = self._max_prefixlen - # Constructing from a tuple (addr, [mask]) - elif isinstance(address, tuple): - addr = address[0] - mask = address[1] if len(address) > 1 else self._max_prefixlen - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - else: - args = _split_optional_netmask(address) - addr = self._ip_int_from_string(args[0]) - mask = args[1] if len(args) == 2 else self._max_prefixlen + addr, mask = self._split_addr_prefix(address) self.network_address = IPv4Address(addr) self.netmask, self._prefixlen = self._make_netmask(mask) @@ -2056,32 +1973,20 @@ def sixtofour(self): class IPv6Interface(IPv6Address): def __init__(self, address): - if isinstance(address, (bytes, int)): - IPv6Address.__init__(self, address) - self.network = IPv6Network(self._ip) - self._prefixlen = self._max_prefixlen - return - if isinstance(address, tuple): - IPv6Address.__init__(self, address[0]) - if len(address) > 1: - self._prefixlen = int(address[1]) - else: - self._prefixlen = self._max_prefixlen - self.network = IPv6Network(address, strict=False) - self.netmask = self.network.netmask - self.hostmask = self.network.hostmask - return + addr, mask = self._split_addr_prefix(address) - addr = _split_optional_netmask(address) - IPv6Address.__init__(self, addr[0]) - self.network = IPv6Network(address, strict=False) + IPv6Address.__init__(self, addr) + self.network = IPv6Network((addr, mask), strict=False) self.netmask = self.network.netmask self._prefixlen = self.network._prefixlen - self.hostmask = self.network.hostmask + + @functools.cached_property + def hostmask(self): + return self.network.hostmask def __str__(self): return '%s/%d' % (self._string_from_ip_int(self._ip), - self.network.prefixlen) + self._prefixlen) def __eq__(self, other): address_equal = IPv6Address.__eq__(self, other) @@ -2186,24 +2091,8 @@ def __init__(self, address, strict=True): an IPv6 address. ValueError: If strict was True and a network address was not supplied. - """ - _BaseNetwork.__init__(self, address) - - # Constructing from a packed address or integer - if isinstance(address, (int, bytes)): - addr = address - mask = self._max_prefixlen - # Constructing from a tuple (addr, [mask]) - elif isinstance(address, tuple): - addr = address[0] - mask = address[1] if len(address) > 1 else self._max_prefixlen - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - else: - args = _split_optional_netmask(address) - addr = self._ip_int_from_string(args[0]) - mask = args[1] if len(args) == 2 else self._max_prefixlen + addr, mask = self._split_addr_prefix(address) self.network_address = IPv6Address(addr) self.netmask, self._prefixlen = self._make_netmask(mask) diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index 3bb4490e818..1ba8b48bd78 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -296,7 +296,7 @@ def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) -def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, +def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. @@ -330,7 +330,7 @@ def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. - The ``encoding`` argument is ignored and deprecated. + The ``encoding`` argument is ignored and deprecated since Python 3.1. """ if isinstance(s, str): if s.startswith('\ufeff'): @@ -342,6 +342,15 @@ def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, f'not {s.__class__.__name__}') s = s.decode(detect_encoding(s), 'surrogatepass') + if "encoding" in kw: + import warnings + warnings.warn( + "'encoding' is ignored and deprecated. It will be removed in Python 3.9", + DeprecationWarning, + stacklevel=2 + ) + del kw['encoding'] + if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py index 2d7b8989c71..c8c78b9c237 100644 --- a/Lib/json/encoder.py +++ b/Lib/json/encoder.py @@ -268,7 +268,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, list=list, str=str, tuple=tuple, - _intstr=int.__str__, + _intstr=int.__repr__, ): if _indent is not None and not isinstance(_indent, str): @@ -307,7 +307,7 @@ def _iterencode_list(lst, _current_indent_level): elif value is False: yield buf + 'false' elif isinstance(value, int): - # Subclasses of int/float may override __str__, but we still + # Subclasses of int/float may override __repr__, but we still # want to encode them as integers/floats in JSON. One example # within the standard library is IntEnum. yield buf + _intstr(value) diff --git a/Lib/keyword.py b/Lib/keyword.py old mode 100755 new mode 100644 index 150c2bc46d2..ddcbb25d3d3 --- a/Lib/keyword.py +++ b/Lib/keyword.py @@ -1,98 +1,55 @@ -#! /usr/bin/env python3 - -"""Keywords (from "graminit.c") +"""Keywords (from "Grammar/Grammar") This file is automatically generated; please don't muck it up! To update the symbols in this file, 'cd' to the top directory of -the python source tree after building the interpreter and run: +the python source tree and run: - ./python Lib/keyword.py + python3 -m Parser.pgen.keywordgen Grammar/Grammar \ + Grammar/Tokens \ + Lib/keyword.py + +Alternatively, you can run 'make regen-keyword'. """ __all__ = ["iskeyword", "kwlist"] kwlist = [ -#--start keywords-- - 'False', - 'None', - 'True', - 'and', - 'as', - 'assert', - 'break', - 'class', - 'continue', - 'def', - 'del', - 'elif', - 'else', - 'except', - 'finally', - 'for', - 'from', - 'global', - 'if', - 'import', - 'in', - 'is', - 'lambda', - 'nonlocal', - 'not', - 'or', - 'pass', - 'raise', - 'return', - 'try', - 'while', - 'with', - 'yield', -#--end keywords-- - ] - -kwlist.append('async') -kwlist.append('await') -kwlist.sort() + 'False', + 'None', + 'True', + 'and', + 'as', + 'assert', + 'async', + 'await', + 'break', + 'class', + 'continue', + 'def', + 'del', + 'elif', + 'else', + 'except', + 'finally', + 'for', + 'from', + 'global', + 'if', + 'import', + 'in', + 'is', + 'lambda', + 'nonlocal', + 'not', + 'or', + 'pass', + 'raise', + 'return', + 'try', + 'while', + 'with', + 'yield' +] iskeyword = frozenset(kwlist).__contains__ - -def main(): - import sys, re - - args = sys.argv[1:] - iptfile = args and args[0] or "Python/graminit.c" - if len(args) > 1: optfile = args[1] - else: optfile = "Lib/keyword.py" - - # load the output skeleton from the target, taking care to preserve its - # newline convention. - with open(optfile, newline='') as fp: - format = fp.readlines() - nl = format[0][len(format[0].strip()):] if format else '\n' - - # scan the source file for keywords - with open(iptfile) as fp: - strprog = re.compile('"([^"]+)"') - lines = [] - for line in fp: - if '{1, "' in line: - match = strprog.search(line) - if match: - lines.append(" '" + match.group(1) + "'," + nl) - lines.sort() - - # insert the lines of keywords into the skeleton - try: - start = format.index("#--start keywords--" + nl) + 1 - end = format.index("#--end keywords--" + nl) - format[start:end] = lines - except ValueError: - sys.stderr.write("target does not contain format markers\n") - sys.exit(1) - - # write the output file - with open(optfile, 'w', newline='') as fp: - fp.writelines(format) - -if __name__ == "__main__": - main() diff --git a/Lib/lib2to3/pgen2/tokenize.py b/Lib/lib2to3/pgen2/tokenize.py index c07b34f7c64..279d322971d 100644 --- a/Lib/lib2to3/pgen2/tokenize.py +++ b/Lib/lib2to3/pgen2/tokenize.py @@ -321,7 +321,7 @@ def untokenize(iterable): Round-trip invariant for full input: Untokenized source will match input source exactly - Round-trip invariant for limited intput: + Round-trip invariant for limited input: # Output text will tokenize the back to the input t1 = [tok[:2] for tok in generate_tokens(f.readline)] newcode = untokenize(t1) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 7355396541a..16812ec8d55 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -231,49 +231,38 @@ def _releaseLock(): # Prevent a held logging lock from blocking a child from logging. if not hasattr(os, 'register_at_fork'): # Windows and friends. - def _register_at_fork_acquire_release(instance): + def _register_at_fork_reinit_lock(instance): pass # no-op when os.register_at_fork does not exist. -else: # The os.register_at_fork API exists - os.register_at_fork(before=_acquireLock, - after_in_child=_releaseLock, - after_in_parent=_releaseLock) +else: + # A collection of instances with a createLock method (logging.Handler) + # to be called in the child after forking. The weakref avoids us keeping + # discarded Handler instances alive. A set is used to avoid accumulating + # duplicate registrations as createLock() is responsible for registering + # a new Handler instance with this set in the first place. + _at_fork_reinit_lock_weakset = weakref.WeakSet() - # A collection of instances with acquire and release methods (logging.Handler) - # to be called before and after fork. The weakref avoids us keeping discarded - # Handler instances alive forever in case an odd program creates and destroys - # many over its lifetime. - _at_fork_acquire_release_weakset = weakref.WeakSet() + def _register_at_fork_reinit_lock(instance): + _acquireLock() + try: + _at_fork_reinit_lock_weakset.add(instance) + finally: + _releaseLock() - - def _register_at_fork_acquire_release(instance): - # We put the instance itself in a single WeakSet as we MUST have only - # one atomic weak ref. used by both before and after atfork calls to - # guarantee matched pairs of acquire and release calls. - _at_fork_acquire_release_weakset.add(instance) - - - def _at_fork_weak_calls(method_name): - for instance in _at_fork_acquire_release_weakset: - method = getattr(instance, method_name) + def _after_at_fork_child_reinit_locks(): + # _acquireLock() was called in the parent before forking. + for handler in _at_fork_reinit_lock_weakset: try: - method() + handler.createLock() except Exception as err: # Similar to what PyErr_WriteUnraisable does. print("Ignoring exception from logging atfork", instance, - method_name, "method:", err, file=sys.stderr) + "._reinit_lock() method:", err, file=sys.stderr) + _releaseLock() # Acquired by os.register_at_fork(before=. - def _before_at_fork_weak_calls(): - _at_fork_weak_calls('acquire') - - - def _after_at_fork_weak_calls(): - _at_fork_weak_calls('release') - - - os.register_at_fork(before=_before_at_fork_weak_calls, - after_in_child=_after_at_fork_weak_calls, - after_in_parent=_after_at_fork_weak_calls) + os.register_at_fork(before=_acquireLock, + after_in_child=_after_at_fork_child_reinit_locks, + after_in_parent=_releaseLock) #--------------------------------------------------------------------------- @@ -364,12 +353,10 @@ def __init__(self, name, level, pathname, lineno, else: self.process = None - def __str__(self): + def __repr__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) - __repr__ = __str__ - def getMessage(self): """ Return the message for this LogRecord. @@ -902,7 +889,7 @@ def createLock(self): Acquire a thread lock for serializing access to the underlying I/O. """ self.lock = threading.RLock() - _register_at_fork_acquire_release(self) + _register_at_fork_reinit_lock(self) def acquire(self): """ @@ -1124,6 +1111,8 @@ def setStream(self, stream): def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') + # bpo-36015: name can be an int + name = str(name) if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index 10320a74d94..a36f1b6d58c 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -8,9 +8,7 @@ import sys import types import warnings -with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - import imp + LOAD_CONST = dis.opmap['LOAD_CONST'] IMPORT_NAME = dis.opmap['IMPORT_NAME'] @@ -19,6 +17,16 @@ STORE_OPS = STORE_NAME, STORE_GLOBAL EXTENDED_ARG = dis.EXTENDED_ARG +# Old imp constants: + +_SEARCH_ERROR = 0 +_PY_SOURCE = 1 +_PY_COMPILED = 2 +_C_EXTENSION = 3 +_PKG_DIRECTORY = 5 +_C_BUILTIN = 6 +_PY_FROZEN = 7 + # Modulefinder does a good job at simulating Python's, but it can not # handle __path__ modifications packages make at runtime. Therefore there # is a mechanism whereby you can register extra paths in this map for a @@ -43,6 +51,54 @@ def ReplacePackage(oldname, newname): replacePackageMap[oldname] = newname +def _find_module(name, path=None): + """An importlib reimplementation of imp.find_module (for our purposes).""" + + # It's necessary to clear the caches for our Finder first, in case any + # modules are being added/deleted/modified at runtime. In particular, + # test_modulefinder.py changes file tree contents in a cache-breaking way: + + importlib.machinery.PathFinder.invalidate_caches() + + spec = importlib.machinery.PathFinder.find_spec(name, path) + + if spec is None: + raise ImportError("No module named {name!r}".format(name=name), name=name) + + # Some special cases: + + if spec.loader is importlib.machinery.BuiltinImporter: + return None, None, ("", "", _C_BUILTIN) + + if spec.loader is importlib.machinery.FrozenImporter: + return None, None, ("", "", _PY_FROZEN) + + file_path = spec.origin + + if spec.loader.is_package(name): + return None, os.path.dirname(file_path), ("", "", _PKG_DIRECTORY) + + if isinstance(spec.loader, importlib.machinery.SourceFileLoader): + kind = _PY_SOURCE + mode = "r" + + elif isinstance(spec.loader, importlib.machinery.ExtensionFileLoader): + kind = _C_EXTENSION + mode = "rb" + + elif isinstance(spec.loader, importlib.machinery.SourcelessFileLoader): + kind = _PY_COMPILED + mode = "rb" + + else: # Should never happen. + return None, None, ("", "", _SEARCH_ERROR) + + file = open(file_path, mode) + suffix = os.path.splitext(file_path)[-1] + + return file, file_path, (suffix, mode, kind) + + class Module: def __init__(self, name, file=None, path=None): @@ -69,7 +125,7 @@ def __repr__(self): class ModuleFinder: - def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]): + def __init__(self, path=None, debug=0, excludes=None, replace_paths=None): if path is None: path = sys.path self.path = path @@ -77,8 +133,8 @@ def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]): self.badmodules = {} self.debug = debug self.indent = 0 - self.excludes = excludes - self.replace_paths = replace_paths + self.excludes = excludes if excludes is not None else [] + self.replace_paths = replace_paths if replace_paths is not None else [] self.processed_paths = [] # Used in debugging only def msg(self, level, str, *args): @@ -105,14 +161,14 @@ def msgout(self, *args): def run_script(self, pathname): self.msg(2, "run_script", pathname) with open(pathname) as fp: - stuff = ("", "r", imp.PY_SOURCE) + stuff = ("", "r", _PY_SOURCE) self.load_module('__main__', fp, pathname, stuff) def load_file(self, pathname): dir, name = os.path.split(pathname) name, ext = os.path.splitext(name) with open(pathname) as fp: - stuff = (ext, "r", imp.PY_SOURCE) + stuff = (ext, "r", _PY_SOURCE) self.load_module(name, fp, pathname, stuff) def import_hook(self, name, caller=None, fromlist=None, level=-1): @@ -279,13 +335,13 @@ def import_module(self, partname, fqname, parent): def load_module(self, fqname, fp, pathname, file_info): suffix, mode, type = file_info self.msgin(2, "load_module", fqname, fp and "fp", pathname) - if type == imp.PKG_DIRECTORY: + if type == _PKG_DIRECTORY: m = self.load_package(fqname, pathname) self.msgout(2, "load_module ->", m) return m - if type == imp.PY_SOURCE: + if type == _PY_SOURCE: co = compile(fp.read()+'\n', pathname, 'exec') - elif type == imp.PY_COMPILED: + elif type == _PY_COMPILED: try: data = fp.read() importlib._bootstrap_external._classify_pyc(data, fqname, {}) @@ -323,17 +379,20 @@ def _safe_import_hook(self, name, caller, fromlist, level=-1): except ImportError as msg: self.msg(2, "ImportError:", str(msg)) self._add_badmodule(name, caller) + except SyntaxError as msg: + self.msg(2, "SyntaxError:", str(msg)) + self._add_badmodule(name, caller) else: if fromlist: for sub in fromlist: - if sub in self.badmodules: - self._add_badmodule(sub, caller) + fullname = name + "." + sub + if fullname in self.badmodules: + self._add_badmodule(fullname, caller) continue try: self.import_hook(name, caller, [sub], level=level) except ImportError as msg: self.msg(2, "ImportError:", str(msg)) - fullname = name + "." + sub self._add_badmodule(fullname, caller) def scan_opcodes(self, co): @@ -445,10 +504,11 @@ def find_module(self, name, path, parent=None): if path is None: if name in sys.builtin_module_names: - return (None, None, ("", "", imp.C_BUILTIN)) + return (None, None, ("", "", _C_BUILTIN)) path = self.path - return imp.find_module(name, path) + + return _find_module(name, path) def report(self): """Print a report to stdout, listing the found modules with their @@ -559,8 +619,9 @@ def replace_paths_in_code(self, co): if isinstance(consts[i], type(co)): consts[i] = self.replace_paths_in_code(consts[i]) - return types.CodeType(co.co_argcount, co.co_kwonlyargcount, - co.co_nlocals, co.co_stacksize, co.co_flags, + return types.CodeType(co.co_argcount, co.co_posonlyargcount, + co.co_kwonlyargcount, co.co_nlocals, + co.co_stacksize, co.co_flags, co.co_code, tuple(consts), co.co_names, co.co_varnames, new_filename, co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 7973012b98d..22abd47fb1f 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -358,10 +358,36 @@ def shutdown(self, c): finally: self.stop_event.set() - def create(self, c, typeid, *args, **kwds): + def create(*args, **kwds): ''' Create a new shared object and return its id ''' + if len(args) >= 3: + self, c, typeid, *args = args + elif not args: + raise TypeError("descriptor 'create' of 'Server' object " + "needs an argument") + else: + if 'typeid' not in kwds: + raise TypeError('create expected at least 2 positional ' + 'arguments, got %d' % (len(args)-1)) + typeid = kwds.pop('typeid') + if len(args) >= 2: + self, c, *args = args + import warnings + warnings.warn("Passing 'typeid' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + if 'c' not in kwds: + raise TypeError('create expected at least 2 positional ' + 'arguments, got %d' % (len(args)-1)) + c = kwds.pop('c') + self, *args = args + import warnings + warnings.warn("Passing 'c' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + args = tuple(args) + with self.mutex: callable, exposed, method_to_typeid, proxytype = \ self.registry[typeid] @@ -393,6 +419,7 @@ def create(self, c, typeid, *args, **kwds): self.incref(c, ident) return ident, tuple(exposed) + create.__text_signature__ = '($self, c, typeid, /, *args, **kwds)' def get_methods(self, c, token): ''' @@ -583,10 +610,13 @@ def _run_server(cls, registry, address, authkey, serializer, writer, util.info('manager serving at %r', server.address) server.serve_forever() - def _create(self, typeid, *args, **kwds): + def _create(*args, **kwds): ''' Create a new shared object; return the token and exposed tuple ''' + self, typeid, *args = args + args = tuple(args) + assert self._state.value == State.STARTED, 'server not yet started' conn = self._Client(self._address, authkey=self._authkey) try: @@ -1261,15 +1291,26 @@ def __init__(self, *args, **kwargs): _SharedMemoryTracker(f"shmm_{self.address}_{getpid()}") util.debug(f"SharedMemoryServer started by pid {getpid()}") - def create(self, c, typeid, *args, **kwargs): + def create(*args, **kwargs): """Create a new distributed-shared object (not backed by a shared memory block) and return its id to be used in a Proxy Object.""" # Unless set up as a shared proxy, don't make shared_memory_context # a standard part of kwargs. This makes things easier for supplying # simple functions. + if len(args) >= 3: + typeod = args[2] + elif 'typeid' in kwargs: + typeid = kwargs['typeid'] + elif not args: + raise TypeError("descriptor 'create' of 'SharedMemoryServer' " + "object needs an argument") + else: + raise TypeError('create expected at least 2 positional ' + 'arguments, got %d' % (len(args)-1)) if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"): kwargs['shared_memory_context'] = self.shared_memory_context - return Server.create(self, c, typeid, *args, **kwargs) + return Server.create(*args, **kwargs) + create.__text_signature__ = '($self, c, typeid, /, *args, **kwargs)' def shutdown(self, c): "Call unlink() on all tracked shared memory, terminate the Server." diff --git a/Lib/multiprocessing/resource_sharer.py b/Lib/multiprocessing/resource_sharer.py index 730b2aa17bd..8d5c9900f69 100644 --- a/Lib/multiprocessing/resource_sharer.py +++ b/Lib/multiprocessing/resource_sharer.py @@ -59,7 +59,7 @@ def detach(self): class _ResourceSharer(object): - '''Manager for resouces using background thread.''' + '''Manager for resources using background thread.''' def __init__(self): self._key = 0 self._cache = {} diff --git a/Lib/multiprocessing/semaphore_tracker.py b/Lib/multiprocessing/semaphore_tracker.py index 82833bcf861..3c2c3ad61ae 100644 --- a/Lib/multiprocessing/semaphore_tracker.py +++ b/Lib/multiprocessing/semaphore_tracker.py @@ -44,20 +44,23 @@ def ensure_running(self): This can be run from any process. Usually a child process will use the semaphore created by its parent.''' with self._lock: - if self._pid is not None: + if self._fd is not None: # semaphore tracker was launched before, is it still running? - try: - pid, _ = os.waitpid(self._pid, os.WNOHANG) - except ChildProcessError: - # The process terminated - pass - else: - if not pid: - # => still alive - return - + if self._check_alive(): + # => still alive + return # => dead, launch it again os.close(self._fd) + + # Clean-up to avoid dangling processes. + try: + # _pid can be None if this process is a child from another + # python process, which has started the semaphore_tracker. + if self._pid is not None: + os.waitpid(self._pid, 0) + except ChildProcessError: + # The semaphore_tracker has already been terminated. + pass self._fd = None self._pid = None @@ -99,6 +102,17 @@ def ensure_running(self): finally: os.close(r) + def _check_alive(self): + '''Check that the pipe has not been closed by sending a probe.''' + try: + # We cannot use send here as it calls ensure_running, creating + # a cycle. + os.write(self._fd, b'PROBE:0\n') + except OSError: + return False + else: + return True + def register(self, name): '''Register name of semaphore with semaphore tracker.''' self._send('REGISTER', name) @@ -150,6 +164,8 @@ def main(fd): cache.add(name) elif cmd == b'UNREGISTER': cache.remove(name) + elif cmd == b'PROBE': + pass else: raise RuntimeError('unrecognized command %r' % cmd) except Exception: diff --git a/Lib/ntpath.py b/Lib/ntpath.py index b5e1d121fc5..f3cfabf0238 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -46,16 +46,10 @@ def normcase(s): Makes all characters lowercase and all slashes into backslashes.""" s = os.fspath(s) - try: - if isinstance(s, bytes): - return s.replace(b'/', b'\\').lower() - else: - return s.replace('/', '\\').lower() - except (TypeError, AttributeError): - if not isinstance(s, (bytes, str)): - raise TypeError("normcase() argument must be str or bytes, " - "not %r" % s.__class__.__name__) from None - raise + if isinstance(s, bytes): + return s.replace(b'/', b'\\').lower() + else: + return s.replace('/', '\\').lower() # Return whether a path is absolute. diff --git a/Lib/os.py b/Lib/os.py index 7741c7580d0..79ff7a22d92 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -1070,3 +1070,40 @@ def __fspath__(self): @classmethod def __subclasshook__(cls, subclass): return hasattr(subclass, '__fspath__') + + +if name == 'nt': + class _AddedDllDirectory: + def __init__(self, path, cookie, remove_dll_directory): + self.path = path + self._cookie = cookie + self._remove_dll_directory = remove_dll_directory + def close(self): + self._remove_dll_directory(self._cookie) + self.path = None + def __enter__(self): + return self + def __exit__(self, *args): + self.close() + def __repr__(self): + if self.path: + return "".format(self.path) + return "" + + def add_dll_directory(path): + """Add a path to the DLL search path. + + This search path is used when resolving dependencies for imported + extension modules (the module itself is resolved through sys.path), + and also by ctypes. + + Remove the directory by calling close() on the returned object or + using it in a with statement. + """ + import nt + cookie = nt._add_dll_directory(path) + return _AddedDllDirectory( + path, + cookie, + nt._remove_dll_directory + ) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 911b774b564..952cd94921e 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -34,7 +34,7 @@ # Internals # -# EBADF - guard agains macOS `stat` throwing EBADF +# EBADF - guard against macOS `stat` throwing EBADF _IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF) _IGNORED_WINERRORS = ( @@ -411,6 +411,8 @@ def lchmod(self, pathobj, mode): unlink = os.unlink + link_to = os.link + rmdir = os.rmdir rename = os.rename @@ -1303,6 +1305,14 @@ def lstat(self): self._raise_closed() return self._accessor.lstat(self) + def link_to(self, target): + """ + Create a hard link pointing to a path named target. + """ + if self._closed: + self._raise_closed() + self._accessor.link_to(self, target) + def rename(self, target): """ Rename this path to the given path. diff --git a/Lib/pdb.py b/Lib/pdb.py index bf3219af398..f5d33c27fc1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -491,8 +491,7 @@ def _complete_expression(self, text, line, begidx, endidx): # Collect globals and locals. It is usually not really sensible to also # complete builtins, and they clutter the namespace quite heavily, so we # leave them out. - ns = self.curframe.f_globals.copy() - ns.update(self.curframe_locals) + ns = {**self.curframe.f_globals, **self.curframe_locals} if '.' in text: # Walk an attribute chain up to the last part, similar to what # rlcompleter does. This will bail if any of the parts are not @@ -1377,8 +1376,7 @@ def do_interact(self, arg): Start an interactive interpreter whose global namespace contains all the (global and local) names found in the current scope. """ - ns = self.curframe.f_globals.copy() - ns.update(self.curframe_locals) + ns = {**self.curframe.f_globals, **self.curframe_locals} code.interact("*interactive*", local=ns) def do_alias(self, arg): diff --git a/Lib/platform.py b/Lib/platform.py index 2ab68aed786..6fbb7b08c59 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -72,7 +72,7 @@ # type information # 0.4.0 - added win32_ver() and modified the platform() output for WinXX # 0.3.4 - fixed a bug in _follow_symlinks() -# 0.3.3 - fixed popen() and "file" command invokation bugs +# 0.3.3 - fixed popen() and "file" command invocation bugs # 0.3.2 - added architecture() API and support for it in platform() # 0.3.1 - fixed syscmd_ver() RE to support Windows NT # 0.3.0 - added system alias support @@ -334,15 +334,32 @@ def _syscmd_ver(system='', release='', version='', (6, None): "post2012ServerR2", } +def win32_is_iot(): + return win32_edition() in ('IoTUAP', 'NanoServer', 'WindowsCoreHeadless', 'IoTEdgeOS') + +def win32_edition(): + try: + try: + import winreg + except ImportError: + import _winreg as winreg + except ImportError: + pass + else: + try: + cvkey = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion' + with winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, cvkey) as key: + return winreg.QueryValueEx(key, 'EditionId')[0] + except OSError: + pass + + return None + def win32_ver(release='', version='', csd='', ptype=''): try: from sys import getwindowsversion except ImportError: return release, version, csd, ptype - try: - from winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE - except ImportError: - from _winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE winver = getwindowsversion() maj, min, build = winver.platform_version or winver[:3] @@ -368,16 +385,20 @@ def win32_ver(release='', version='', csd='', ptype=''): _WIN32_SERVER_RELEASES.get((maj, None)) or release) - key = None try: - key = OpenKeyEx(HKEY_LOCAL_MACHINE, - r'SOFTWARE\Microsoft\Windows NT\CurrentVersion') - ptype = QueryValueEx(key, 'CurrentType')[0] - except: + try: + import winreg + except ImportError: + import _winreg as winreg + except ImportError: pass - finally: - if key: - CloseKey(key) + else: + try: + cvkey = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion' + with winreg.OpenKeyEx(HKEY_LOCAL_MACHINE, cvkey) as key: + ptype = QueryValueEx(key, 'CurrentType')[0] + except: + pass return release, version, csd, ptype diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 12ab2eadbf9..ecb4e5a8f70 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -18,7 +18,7 @@ extsep = '.' sep = '/' pathsep = ':' -defpath = ':/bin:/usr/bin' +defpath = '/bin:/usr/bin' altsep = None devnull = '/dev/null' @@ -51,11 +51,7 @@ def _get_sep(path): def normcase(s): """Normalize case of pathname. Has no effect under Posix""" - s = os.fspath(s) - if not isinstance(s, (bytes, str)): - raise TypeError("normcase() argument must be str or bytes, " - "not '{}'".format(s.__class__.__name__)) - return s + return os.fspath(s) # Return whether a path is absolute. diff --git a/Lib/profile.py b/Lib/profile.py index 5df43604acd..1346297c04a 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -425,13 +425,29 @@ def runctx(self, cmd, globals, locals): return self # This method is more useful to profile a single function call. - def runcall(self, func, *args, **kw): + def runcall(*args, **kw): + if len(args) >= 2: + self, func, *args = args + elif not args: + raise TypeError("descriptor 'runcall' of 'Profile' object " + "needs an argument") + elif 'func' in kw: + func = kw.pop('func') + self, *args = args + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('runcall expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + self.set_cmd(repr(func)) sys.setprofile(self.dispatcher) try: return func(*args, **kw) finally: sys.setprofile(None) + runcall.__text_signature__ = '($self, func, /, *args, **kw)' #****************************************************************** diff --git a/Lib/pstats.py b/Lib/pstats.py index ded5ae59f7d..b7649ebc6f1 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -509,7 +509,7 @@ def func_std_string(func_name): # match what old profile produced return "%s:%d(%s)" % func_name #************************************************************************** -# The following functions combine statists for pairs functions. +# The following functions combine statistics for pairs functions. # The bulk of the processing involves correctly handling "call" lists, # such as callers and callees. #************************************************************************** diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 0cf3d335962..86ccfe041f6 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -997,8 +997,8 @@ def docdata(self, object, name=None, mod=None, cl=None): if name: push('
    %s
    \n' % name) - if object.__doc__ is not None: - doc = self.markup(getdoc(object), self.preformat) + doc = self.markup(getdoc(object), self.preformat) + if doc: push('
    %s
    \n' % doc) push('
    \n') diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index c2f9fa8e2fa..875d6e89034 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Mon Feb 25 13:03:43 2019 +# Autogenerated by Sphinx on Mon May 6 20:27:55 2019 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -162,20 +162,21 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' Note: If the object is a class instance and the attribute ' 'reference\n' - ' occurs on both sides of the assignment operator, the RHS ' - 'expression,\n' - ' "a.x" can access either an instance attribute or (if no ' - 'instance\n' - ' attribute exists) a class attribute. The LHS target "a.x" ' - 'is always\n' - ' set as an instance attribute, creating it if necessary. ' - 'Thus, the\n' - ' two occurrences of "a.x" do not necessarily refer to the ' - 'same\n' - ' attribute: if the RHS expression refers to a class ' - 'attribute, the\n' - ' LHS creates a new instance attribute as the target of the\n' - ' assignment:\n' + ' occurs on both sides of the assignment operator, the ' + 'right-hand side\n' + ' expression, "a.x" can access either an instance attribute or ' + '(if no\n' + ' instance attribute exists) a class attribute. The left-hand ' + 'side\n' + ' target "a.x" is always set as an instance attribute, ' + 'creating it if\n' + ' necessary. Thus, the two occurrences of "a.x" do not ' + 'necessarily\n' + ' refer to the same attribute: if the right-hand side ' + 'expression\n' + ' refers to a class attribute, the left-hand side creates a ' + 'new\n' + ' instance attribute as the target of the assignment:\n' '\n' ' class Cls:\n' ' x = 3 # class variable\n' @@ -3302,11 +3303,11 @@ topics = {'assert': 'The "assert" statement\n' '"str.format()"\n' ' method, to produce a “formatted” string representation ' 'of an\n' - ' object. The "format_spec" argument is a string that ' + ' object. The *format_spec* argument is a string that ' 'contains a\n' ' description of the formatting options desired. The ' 'interpretation\n' - ' of the "format_spec" argument is up to the type ' + ' of the *format_spec* argument is up to the type ' 'implementing\n' ' "__format__()", however most classes will either ' 'delegate\n' @@ -6189,8 +6190,8 @@ topics = {'assert': 'The "assert" statement\n' 'end up importing "pkg.mod". If you execute "from ..subpkg2 import ' 'mod"\n' 'from within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\n' - 'specification for relative imports is contained within **PEP ' - '328**.\n' + 'specification for relative imports is contained in the Package\n' + 'Relative Imports section.\n' '\n' '"importlib.import_module()" is provided to support applications ' 'that\n' @@ -8002,11 +8003,11 @@ topics = {'assert': 'The "assert" statement\n' '"str.format()"\n' ' method, to produce a “formatted” string representation of ' 'an\n' - ' object. The "format_spec" argument is a string that ' + ' object. The *format_spec* argument is a string that ' 'contains a\n' ' description of the formatting options desired. The ' 'interpretation\n' - ' of the "format_spec" argument is up to the type ' + ' of the *format_spec* argument is up to the type ' 'implementing\n' ' "__format__()", however most classes will either ' 'delegate\n' @@ -8768,15 +8769,15 @@ topics = {'assert': 'The "assert" statement\n' 'When a class definition is executed, the following steps ' 'occur:\n' '\n' - '* MRO entries are resolved\n' + '* MRO entries are resolved;\n' '\n' - '* the appropriate metaclass is determined\n' + '* the appropriate metaclass is determined;\n' '\n' - '* the class namespace is prepared\n' + '* the class namespace is prepared;\n' '\n' - '* the class body is executed\n' + '* the class body is executed;\n' '\n' - '* the class object is created\n' + '* the class object is created.\n' '\n' '\n' 'Resolving MRO entries\n' @@ -8806,16 +8807,16 @@ topics = {'assert': 'The "assert" statement\n' '\n' '* if no bases and no explicit metaclass are given, then ' '"type()" is\n' - ' used\n' + ' used;\n' '\n' '* if an explicit metaclass is given and it is *not* an ' 'instance of\n' - ' "type()", then it is used directly as the metaclass\n' + ' "type()", then it is used directly as the metaclass;\n' '\n' '* if an instance of "type()" is given as the explicit ' 'metaclass, or\n' ' bases are defined, then the most derived metaclass is ' - 'used\n' + 'used.\n' '\n' 'The most derived metaclass is selected from the explicitly ' 'specified\n' @@ -8931,7 +8932,7 @@ topics = {'assert': 'The "assert" statement\n' 'with the\n' ' class being defined and the assigned name of that ' 'particular\n' - ' descriptor; and\n' + ' descriptor;\n' '\n' '* finally, the "__init_subclass__()" hook is called on the ' 'immediate\n' @@ -9030,7 +9031,7 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'One can implement the generic class syntax as specified by ' '**PEP 484**\n' - '(for example "List[int]") by defining a special method\n' + '(for example "List[int]") by defining a special method:\n' '\n' 'classmethod object.__class_getitem__(cls, key)\n' '\n' @@ -9672,6 +9673,14 @@ topics = {'assert': 'The "assert" statement\n' 'capitalized\n' ' and the rest lowercased.\n' '\n' + ' Changed in version 3.8: The first character is now put ' + 'into\n' + ' titlecase rather than uppercase. This means that ' + 'characters like\n' + ' digraphs will only have their first letter capitalized, ' + 'instead of\n' + ' the full character.\n' + '\n' 'str.casefold()\n' '\n' ' Return a casefolded copy of the string. Casefolded ' @@ -10416,9 +10425,7 @@ topics = {'assert': 'The "assert" statement\n' ' >>> def titlecase(s):\n' ' ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n' ' ... lambda mo: ' - 'mo.group(0)[0].upper() +\n' - ' ... ' - 'mo.group(0)[1:].lower(),\n' + 'mo.group(0).capitalize(),\n' ' ... s)\n' ' ...\n' ' >>> titlecase("they\'re bill\'s friends.")\n' @@ -11286,17 +11293,17 @@ topics = {'assert': 'The "assert" statement\n' '| |\n' ' | | unavailable; not inherited by ' '| |\n' - ' | | subclasses ' + ' | | subclasses. ' '| |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function’s name ' + ' | "__name__" | The function’s name. ' '| Writable |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function’s *qualified name* ' + ' | "__qualname__" | The function’s *qualified ' '| Writable |\n' - ' | | New in version 3.3. ' + ' | | name*. New in version 3.3. ' '| |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' @@ -11316,7 +11323,7 @@ topics = {'assert': 'The "assert" statement\n' '| |\n' ' | | or "None" if no arguments have ' '| |\n' - ' | | a default value ' + ' | | a default value. ' '| |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' @@ -11436,15 +11443,6 @@ topics = {'assert': 'The "assert" statement\n' 'is\n' ' the original function object.\n' '\n' - ' When a user-defined method object is created by retrieving\n' - ' another method object from a class or instance, the behaviour ' - 'is\n' - ' the same as for a function object, except that the ' - '"__func__"\n' - ' attribute of the new instance is not the original method ' - 'object\n' - ' but its "__func__" attribute.\n' - '\n' ' When an instance method object is created by retrieving a ' 'class\n' ' method object from a class or instance, its "__self__" ' @@ -12181,7 +12179,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' "fromkeys()" is a class method that returns a new ' 'dictionary.\n' - ' *value* defaults to "None".\n' + ' *value* defaults to "None". All of the values refer ' + 'to just a\n' + ' single instance, so it generally doesn’t make sense ' + 'for *value*\n' + ' to be a mutable object such as an empty list. To get ' + 'distinct\n' + ' values, use a dict comprehension instead.\n' '\n' ' get(key[, default])\n' '\n' diff --git a/Lib/random.py b/Lib/random.py index 79ef30d7d18..53981f3e4f8 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -42,11 +42,18 @@ from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from os import urandom as _urandom from _collections_abc import Set as _Set, Sequence as _Sequence -from hashlib import sha512 as _sha512 from itertools import accumulate as _accumulate, repeat as _repeat from bisect import bisect as _bisect import os as _os +try: + # hashlib is pretty heavy to load, try lean internal module first + from _sha512 import sha512 as _sha512 +except ImportError: + # fallback to official implementation + from hashlib import sha512 as _sha512 + + __all__ = ["Random","seed","random","uniform","randint","choice","sample", "randrange","shuffle","normalvariate","lognormvariate", "expovariate","vonmisesvariate","gammavariate","triangular", diff --git a/Lib/shutil.py b/Lib/shutil.py index 7dd470dfaba..6cfe3738f6e 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1309,9 +1309,20 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): use_bytes = isinstance(cmd, bytes) if path is None: - path = os.environ.get("PATH", os.defpath) + path = os.environ.get("PATH", None) + if path is None: + try: + path = os.confstr("CS_PATH") + except (AttributeError, ValueError): + # os.confstr() or CS_PATH is not available + path = os.defpath + # bpo-35755: Don't use os.defpath if the PATH environment variable is + # set to an empty string + + # PATH='' doesn't match, whereas PATH=':' looks in the current directory if not path: return None + if use_bytes: path = os.fsencode(path) path = path.split(os.fsencode(os.pathsep)) diff --git a/Lib/socket.py b/Lib/socket.py index 772b9e185bf..0dd8ec70e16 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -60,8 +60,8 @@ EAGAIN = getattr(errno, 'EAGAIN', 11) EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11) -__all__ = ["fromfd", "getfqdn", "create_connection", - "AddressFamily", "SocketKind"] +__all__ = ["fromfd", "getfqdn", "create_connection", "create_server", + "has_dualstack_ipv6", "AddressFamily", "SocketKind"] __all__.extend(os._get_exports_list(_socket)) # Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for @@ -728,6 +728,92 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, else: raise error("getaddrinfo returns an empty list") + +def has_dualstack_ipv6(): + """Return True if the platform supports creating a SOCK_STREAM socket + which can handle both AF_INET and AF_INET6 (IPv4 / IPv6) connections. + """ + if not has_ipv6 \ + or not hasattr(_socket, 'IPPROTO_IPV6') \ + or not hasattr(_socket, 'IPV6_V6ONLY'): + return False + try: + with socket(AF_INET6, SOCK_STREAM) as sock: + sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0) + return True + except error: + return False + + +def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, + dualstack_ipv6=False): + """Convenience function which creates a SOCK_STREAM type socket + bound to *address* (a 2-tuple (host, port)) and return the socket + object. + + *family* should be either AF_INET or AF_INET6. + *backlog* is the queue size passed to socket.listen(). + *reuse_port* dictates whether to use the SO_REUSEPORT socket option. + *dualstack_ipv6*: if true and the platform supports it, it will + create an AF_INET6 socket able to accept both IPv4 or IPv6 + connections. When false it will explicitly disable this option on + platforms that enable it by default (e.g. Linux). + + >>> with create_server((None, 8000)) as server: + ... while True: + ... conn, addr = server.accept() + ... # handle new connection + """ + if reuse_port and not hasattr(_socket, "SO_REUSEPORT"): + raise ValueError("SO_REUSEPORT not supported on this platform") + if dualstack_ipv6: + if not has_dualstack_ipv6(): + raise ValueError("dualstack_ipv6 not supported on this platform") + if family != AF_INET6: + raise ValueError("dualstack_ipv6 requires AF_INET6 family") + sock = socket(family, SOCK_STREAM) + try: + # Note about Windows. We don't set SO_REUSEADDR because: + # 1) It's unnecessary: bind() will succeed even in case of a + # previous closed socket on the same address and still in + # TIME_WAIT state. + # 2) If set, another socket is free to bind() on the same + # address, effectively preventing this one from accepting + # connections. Also, it may set the process in a state where + # it'll no longer respond to any signals or graceful kills. + # See: msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx + if os.name not in ('nt', 'cygwin') and \ + hasattr(_socket, 'SO_REUSEADDR'): + try: + sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) + except error: + # Fail later on bind(), for platforms which may not + # support this option. + pass + if reuse_port: + sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1) + if has_ipv6 and family == AF_INET6: + if dualstack_ipv6: + sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0) + elif hasattr(_socket, "IPV6_V6ONLY") and \ + hasattr(_socket, "IPPROTO_IPV6"): + sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 1) + try: + sock.bind(address) + except error as err: + msg = '%s (while attempting to bind on address %r)' % \ + (err.strerror, address) + raise error(err.errno, msg) from None + if backlog is None: + sock.listen() + else: + sock.listen(backlog) + return sock + except error: + sock.close() + raise + + def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 13deb00bc81..8e613cb3fa5 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -59,11 +59,9 @@ def __new__(cls, value, name): self.name = name return self - def __str__(self): + def __repr__(self): return self.name - __repr__ = __str__ - MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') def _makecodes(names): diff --git a/Lib/statistics.py b/Lib/statistics.py index e5a62463f01..19db8e82801 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -7,18 +7,21 @@ Calculating averages -------------------- -================== ============================================= +================== ================================================== Function Description -================== ============================================= +================== ================================================== mean Arithmetic mean (average) of data. +fmean Fast, floating point arithmetic mean. +geometric_mean Geometric mean of data. harmonic_mean Harmonic mean of data. median Median (middle value) of data. median_low Low median of data. median_high High median of data. median_grouped Median, or 50th percentile, of grouped data. mode Mode (most common value) of data. -multimode List of modes (most common values of data) -================== ============================================= +multimode List of modes (most common values of data). +quantiles Divide data into intervals with equal probability. +================== ================================================== Calculate the arithmetic mean ("the average") of data: @@ -77,10 +80,11 @@ """ -__all__ = [ 'StatisticsError', 'NormalDist', +__all__ = [ 'StatisticsError', 'NormalDist', 'quantiles', 'pstdev', 'pvariance', 'stdev', 'variance', 'median', 'median_low', 'median_high', 'median_grouped', 'mean', 'mode', 'multimode', 'harmonic_mean', 'fmean', + 'geometric_mean', ] import math @@ -328,6 +332,24 @@ def count(x): except ZeroDivisionError: raise StatisticsError('fmean requires at least one data point') from None +def geometric_mean(data): + """Convert data to floats and compute the geometric mean. + + Raises a StatisticsError if the input dataset is empty, + if it contains a zero, or if it contains a negative value. + + No special efforts are made to achieve exact results. + (However, this may change in the future.) + + >>> round(geometric_mean([54, 24, 36]), 9) + 36.0 + """ + try: + return exp(fmean(map(log, data))) + except ValueError: + raise StatisticsError('geometric mean requires a non-empty dataset ' + ' containing positive numbers') from None + def harmonic_mean(data): """Return the harmonic mean of data. @@ -542,6 +564,54 @@ def multimode(data): maxcount, mode_items = next(groupby(counts, key=itemgetter(1)), (0, [])) return list(map(itemgetter(0), mode_items)) +def quantiles(dist, *, n=4, method='exclusive'): + '''Divide *dist* into *n* continuous intervals with equal probability. + + Returns a list of (n - 1) cut points separating the intervals. + + Set *n* to 4 for quartiles (the default). Set *n* to 10 for deciles. + Set *n* to 100 for percentiles which gives the 99 cuts points that + separate *dist* in to 100 equal sized groups. + + The *dist* can be any iterable containing sample data or it can be + an instance of a class that defines an inv_cdf() method. For sample + data, the cut points are linearly interpolated between data points. + + If *method* is set to *inclusive*, *dist* is treated as population + data. The minimum value is treated as the 0th percentile and the + maximum value is treated as the 100th percentile. + ''' + # Possible future API extensions: + # quantiles(data, already_sorted=True) + # quantiles(data, cut_points=[0.02, 0.25, 0.50, 0.75, 0.98]) + if n < 1: + raise StatisticsError('n must be at least 1') + if hasattr(dist, 'inv_cdf'): + return [dist.inv_cdf(i / n) for i in range(1, n)] + data = sorted(dist) + ld = len(data) + if ld < 2: + raise StatisticsError('must have at least two data points') + if method == 'inclusive': + m = ld - 1 + result = [] + for i in range(1, n): + j = i * m // n + delta = i*m - j*n + interpolated = (data[j] * (n - delta) + data[j+1] * delta) / n + result.append(interpolated) + return result + if method == 'exclusive': + m = ld + 1 + result = [] + for i in range(1, n): + j = i * m // n # rescale i to m/n + j = 1 if j < 1 else ld-1 if j > ld-1 else j # clamp to 1 .. ld-1 + delta = i*m - j*n # exact integer math + interpolated = (data[j-1] * (n - delta) + data[j] * delta) / n + result.append(interpolated) + return result + raise ValueError(f'Unknown method: {method!r}') # === Measures of spread === @@ -709,7 +779,8 @@ class NormalDist: # https://en.wikipedia.org/wiki/Normal_distribution # https://en.wikipedia.org/wiki/Variance#Properties - __slots__ = ('mu', 'sigma') + __slots__ = {'mu': 'Arithmetic mean of a normal distribution', + 'sigma': 'Standard deviation of a normal distribution'} def __init__(self, mu=0.0, sigma=1.0): 'NormalDist where mu is the mean and sigma is the standard deviation.' @@ -726,7 +797,7 @@ def from_samples(cls, data): xbar = fmean(data) return cls(xbar, stdev(data, xbar)) - def samples(self, n, seed=None): + def samples(self, n, *, seed=None): 'Generate *n* samples for a given mean and standard deviation.' gauss = random.gauss if seed is None else random.Random(seed).gauss mu, sigma = self.mu, self.sigma diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 0496b447e8e..6cc9eb322e2 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -203,7 +203,6 @@ def __repr__(self): return "%s(%d)" % (self.__class__.__name__, int(self)) __del__ = Close - __str__ = __repr__ else: # When select or poll has indicated that the file is writable, # we can write up to _PIPE_BUF bytes without risk of blocking. diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index cc8c7962b1b..8446c8deb24 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -626,6 +626,8 @@ def get_platform(): if os.name == 'nt': if 'amd64' in sys.version.lower(): return 'win-amd64' + if '(arm)' in sys.version.lower(): + return 'win-arm32' return sys.platform if os.name != "posix" or not hasattr(os, 'uname'): diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 30cecffd1a8..2c06f9160c6 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -717,11 +717,32 @@ class TarInfo(object): usually created internally. """ - __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", - "chksum", "type", "linkname", "uname", "gname", - "devmajor", "devminor", - "offset", "offset_data", "pax_headers", "sparse", - "tarfile", "_sparse_structs", "_link_target") + __slots__ = dict( + name = 'Name of the archive member.', + mode = 'Permission bits.', + uid = 'User ID of the user who originally stored this member.', + gid = 'Group ID of the user who originally stored this member.', + size = 'Size in bytes.', + mtime = 'Time of last modification.', + chksum = 'Header checksum.', + type = ('File type. type is usually one of these constants: ' + 'REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, ' + 'CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE.'), + linkname = ('Name of the target file name, which is only present ' + 'in TarInfo objects of type LNKTYPE and SYMTYPE.'), + uname = 'User name.', + gname = 'Group name.', + devmajor = 'Device major number.', + devminor = 'Device minor number.', + offset = 'The tar header starts here.', + offset_data = "The file's data starts here.", + pax_headers = ('A dictionary containing key-value pairs of an ' + 'associated pax extended header.'), + sparse = 'Sparse member information.', + tarfile = None, + _sparse_structs = None, + _link_target = None, + ) def __init__(self, name=""): """Construct a TarInfo object. name is the optional name @@ -747,10 +768,9 @@ def __init__(self, name=""): self.sparse = None # sparse member information self.pax_headers = {} # pax header information - # In pax headers the "name" and "linkname" field are called - # "path" and "linkpath". @property def path(self): + 'In pax headers, "name" is called "path".' return self.name @path.setter @@ -759,6 +779,7 @@ def path(self, name): @property def linkpath(self): + 'In pax headers, "linkname" is called "linkpath".' return self.linkname @linkpath.setter @@ -1350,24 +1371,42 @@ def _block(self, count): return blocks * BLOCKSIZE def isreg(self): + 'Return True if the Tarinfo object is a regular file.' return self.type in REGULAR_TYPES + def isfile(self): + 'Return True if the Tarinfo object is a regular file.' return self.isreg() + def isdir(self): + 'Return True if it is a directory.' return self.type == DIRTYPE + def issym(self): + 'Return True if it is a symbolic link.' return self.type == SYMTYPE + def islnk(self): + 'Return True if it is a hard link.' return self.type == LNKTYPE + def ischr(self): + 'Return True if it is a character device.' return self.type == CHRTYPE + def isblk(self): + 'Return True if it is a block device.' return self.type == BLKTYPE + def isfifo(self): + 'Return True if it is a FIFO.' return self.type == FIFOTYPE + def issparse(self): return self.sparse is not None + def isdev(self): + 'Return True if it is one of character device, block device or FIFO.' return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) # class TarInfo diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index f4239badfe8..836fde88cd2 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3334,9 +3334,7 @@ def _listener(cls, conn, families): new_conn.close() l.close() - l = socket.socket() - l.bind((test.support.HOST, 0)) - l.listen() + l = socket.create_server((test.support.HOST, 0)) conn.send(l.getsockname()) new_conn, addr = l.accept() conn.send(new_conn) @@ -4345,9 +4343,7 @@ def _child_test_wait_socket(cls, address, slow): def test_wait_socket(self, slow=False): from multiprocessing.connection import wait - l = socket.socket() - l.bind((test.support.HOST, 0)) - l.listen() + l = socket.create_server((test.support.HOST, 0)) addr = l.getsockname() readers = [] procs = [] @@ -4895,6 +4891,34 @@ def test_semaphore_tracker_sigkill(self): # Uncatchable signal. self.check_semaphore_tracker_death(signal.SIGKILL, True) + @staticmethod + def _is_semaphore_tracker_reused(conn, pid): + from multiprocessing.semaphore_tracker import _semaphore_tracker + _semaphore_tracker.ensure_running() + # The pid should be None in the child process, expect for the fork + # context. It should not be a new value. + reused = _semaphore_tracker._pid in (None, pid) + reused &= _semaphore_tracker._check_alive() + conn.send(reused) + + def test_semaphore_tracker_reused(self): + from multiprocessing.semaphore_tracker import _semaphore_tracker + _semaphore_tracker.ensure_running() + pid = _semaphore_tracker._pid + + r, w = multiprocessing.Pipe(duplex=False) + p = multiprocessing.Process(target=self._is_semaphore_tracker_reused, + args=(w, pid)) + p.start() + is_semaphore_tracker_reused = r.recv() + + # Clean up + p.join() + w.close() + r.close() + + self.assertTrue(is_semaphore_tracker_reused) + class TestSimpleQueue(unittest.TestCase): diff --git a/Lib/test/bisect_cmd.py b/Lib/test/bisect_cmd.py index 968537e0f80..cb06480e7c9 100755 --- a/Lib/test/bisect_cmd.py +++ b/Lib/test/bisect_cmd.py @@ -4,17 +4,17 @@ Find the test_os test method which alters the environment: - ./python -m test.bisect --fail-env-changed test_os + ./python -m test.bisect_cmd --fail-env-changed test_os Find a reference leak in "test_os", write the list of failing tests into the "bisect" file: - ./python -m test.bisect -o bisect -R 3:3 test_os + ./python -m test.bisect_cmd -o bisect -R 3:3 test_os Load an existing list of tests from a file using -i option: ./python -m test --list-cases -m FileTests test_os > tests - ./python -m test.bisect -i tests test_os + ./python -m test.bisect_cmd -i tests test_os """ import argparse diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 715f0ea6b40..af0047fafd8 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1795,6 +1795,82 @@ def test_fromisoformat_fails_typeerror(self): with self.assertRaises(TypeError): self.theclass.fromisoformat(bad_type) + def test_fromisocalendar(self): + # For each test case, assert that fromisocalendar is the + # inverse of the isocalendar function + dates = [ + (2016, 4, 3), + (2005, 1, 2), # (2004, 53, 7) + (2008, 12, 30), # (2009, 1, 2) + (2010, 1, 2), # (2009, 53, 6) + (2009, 12, 31), # (2009, 53, 4) + (1900, 1, 1), # Unusual non-leap year (year % 100 == 0) + (1900, 12, 31), + (2000, 1, 1), # Unusual leap year (year % 400 == 0) + (2000, 12, 31), + (2004, 1, 1), # Leap year + (2004, 12, 31), + (1, 1, 1), + (9999, 12, 31), + (MINYEAR, 1, 1), + (MAXYEAR, 12, 31), + ] + + for datecomps in dates: + with self.subTest(datecomps=datecomps): + dobj = self.theclass(*datecomps) + isocal = dobj.isocalendar() + + d_roundtrip = self.theclass.fromisocalendar(*isocal) + + self.assertEqual(dobj, d_roundtrip) + + def test_fromisocalendar_value_errors(self): + isocals = [ + (2019, 0, 1), + (2019, -1, 1), + (2019, 54, 1), + (2019, 1, 0), + (2019, 1, -1), + (2019, 1, 8), + (2019, 53, 1), + (10000, 1, 1), + (0, 1, 1), + (9999999, 1, 1), + (2<<32, 1, 1), + (2019, 2<<32, 1), + (2019, 1, 2<<32), + ] + + for isocal in isocals: + with self.subTest(isocal=isocal): + with self.assertRaises(ValueError): + self.theclass.fromisocalendar(*isocal) + + def test_fromisocalendar_type_errors(self): + err_txformers = [ + str, + float, + lambda x: None, + ] + + # Take a valid base tuple and transform it to contain one argument + # with the wrong type. Repeat this for each argument, e.g. + # [("2019", 1, 1), (2019, "1", 1), (2019, 1, "1"), ...] + isocals = [] + base = (2019, 1, 1) + for i in range(3): + for txformer in err_txformers: + err_val = list(base) + err_val[i] = txformer(err_val[i]) + isocals.append(tuple(err_val)) + + for isocal in isocals: + with self.subTest(isocal=isocal): + with self.assertRaises(TypeError): + self.theclass.fromisocalendar(*isocal) + + ############################################################################# # datetime tests @@ -3407,7 +3483,7 @@ def utcoffset(self, t): self.assertEqual(got, expected) # However, if they're different members, uctoffset is not ignored. - # Note that a time can't actually have an operand-depedent offset, + # Note that a time can't actually have an operand-dependent offset, # though (and time.utcoffset() passes None to tzinfo.utcoffset()), # so skip this test for time. if cls is not time: @@ -5942,6 +6018,41 @@ class TZInfoSubclass(tzinfo): with self.subTest(arg=arg, exact=exact): self.assertFalse(is_tzinfo(arg, exact)) + def test_date_from_timestamp(self): + ts = datetime(1995, 4, 12).timestamp() + + for macro in [0, 1]: + with self.subTest(macro=macro): + d = _testcapi.get_date_fromtimestamp(int(ts), macro) + + self.assertEqual(d, date(1995, 4, 12)) + + def test_datetime_from_timestamp(self): + ts0 = datetime(1995, 4, 12).timestamp() + ts1 = datetime(1995, 4, 12, 12, 30).timestamp() + + cases = [ + ((1995, 4, 12), None, False), + ((1995, 4, 12), None, True), + ((1995, 4, 12), timezone(timedelta(hours=1)), True), + ((1995, 4, 12, 14, 30), None, False), + ((1995, 4, 12, 14, 30), None, True), + ((1995, 4, 12, 14, 30), timezone(timedelta(hours=1)), True), + ] + + from_timestamp = _testcapi.get_datetime_fromtimestamp + for case in cases: + for macro in [0, 1]: + with self.subTest(case=case, macro=macro): + dtup, tzinfo, usetz = case + dt_orig = datetime(*dtup, tzinfo=tzinfo) + ts = int(dt_orig.timestamp()) + + dt_rt = from_timestamp(ts, tzinfo, usetz, macro) + + self.assertEqual(dt_orig, dt_rt) + + def load_tests(loader, standard_tests, pattern): standard_tests.addTest(ZoneInfoCompleteTest()) return standard_tests diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py index 5f956b548fc..404934ce97a 100644 --- a/Lib/test/eintrdata/eintr_tester.py +++ b/Lib/test/eintrdata/eintr_tester.py @@ -285,12 +285,9 @@ def test_sendmsg(self): self._test_send(lambda sock, data: sock.sendmsg([data])) def test_accept(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.create_server((support.HOST, 0)) self.addCleanup(sock.close) - - sock.bind((support.HOST, 0)) port = sock.getsockname()[1] - sock.listen() code = '\n'.join(( 'import socket, time', diff --git a/Lib/test/inspect_fodder.py b/Lib/test/inspect_fodder.py index ff3f0e4b73b..96a0257bfdf 100644 --- a/Lib/test/inspect_fodder.py +++ b/Lib/test/inspect_fodder.py @@ -5,7 +5,7 @@ # line 5 # line 7 -def spam(a, b, c, d=3, e=4, f=5, *g, **h): +def spam(a, /, b, c, d=3, e=4, f=5, *g, **h): eggs(b + d, c + f) # line 11 @@ -80,3 +80,14 @@ async def lobbest(grenade): raise Exception() except: tb = sys.exc_info()[2] + +class Callable: + def __call__(self, *args): + return args + + def as_method_of(self, obj): + from types import MethodType + return MethodType(self, obj) + +custom_method = Callable().as_method_of(42) +del Callable diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index c6987ea2c9e..5a7b559d07d 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -137,3 +137,19 @@ def func136(): def func137(): never_reached1 never_reached2 + +#line 141 +def positional_only_arg(a, /): + pass + +#line 145 +def all_markers(a, b, /, c, d, *, e, f): + pass + +# line 149 +def all_markers_with_args_and_kwargs(a, b, /, c, d, *args, e, f, **kwargs): + pass + +#line 153 +def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5): + pass diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index 7cd85bf2803..cb09ee0e03b 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -226,8 +226,9 @@ def _create_parser(): '(instead of the Python stdlib test suite)') group = parser.add_argument_group('Special runs') - group.add_argument('-l', '--findleaks', action='store_true', - help='if GC is available detect tests that leak memory') + group.add_argument('-l', '--findleaks', action='store_const', const=2, + default=1, + help='deprecated alias to --fail-env-changed') group.add_argument('-L', '--runleaks', action='store_true', help='run the leaks(1) command just before exit.' + more_details) @@ -309,7 +310,7 @@ def _parse_args(args, **kwargs): # Defaults ns = argparse.Namespace(testdir=None, verbose=0, quiet=False, exclude=False, single=False, randomize=False, fromfile=None, - findleaks=False, use_resources=None, trace=False, coverdir='coverage', + findleaks=1, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, random_seed=None, use_mp=None, verbose3=False, forever=False, header=False, failfast=False, match_tests=None, pgo=False) @@ -330,12 +331,13 @@ def _parse_args(args, **kwargs): parser.error("unrecognized arguments: %s" % arg) sys.exit(1) + if ns.findleaks > 1: + # --findleaks implies --fail-env-changed + ns.fail_env_changed = True if ns.single and ns.fromfile: parser.error("-s and -f don't go together!") if ns.use_mp is not None and ns.trace: parser.error("-T and -j don't go together!") - if ns.use_mp is not None and ns.findleaks: - parser.error("-l and -j don't go together!") if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 32ac44029bc..c19ea44db9b 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -20,10 +20,6 @@ from test.libregrtest.setup import setup_tests from test.libregrtest.utils import removepy, count, format_duration, printlist from test import support -try: - import gc -except ImportError: - gc = None # When tests are run from the Python build directory, it is best practice @@ -79,8 +75,8 @@ def __init__(self): self.skipped = [] self.resource_denieds = [] self.environment_changed = [] - self.rerun = [] self.run_no_tests = [] + self.rerun = [] self.first_result = None self.interrupted = False @@ -90,9 +86,6 @@ def __init__(self): # used by --coverage, trace.Trace instance self.tracer = None - # used by --findleaks, store for gc.garbage - self.found_garbage = [] - # used to display the progress bar "[ 3/100]" self.start_time = time.monotonic() self.test_count = '' @@ -105,26 +98,43 @@ def __init__(self): # used by --junit-xml self.testsuite_xml = None - def accumulate_result(self, test, result): - ok, test_time, xml_data = result - if ok not in (CHILD_ERROR, INTERRUPTED): - self.test_times.append((test_time, test)) + self.win_load_tracker = None + + def get_executed(self): + return (set(self.good) | set(self.bad) | set(self.skipped) + | set(self.resource_denieds) | set(self.environment_changed) + | set(self.run_no_tests)) + + def accumulate_result(self, result, rerun=False): + test_name = result.test_name + ok = result.result + + if ok not in (CHILD_ERROR, INTERRUPTED) and not rerun: + self.test_times.append((result.test_time, test_name)) + if ok == PASSED: - self.good.append(test) + self.good.append(test_name) elif ok in (FAILED, CHILD_ERROR): - self.bad.append(test) + if not rerun: + self.bad.append(test_name) elif ok == ENV_CHANGED: - self.environment_changed.append(test) + self.environment_changed.append(test_name) elif ok == SKIPPED: - self.skipped.append(test) + self.skipped.append(test_name) elif ok == RESOURCE_DENIED: - self.skipped.append(test) - self.resource_denieds.append(test) + self.skipped.append(test_name) + self.resource_denieds.append(test_name) elif ok == TEST_DID_NOT_RUN: - self.run_no_tests.append(test) - elif ok != INTERRUPTED: + self.run_no_tests.append(test_name) + elif ok == INTERRUPTED: + self.interrupted = True + else: raise ValueError("invalid test result: %r" % ok) + if rerun and ok not in {FAILED, CHILD_ERROR, INTERRUPTED}: + self.bad.remove(test_name) + + xml_data = result.xml_data if xml_data: import xml.etree.ElementTree as ET for e in xml_data: @@ -134,7 +144,7 @@ def accumulate_result(self, test, result): print(xml_data, file=sys.__stderr__) raise - def display_progress(self, test_index, test): + def display_progress(self, test_index, text): if self.ns.quiet: return @@ -143,12 +153,12 @@ def display_progress(self, test_index, test): fails = len(self.bad) + len(self.environment_changed) if fails and not self.ns.pgo: line = f"{line}/{fails}" - line = f"[{line}] {test}" + line = f"[{line}] {text}" # add the system load prefix: "load avg: 1.80 " - if hasattr(os, 'getloadavg'): - load_avg_1min = os.getloadavg()[0] - line = f"load avg: {load_avg_1min:.2f} {line}" + load_avg = self.getloadavg() + if load_avg is not None: + line = f"load avg: {load_avg:.2f} {line}" # add the timestamp prefix: "0:01:05 " test_time = time.monotonic() - self.start_time @@ -164,22 +174,6 @@ def parse_args(self, kwargs): "faulthandler.dump_traceback_later", file=sys.stderr) ns.timeout = None - if ns.threshold is not None and gc is None: - print('No GC available, ignore --threshold.', file=sys.stderr) - ns.threshold = None - - if ns.findleaks: - if gc is not None: - # Uncomment the line below to report garbage that is not - # freeable by reference counting alone. By default only - # garbage that is not collectable by the GC is reported. - pass - #gc.set_debug(gc.DEBUG_SAVEALL) - else: - print('No GC available, disabling --findleaks', - file=sys.stderr) - ns.findleaks = False - if ns.xmlpath: support.junit_xml_list = self.testsuite_xml = [] @@ -275,13 +269,13 @@ def list_cases(self): support.verbose = False support.set_match_tests(self.ns.match_tests) - for test in self.selected: - abstest = get_abs_module(self.ns, test) + for test_name in self.selected: + abstest = get_abs_module(self.ns, test_name) try: suite = unittest.defaultTestLoader.loadTestsFromName(abstest) self._list_cases(suite) except unittest.SkipTest: - self.skipped.append(test) + self.skipped.append(test_name) if self.skipped: print(file=sys.stderr) @@ -298,23 +292,19 @@ def rerun_failed_tests(self): print() print("Re-running failed tests in verbose mode") self.rerun = self.bad[:] - for test in self.rerun: - print("Re-running test %r in verbose mode" % test, flush=True) - try: - self.ns.verbose = True - ok = runtest(self.ns, test) - except KeyboardInterrupt: - self.interrupted = True - # print a newline separate from the ^C - print() + for test_name in self.rerun: + print(f"Re-running {test_name} in verbose mode", flush=True) + self.ns.verbose = True + result = runtest(self.ns, test_name) + + self.accumulate_result(result, rerun=True) + + if result.result == INTERRUPTED: break - else: - if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}: - self.bad.remove(test) - else: - if self.bad: - print(count(len(self.bad), 'test'), "failed again:") - printlist(self.bad) + + if self.bad: + print(count(len(self.bad), 'test'), "failed again:") + printlist(self.bad) self.display_result() @@ -327,11 +317,11 @@ def display_result(self): print("== Tests result: %s ==" % self.get_tests_result()) if self.interrupted: - print() - # print a newline after ^C print("Test suite interrupted by signal SIGINT.") - executed = set(self.good) | set(self.bad) | set(self.skipped) - omitted = set(self.selected) - executed + + omitted = set(self.selected) - self.get_executed() + if omitted: + print() print(count(len(omitted), "test"), "omitted:") printlist(omitted) @@ -348,8 +338,8 @@ def display_result(self): self.test_times.sort(reverse=True) print() print("10 slowest tests:") - for time, test in self.test_times[:10]: - print("- %s: %s" % (test, format_duration(time))) + for test_time, test in self.test_times[:10]: + print("- %s: %s" % (test, format_duration(test_time))) if self.bad: print() @@ -387,10 +377,10 @@ def run_tests_sequential(self): print("Run tests sequentially") previous_test = None - for test_index, test in enumerate(self.tests, 1): + for test_index, test_name in enumerate(self.tests, 1): start_time = time.monotonic() - text = test + text = test_name if previous_test: text = '%s -- %s' % (text, previous_test) self.display_progress(test_index, text) @@ -398,22 +388,19 @@ def run_tests_sequential(self): if self.tracer: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. - cmd = ('result = runtest(self.ns, test); ' - 'self.accumulate_result(test, result)') + cmd = ('result = runtest(self.ns, test_name); ' + 'self.accumulate_result(result)') ns = dict(locals()) self.tracer.runctx(cmd, globals=globals(), locals=ns) result = ns['result'] else: - try: - result = runtest(self.ns, test) - except KeyboardInterrupt: - self.interrupted = True - self.accumulate_result(test, (INTERRUPTED, None, None)) - break - else: - self.accumulate_result(test, result) + result = runtest(self.ns, test_name) + self.accumulate_result(result) - previous_test = format_test_result(test, result[0]) + if result.result == INTERRUPTED: + break + + previous_test = format_test_result(result) test_time = time.monotonic() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = "%s in %s" % (previous_test, format_duration(test_time)) @@ -421,16 +408,6 @@ def run_tests_sequential(self): # be quiet: say nothing if the test passed shortly previous_test = None - if self.ns.findleaks: - gc.collect() - if gc.garbage: - print("Warning: test created", len(gc.garbage), end=' ') - print("uncollectable object(s).") - # move the uncollectable objects somewhere so we don't see - # them again - self.found_garbage.extend(gc.garbage) - del gc.garbage[:] - # Unload the newly imported modules (best effort finalization) for module in sys.modules.keys(): if module not in save_modules and module.startswith("test."): @@ -441,8 +418,8 @@ def run_tests_sequential(self): def _test_forever(self, tests): while True: - for test in tests: - yield test + for test_name in tests: + yield test_name if self.bad: return if self.ns.fail_env_changed and self.environment_changed: @@ -515,6 +492,10 @@ def run_tests(self): self.run_tests_sequential() def finalize(self): + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None + if self.next_single_filename: if self.next_single_test: with open(self.next_single_filename, 'w') as fp: @@ -585,6 +566,15 @@ def main(self, tests=None, **kwargs): with support.temp_cwd(test_cwd, quiet=True): self._main(tests, kwargs) + def getloadavg(self): + if self.win_load_tracker is not None: + return self.win_load_tracker.getloadavg() + + if hasattr(os, 'getloadavg'): + return os.getloadavg()[0] + + return None + def _main(self, tests, kwargs): if self.ns.huntrleaks: warmup, repetitions, _ = self.ns.huntrleaks @@ -616,6 +606,18 @@ def _main(self, tests, kwargs): self.list_cases() sys.exit(0) + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32' and (self.ns.worker_args is None): + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except FileNotFoundError as error: + # Windows IoT Core and Windows Nano Server do not provide + # typeperf.exe for x64, x86 or ARM + print(f'Failed to create WindowsLoadTracker: {error}') + self.run_tests() self.display_result() diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 6724488fcfb..8d221232eb6 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -1,4 +1,3 @@ -import errno import os import re import sys @@ -8,13 +7,17 @@ try: from _abc import _get_dump except ImportError: + import weakref + def _get_dump(cls): - # For legacy Python version - return (cls._abc_registry, cls._abc_cache, + # Reimplement _get_dump() for pure-Python implementation of + # the abc module (Lib/_py_abc.py) + registry_weakrefs = set(weakref.ref(obj) for obj in cls._abc_registry) + return (registry_weakrefs, cls._abc_cache, cls._abc_negative_cache, cls._abc_negative_cache_version) -def dash_R(the_module, test, indirect_test, huntrleaks): +def dash_R(ns, test_name, test_func): """Run a test multiple times, looking for reference leaks. Returns: @@ -28,6 +31,10 @@ def dash_R(the_module, test, indirect_test, huntrleaks): raise Exception("Tracking reference leaks requires a debug build " "of Python") + # Avoid false positives due to various caches + # filling slowly with random data: + warm_caches() + # Save current values for dash_R_cleanup() to restore. fs = warnings.filters[:] ps = copyreg.dispatch_table.copy() @@ -53,31 +60,52 @@ def dash_R(the_module, test, indirect_test, huntrleaks): def get_pooled_int(value): return int_pool.setdefault(value, value) - nwarmup, ntracked, fname = huntrleaks + nwarmup, ntracked, fname = ns.huntrleaks fname = os.path.join(support.SAVEDCWD, fname) repcount = nwarmup + ntracked + + # Pre-allocate to ensure that the loop doesn't allocate anything new + rep_range = list(range(repcount)) rc_deltas = [0] * repcount alloc_deltas = [0] * repcount fd_deltas = [0] * repcount + getallocatedblocks = sys.getallocatedblocks + gettotalrefcount = sys.gettotalrefcount + fd_count = support.fd_count - print("beginning", repcount, "repetitions", file=sys.stderr) - print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, - flush=True) # initialize variables to make pyflakes quiet rc_before = alloc_before = fd_before = 0 - for i in range(repcount): - indirect_test() - alloc_after, rc_after, fd_after = dash_R_cleanup(fs, ps, pic, zdc, - abcs) - print('.', end='', file=sys.stderr, flush=True) - if i >= nwarmup: - rc_deltas[i] = get_pooled_int(rc_after - rc_before) - alloc_deltas[i] = get_pooled_int(alloc_after - alloc_before) - fd_deltas[i] = get_pooled_int(fd_after - fd_before) + + if not ns.quiet: + print("beginning", repcount, "repetitions", file=sys.stderr) + print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, + flush=True) + + dash_R_cleanup(fs, ps, pic, zdc, abcs) + + for i in rep_range: + test_func() + dash_R_cleanup(fs, ps, pic, zdc, abcs) + + # dash_R_cleanup() ends with collecting cyclic trash: + # read memory statistics immediately after. + alloc_after = getallocatedblocks() + rc_after = gettotalrefcount() + fd_after = fd_count() + + if not ns.quiet: + print('.', end='', file=sys.stderr, flush=True) + + rc_deltas[i] = get_pooled_int(rc_after - rc_before) + alloc_deltas[i] = get_pooled_int(alloc_after - alloc_before) + fd_deltas[i] = get_pooled_int(fd_after - fd_before) + alloc_before = alloc_after rc_before = rc_after fd_before = fd_after - print(file=sys.stderr) + + if not ns.quiet: + print(file=sys.stderr) # These checkers return False on success, True on failure def check_rc_deltas(deltas): @@ -108,7 +136,7 @@ def check_fd_deltas(deltas): deltas = deltas[nwarmup:] if checker(deltas): msg = '%s leaked %s %s, sum=%s' % ( - test, deltas, item_name, sum(deltas)) + test_name, deltas, item_name, sum(deltas)) print(msg, file=sys.stderr, flush=True) with open(fname, "a") as refrep: print(msg, file=refrep) @@ -118,7 +146,7 @@ def check_fd_deltas(deltas): def dash_R_cleanup(fs, ps, pic, zdc, abcs): - import gc, copyreg + import copyreg import collections.abc # Restore some original values. @@ -150,16 +178,8 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs): clear_caches() - # Collect cyclic trash and read memory statistics immediately after. - func1 = sys.getallocatedblocks - func2 = sys.gettotalrefcount - gc.collect() - return func1(), func2(), support.fd_count() - def clear_caches(): - import gc - # Clear the warnings registry, so they can be displayed again for mod in sys.modules.values(): if hasattr(mod, '__warningregistry__'): @@ -252,7 +272,7 @@ def clear_caches(): for f in typing._cleanups: f() - gc.collect() + support.gc_collect() def warm_caches(): diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index 4f218b769f9..a9574929a4c 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -1,4 +1,7 @@ +import collections import faulthandler +import functools +import gc import importlib import io import os @@ -6,9 +9,11 @@ import time import traceback import unittest + from test import support from test.libregrtest.refleak import dash_R, clear_caches from test.libregrtest.save_env import saved_test_environment +from test.libregrtest.utils import print_warning # Test result constants. @@ -55,9 +60,17 @@ NOTTESTS = set() -def format_test_result(test_name, result): - fmt = _FORMAT_TEST_RESULT.get(result, "%s") - return fmt % test_name +# used by --findleaks, store for gc.garbage +FOUND_GARBAGE = [] + + +def format_test_result(result): + fmt = _FORMAT_TEST_RESULT.get(result.result, "%s") + return fmt % result.test_name + + +def findtestdir(path=None): + return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): @@ -73,24 +86,84 @@ def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): return stdtests + sorted(tests) -def get_abs_module(ns, test): - if test.startswith('test.') or ns.testdir: - return test +def get_abs_module(ns, test_name): + if test_name.startswith('test.') or ns.testdir: + return test_name else: - # Always import it from the test package - return 'test.' + test + # Import it from the test package + return 'test.' + test_name -def runtest(ns, test): +TestResult = collections.namedtuple('TestResult', + 'test_name result test_time xml_data') + +def _runtest(ns, test_name): + # Handle faulthandler timeout, capture stdout+stderr, XML serialization + # and measure time. + + output_on_failure = ns.verbose3 + + use_timeout = (ns.timeout is not None) + if use_timeout: + faulthandler.dump_traceback_later(ns.timeout, exit=True) + + start_time = time.perf_counter() + try: + support.set_match_tests(ns.match_tests) + support.junit_xml_list = xml_list = [] if ns.xmlpath else None + if ns.failfast: + support.failfast = True + + if output_on_failure: + support.verbose = True + + stream = io.StringIO() + orig_stdout = sys.stdout + orig_stderr = sys.stderr + try: + sys.stdout = stream + sys.stderr = stream + result = _runtest_inner(ns, test_name, + display_failure=False) + if result != PASSED: + output = stream.getvalue() + orig_stderr.write(output) + orig_stderr.flush() + finally: + sys.stdout = orig_stdout + sys.stderr = orig_stderr + else: + # Tell tests to be moderately quiet + support.verbose = ns.verbose + + result = _runtest_inner(ns, test_name, + display_failure=not ns.verbose) + + if xml_list: + import xml.etree.ElementTree as ET + xml_data = [ET.tostring(x).decode('us-ascii') for x in xml_list] + else: + xml_data = None + + test_time = time.perf_counter() - start_time + + return TestResult(test_name, result, test_time, xml_data) + finally: + if use_timeout: + faulthandler.cancel_dump_traceback_later() + support.junit_xml_list = None + + +def runtest(ns, test_name): """Run a single test. ns -- regrtest namespace of options - test -- the name of the test + test_name -- the name of the test Returns the tuple (result, test_time, xml_data), where result is one of the constants: - INTERRUPTED KeyboardInterrupt when run under -j + INTERRUPTED KeyboardInterrupt RESOURCE_DENIED test skipped because resource denied SKIPPED test skipped for some other reason ENV_CHANGED test failed because it changed the execution environment @@ -101,130 +174,123 @@ def runtest(ns, test): If ns.xmlpath is not None, xml_data is a list containing each generated testsuite element. """ - - output_on_failure = ns.verbose3 - - use_timeout = (ns.timeout is not None) - if use_timeout: - faulthandler.dump_traceback_later(ns.timeout, exit=True) try: - support.set_match_tests(ns.match_tests) - # reset the environment_altered flag to detect if a test altered - # the environment - support.environment_altered = False - support.junit_xml_list = xml_list = [] if ns.xmlpath else None - if ns.failfast: - support.failfast = True - if output_on_failure: - support.verbose = True + return _runtest(ns, test_name) + except: + if not ns.pgo: + msg = traceback.format_exc() + print(f"test {test_name} crashed -- {msg}", + file=sys.stderr, flush=True) + return TestResult(test_name, FAILED, 0.0, None) - stream = io.StringIO() - orig_stdout = sys.stdout - orig_stderr = sys.stderr - try: - sys.stdout = stream - sys.stderr = stream - result = runtest_inner(ns, test, display_failure=False) - if result[0] != PASSED: - output = stream.getvalue() - orig_stderr.write(output) - orig_stderr.flush() - finally: - sys.stdout = orig_stdout - sys.stderr = orig_stderr - else: - support.verbose = ns.verbose # Tell tests to be moderately quiet - result = runtest_inner(ns, test, display_failure=not ns.verbose) - if xml_list: - import xml.etree.ElementTree as ET - xml_data = [ET.tostring(x).decode('us-ascii') for x in xml_list] +def _test_module(the_module): + loader = unittest.TestLoader() + tests = loader.loadTestsFromModule(the_module) + for error in loader.errors: + print(error, file=sys.stderr) + if loader.errors: + raise Exception("errors while loading tests") + support.run_unittest(tests) + + +def _runtest_inner2(ns, test_name): + # Load the test function, run the test function, handle huntrleaks + # and findleaks to detect leaks + + abstest = get_abs_module(ns, test_name) + + # remove the module from sys.module to reload it if it was already imported + support.unload(abstest) + + the_module = importlib.import_module(abstest) + + # If the test has a test_main, that will run the appropriate + # tests. If not, use normal unittest test loading. + test_runner = getattr(the_module, "test_main", None) + if test_runner is None: + test_runner = functools.partial(_test_module, the_module) + + try: + if ns.huntrleaks: + # Return True if the test leaked references + refleak = dash_R(ns, test_name, test_runner) else: - xml_data = None - return result + (xml_data,) + test_runner() + refleak = False finally: - if use_timeout: - faulthandler.cancel_dump_traceback_later() - cleanup_test_droppings(test, ns.verbose) - support.junit_xml_list = None + cleanup_test_droppings(test_name, ns.verbose) + support.gc_collect() + + if gc.garbage: + support.environment_altered = True + print_warning(f"{test_name} created {len(gc.garbage)} " + f"uncollectable object(s).") + + # move the uncollectable objects somewhere, + # so we don't see them again + FOUND_GARBAGE.extend(gc.garbage) + gc.garbage.clear() -def post_test_cleanup(): support.reap_children() + return refleak -def runtest_inner(ns, test, display_failure=True): - support.unload(test) - test_time = 0.0 - refleak = False # True if the test leaked references. +def _runtest_inner(ns, test_name, display_failure=True): + # Detect environment changes, handle exceptions. + + # Reset the environment_altered flag to detect if a test altered + # the environment + support.environment_altered = False + + if ns.pgo: + display_failure = False + try: - abstest = get_abs_module(ns, test) clear_caches() - with saved_test_environment(test, ns.verbose, ns.quiet, pgo=ns.pgo) as environment: - start_time = time.perf_counter() - the_module = importlib.import_module(abstest) - # If the test has a test_main, that will run the appropriate - # tests. If not, use normal unittest test loading. - test_runner = getattr(the_module, "test_main", None) - if test_runner is None: - def test_runner(): - loader = unittest.TestLoader() - tests = loader.loadTestsFromModule(the_module) - for error in loader.errors: - print(error, file=sys.stderr) - if loader.errors: - raise Exception("errors while loading tests") - support.run_unittest(tests) - if ns.huntrleaks: - refleak = dash_R(the_module, test, test_runner, ns.huntrleaks) - else: - test_runner() - test_time = time.perf_counter() - start_time - post_test_cleanup() + + with saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) as environment: + refleak = _runtest_inner2(ns, test_name) except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: - print(test, "skipped --", msg, flush=True) - return RESOURCE_DENIED, test_time + print(f"{test_name} skipped -- {msg}", flush=True) + return RESOURCE_DENIED except unittest.SkipTest as msg: if not ns.quiet and not ns.pgo: - print(test, "skipped --", msg, flush=True) - return SKIPPED, test_time - except KeyboardInterrupt: - raise - except support.TestFailed as msg: - if not ns.pgo: - if display_failure: - print("test", test, "failed --", msg, file=sys.stderr, - flush=True) - else: - print("test", test, "failed", file=sys.stderr, flush=True) - return FAILED, test_time + print(f"{test_name} skipped -- {msg}", flush=True) + return SKIPPED + except support.TestFailed as exc: + msg = f"test {test_name} failed" + if display_failure: + msg = f"{msg} -- {exc}" + print(msg, file=sys.stderr, flush=True) + return FAILED except support.TestDidNotRun: - return TEST_DID_NOT_RUN, test_time + return TEST_DID_NOT_RUN + except KeyboardInterrupt: + print() + return INTERRUPTED except: - msg = traceback.format_exc() if not ns.pgo: - print("test", test, "crashed --", msg, file=sys.stderr, - flush=True) - return FAILED, test_time - else: - if refleak: - return FAILED, test_time - if environment.changed: - return ENV_CHANGED, test_time - return PASSED, test_time + msg = traceback.format_exc() + print(f"test {test_name} crashed -- {msg}", + file=sys.stderr, flush=True) + return FAILED + + if refleak: + return FAILED + if environment.changed: + return ENV_CHANGED + return PASSED -def cleanup_test_droppings(testname, verbose): - import shutil - import stat - import gc - +def cleanup_test_droppings(test_name, verbose): # First kill any dangling references to open files etc. # This can also issue some ResourceWarnings which would otherwise get # triggered during the following test run, and possibly produce failures. - gc.collect() + support.gc_collect() # Try to clean up junk commonly left behind. While tests shouldn't leave # any files or directories behind, when a test fails that can be tedious @@ -239,23 +305,23 @@ def cleanup_test_droppings(testname, verbose): continue if os.path.isdir(name): + import shutil kind, nuker = "directory", shutil.rmtree elif os.path.isfile(name): kind, nuker = "file", os.unlink else: - raise SystemError("os.path says %r exists but is neither " - "directory nor file" % name) + raise RuntimeError(f"os.path says {name!r} exists but is neither " + f"directory nor file") if verbose: - print("%r left behind %s %r" % (testname, kind, name)) + print_warning("%r left behind %s %r" % (test_name, kind, name)) + support.environment_altered = True + try: + import stat # fix possible permissions problems that might prevent cleanup os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) nuker(name) - except Exception as msg: - print(("%r left behind %s %r and it couldn't be " - "removed: %s" % (testname, kind, name, msg)), file=sys.stderr) - - -def findtestdir(path=None): - return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir + except Exception as exc: + print_warning(f"{test_name} left behind {kind} {name!r} " + f"and it couldn't be removed: {exc}") diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index 6190574afdf..dbab6954de8 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -1,7 +1,9 @@ +import collections import faulthandler import json import os import queue +import subprocess import sys import threading import time @@ -11,7 +13,7 @@ from test.libregrtest.runtest import ( runtest, INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME, - format_test_result) + format_test_result, TestResult) from test.libregrtest.setup import setup_tests from test.libregrtest.utils import format_duration @@ -19,20 +21,12 @@ # Display the running tests if nothing happened last N seconds PROGRESS_UPDATE = 30.0 # seconds -# If interrupted, display the wait progress every N seconds -WAIT_PROGRESS = 2.0 # seconds + +def must_stop(result): + return result.result in (INTERRUPTED, CHILD_ERROR) def run_test_in_subprocess(testname, ns): - """Run the given test in a subprocess with --worker-args. - - ns is the option Namespace parsed from command-line arguments. regrtest - is invoked in a subprocess with the --worker-args argument; when the - subprocess exits, its return code, stdout and stderr are returned as a - 3-tuple. - """ - from subprocess import Popen, PIPE - ns_dict = vars(ns) worker_args = (ns_dict, testname) worker_args = json.dumps(worker_args) @@ -47,15 +41,12 @@ def run_test_in_subprocess(testname, ns): # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. - popen = Popen(cmd, - stdout=PIPE, stderr=PIPE, - universal_newlines=True, - close_fds=(os.name != 'nt'), - cwd=support.SAVEDCWD) - with popen: - stdout, stderr = popen.communicate() - retcode = popen.wait() - return retcode, stdout, stderr + return subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + close_fds=(os.name != 'nt'), + cwd=support.SAVEDCWD) def run_tests_worker(worker_args): @@ -64,14 +55,7 @@ def run_tests_worker(worker_args): setup_tests(ns) - try: - result = runtest(ns, testname) - except KeyboardInterrupt: - result = INTERRUPTED, '', None - except BaseException as e: - traceback.print_exc() - result = CHILD_ERROR, str(e) - + result = runtest(ns, testname) print() # Force a newline (just in case) print(json.dumps(result), flush=True) sys.exit(0) @@ -83,7 +67,6 @@ class MultiprocessIterator: """A thread-safe iterator over tests for multiprocess mode.""" def __init__(self, tests): - self.interrupted = False self.lock = threading.Lock() self.tests = tests @@ -92,152 +75,213 @@ def __iter__(self): def __next__(self): with self.lock: - if self.interrupted: - raise StopIteration('tests interrupted') return next(self.tests) +MultiprocessResult = collections.namedtuple('MultiprocessResult', + 'result stdout stderr error_msg') + class MultiprocessThread(threading.Thread): def __init__(self, pending, output, ns): super().__init__() self.pending = pending self.output = output self.ns = ns - self.current_test = None + self.current_test_name = None self.start_time = None + self._popen = None - def _runtest(self): - try: - test = next(self.pending) - except StopIteration: - self.output.put((None, None, None, None)) - return True + def kill(self): + if not self.is_alive(): + return + if self._popen is not None: + self._popen.kill() + def _runtest(self, test_name): try: self.start_time = time.monotonic() - self.current_test = test + self.current_test_name = test_name - retcode, stdout, stderr = run_test_in_subprocess(test, self.ns) + popen = run_test_in_subprocess(test_name, self.ns) + self._popen = popen + with popen: + try: + stdout, stderr = popen.communicate() + except: + popen.kill() + popen.wait() + raise + + retcode = popen.wait() finally: - self.current_test = None + self.current_test_name = None + self._popen = None + stdout = stdout.strip() + stderr = stderr.rstrip() + + err_msg = None if retcode != 0: - result = (CHILD_ERROR, "Exit code %s" % retcode, None) - self.output.put((test, stdout.rstrip(), stderr.rstrip(), - result)) - return False + err_msg = "Exit code %s" % retcode + else: + stdout, _, result = stdout.rpartition("\n") + stdout = stdout.rstrip() + if not result: + err_msg = "Failed to parse worker stdout" + else: + try: + # deserialize run_tests_worker() output + result = json.loads(result) + result = TestResult(*result) + except Exception as exc: + err_msg = "Failed to parse worker JSON: %s" % exc - stdout, _, result = stdout.strip().rpartition("\n") - if not result: - self.output.put((None, None, None, None)) - return True + if err_msg is not None: + test_time = time.monotonic() - self.start_time + result = TestResult(test_name, CHILD_ERROR, test_time, None) - result = json.loads(result) - assert len(result) == 3, f"Invalid result tuple: {result!r}" - self.output.put((test, stdout.rstrip(), stderr.rstrip(), - result)) - return False + return MultiprocessResult(result, stdout, stderr, err_msg) def run(self): + while True: + try: + try: + test_name = next(self.pending) + except StopIteration: + break + + mp_result = self._runtest(test_name) + self.output.put((False, mp_result)) + + if must_stop(mp_result.result): + break + except BaseException: + self.output.put((True, traceback.format_exc())) + break + + +def get_running(workers): + running = [] + for worker in workers: + current_test_name = worker.current_test_name + if not current_test_name: + continue + dt = time.monotonic() - worker.start_time + if dt >= PROGRESS_MIN_TIME: + text = '%s (%s)' % (current_test_name, format_duration(dt)) + running.append(text) + return running + + +class MultiprocessRunner: + def __init__(self, regrtest): + self.regrtest = regrtest + self.ns = regrtest.ns + self.output = queue.Queue() + self.pending = MultiprocessIterator(self.regrtest.tests) + if self.ns.timeout is not None: + self.test_timeout = self.ns.timeout * 1.5 + else: + self.test_timeout = None + self.workers = None + + def start_workers(self): + self.workers = [MultiprocessThread(self.pending, self.output, self.ns) + for _ in range(self.ns.use_mp)] + print("Run tests in parallel using %s child processes" + % len(self.workers)) + for worker in self.workers: + worker.start() + + def wait_workers(self): + for worker in self.workers: + worker.kill() + for worker in self.workers: + worker.join() + + def _get_result(self): + if not any(worker.is_alive() for worker in self.workers): + # all worker threads are done: consume pending results + try: + return self.output.get(timeout=0) + except queue.Empty: + return None + + while True: + if self.test_timeout is not None: + faulthandler.dump_traceback_later(self.test_timeout, exit=True) + + # wait for a thread + timeout = max(PROGRESS_UPDATE, PROGRESS_MIN_TIME) + try: + return self.output.get(timeout=timeout) + except queue.Empty: + pass + + # display progress + running = get_running(self.workers) + if running and not self.ns.pgo: + print('running: %s' % ', '.join(running), flush=True) + + def display_result(self, mp_result): + result = mp_result.result + + text = format_test_result(result) + if mp_result.error_msg is not None: + # CHILD_ERROR + text += ' (%s)' % mp_result.error_msg + elif (result.test_time >= PROGRESS_MIN_TIME and not self.ns.pgo): + text += ' (%s)' % format_duration(result.test_time) + running = get_running(self.workers) + if running and not self.ns.pgo: + text += ' -- running: %s' % ', '.join(running) + self.regrtest.display_progress(self.test_index, text) + + def _process_result(self, item): + if item[0]: + # Thread got an exception + format_exc = item[1] + print(f"regrtest worker thread failed: {format_exc}", + file=sys.stderr, flush=True) + return True + + self.test_index += 1 + mp_result = item[1] + self.regrtest.accumulate_result(mp_result.result) + self.display_result(mp_result) + + if mp_result.stdout: + print(mp_result.stdout, flush=True) + if mp_result.stderr and not self.ns.pgo: + print(mp_result.stderr, file=sys.stderr, flush=True) + + if must_stop(mp_result.result): + return True + + return False + + def run_tests(self): + self.start_workers() + + self.test_index = 0 try: - stop = False - while not stop: - stop = self._runtest() - except BaseException: - self.output.put((None, None, None, None)) - raise + while True: + item = self._get_result() + if item is None: + break + + stop = self._process_result(item) + if stop: + break + except KeyboardInterrupt: + print() + self.regrtest.interrupted = True + finally: + if self.test_timeout is not None: + faulthandler.cancel_dump_traceback_later() + + self.wait_workers() def run_tests_multiprocess(regrtest): - output = queue.Queue() - pending = MultiprocessIterator(regrtest.tests) - test_timeout = regrtest.ns.timeout - use_timeout = (test_timeout is not None) - - workers = [MultiprocessThread(pending, output, regrtest.ns) - for i in range(regrtest.ns.use_mp)] - print("Run tests in parallel using %s child processes" - % len(workers)) - for worker in workers: - worker.start() - - def get_running(workers): - running = [] - for worker in workers: - current_test = worker.current_test - if not current_test: - continue - dt = time.monotonic() - worker.start_time - if dt >= PROGRESS_MIN_TIME: - text = '%s (%s)' % (current_test, format_duration(dt)) - running.append(text) - return running - - finished = 0 - test_index = 1 - get_timeout = max(PROGRESS_UPDATE, PROGRESS_MIN_TIME) - try: - while finished < regrtest.ns.use_mp: - if use_timeout: - faulthandler.dump_traceback_later(test_timeout, exit=True) - - try: - item = output.get(timeout=get_timeout) - except queue.Empty: - running = get_running(workers) - if running and not regrtest.ns.pgo: - print('running: %s' % ', '.join(running), flush=True) - continue - - test, stdout, stderr, result = item - if test is None: - finished += 1 - continue - regrtest.accumulate_result(test, result) - - # Display progress - ok, test_time, xml_data = result - text = format_test_result(test, ok) - if (ok not in (CHILD_ERROR, INTERRUPTED) - and test_time >= PROGRESS_MIN_TIME - and not regrtest.ns.pgo): - text += ' (%s)' % format_duration(test_time) - elif ok == CHILD_ERROR: - text = '%s (%s)' % (text, test_time) - running = get_running(workers) - if running and not regrtest.ns.pgo: - text += ' -- running: %s' % ', '.join(running) - regrtest.display_progress(test_index, text) - - # Copy stdout and stderr from the child process - if stdout: - print(stdout, flush=True) - if stderr and not regrtest.ns.pgo: - print(stderr, file=sys.stderr, flush=True) - - if result[0] == INTERRUPTED: - raise KeyboardInterrupt - test_index += 1 - except KeyboardInterrupt: - regrtest.interrupted = True - pending.interrupted = True - print() - finally: - if use_timeout: - faulthandler.cancel_dump_traceback_later() - - # If tests are interrupted, wait until tests complete - wait_start = time.monotonic() - while True: - running = [worker.current_test for worker in workers] - running = list(filter(bool, running)) - if not running: - break - - dt = time.monotonic() - wait_start - line = "Waiting for %s (%s tests)" % (', '.join(running), len(running)) - if dt >= WAIT_PROGRESS: - line = "%s since %.0f sec" % (line, dt) - print(line, flush=True) - for worker in workers: - worker.join(WAIT_PROGRESS) + MultiprocessRunner(regrtest).run_tests() diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index 2313b71ec89..31931f2192f 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -9,6 +9,7 @@ import threading import warnings from test import support +from test.libregrtest.utils import print_warning try: import _multiprocessing, multiprocessing.process except ImportError: @@ -283,8 +284,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.changed = True restore(original) if not self.quiet and not self.pgo: - print(f"Warning -- {name} was modified by {self.testname}", - file=sys.stderr, flush=True) + print_warning(f"{name} was modified by {self.testname}") print(f" Before: {original}\n After: {current} ", file=sys.stderr, flush=True) return False diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index 910aca1b1a6..9a6585af9d0 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -10,8 +10,6 @@ except ImportError: gc = None -from test.libregrtest.refleak import warm_caches - def setup_tests(ns): try: @@ -79,10 +77,6 @@ def setup_tests(ns): if ns.huntrleaks: unittest.BaseTestSuite._cleanup = False - # Avoid false positives due to various caches - # filling slowly with random data: - warm_caches() - if ns.memlimit is not None: support.set_memlimit(ns.memlimit) diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index d36bf919662..fb9971a64f6 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -1,5 +1,6 @@ -import os.path import math +import os.path +import sys import textwrap @@ -54,3 +55,7 @@ def printlist(x, width=70, indent=4, file=None): print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width, initial_indent=blanks, subsequent_indent=blanks), file=file) + + +def print_warning(msg): + print(f"Warning -- {msg}", file=sys.stderr, flush=True) diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py new file mode 100644 index 00000000000..adfe278ba39 --- /dev/null +++ b/Lib/test/libregrtest/win_utils.py @@ -0,0 +1,105 @@ +import _winapi +import msvcrt +import os +import subprocess +import uuid +from test import support + + +# Max size of asynchronous reads +BUFSIZE = 8192 +# Exponential damping factor (see below) +LOAD_FACTOR_1 = 0.9200444146293232478931553241 +# Seconds per measurement +SAMPLING_INTERVAL = 5 +COUNTER_NAME = r'\System\Processor Queue Length' + + +class WindowsLoadTracker(): + """ + This class asynchronously interacts with the `typeperf` command to read + the system load on Windows. Mulitprocessing and threads can't be used + here because they interfere with the test suite's cases for those + modules. + """ + + def __init__(self): + self.load = 0.0 + self.start() + + def start(self): + # Create a named pipe which allows for asynchronous IO in Windows + pipe_name = r'\\.\pipe\typeperf_output_' + str(uuid.uuid4()) + + open_mode = _winapi.PIPE_ACCESS_INBOUND + open_mode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE + open_mode |= _winapi.FILE_FLAG_OVERLAPPED + + # This is the read end of the pipe, where we will be grabbing output + self.pipe = _winapi.CreateNamedPipe( + pipe_name, open_mode, _winapi.PIPE_WAIT, + 1, BUFSIZE, BUFSIZE, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL + ) + # The write end of the pipe which is passed to the created process + pipe_write_end = _winapi.CreateFile( + pipe_name, _winapi.GENERIC_WRITE, 0, _winapi.NULL, + _winapi.OPEN_EXISTING, 0, _winapi.NULL + ) + # Open up the handle as a python file object so we can pass it to + # subprocess + command_stdout = msvcrt.open_osfhandle(pipe_write_end, 0) + + # Connect to the read end of the pipe in overlap/async mode + overlap = _winapi.ConnectNamedPipe(self.pipe, overlapped=True) + overlap.GetOverlappedResult(True) + + # Spawn off the load monitor + command = ['typeperf', COUNTER_NAME, '-si', str(SAMPLING_INTERVAL)] + self.p = subprocess.Popen(command, stdout=command_stdout, cwd=support.SAVEDCWD) + + # Close our copy of the write end of the pipe + os.close(command_stdout) + + def close(self): + if self.p is None: + return + self.p.kill() + self.p.wait() + self.p = None + + def __del__(self): + self.close() + + def read_output(self): + import _winapi + + overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True) + bytes_read, res = overlapped.GetOverlappedResult(False) + if res != 0: + return + + return overlapped.getbuffer().decode() + + def getloadavg(self): + typeperf_output = self.read_output() + # Nothing to update, just return the current load + if not typeperf_output: + return self.load + + # Process the backlog of load values + for line in typeperf_output.splitlines(): + # typeperf outputs in a CSV format like this: + # "07/19/2018 01:32:26.605","3.000000" + toks = line.split(',') + # Ignore blank lines and the initial header + if line.strip() == '' or (COUNTER_NAME in line) or len(toks) != 2: + continue + + load = float(toks[1].replace('"', '')) + # We use an exponentially weighted moving average, imitating the + # load calculation on Unix systems. + # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation + new_load = self.load * LOAD_FACTOR_1 + load * (1.0 - LOAD_FACTOR_1) + self.load = new_load + + return self.load diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 8f687c49e69..bb8e6ce0964 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2222,7 +2222,7 @@ def remove_frames(pickled, keep_frame=None): frame_size = self.FRAME_SIZE_TARGET num_frames = 20 - # Large byte objects (dict values) intermitted with small objects + # Large byte objects (dict values) intermittent with small objects # (dict keys) obj = {i: bytes([i]) * frame_size for i in range(num_frames)} diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 07f3cb3bea4..e9edf675b91 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -571,10 +571,17 @@ def collect_cc(info_add): except ImportError: args = CC.split() args.append('--version') - proc = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - universal_newlines=True) + try: + proc = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True) + except OSError: + # Cannot run the compiler, for example when Python has been + # cross-compiled and installed on the target platform where the + # compiler is missing. + return + stdout = proc.communicate()[0] if proc.returncode: # CC --version failed: ignore error @@ -595,21 +602,17 @@ def collect_gdbm(info_add): def collect_get_config(info_add): - # Dump global configuration variables, _PyCoreConfig - # and _PyMainInterpreterConfig + # Get global configuration variables, _PyPreConfig and _PyCoreConfig try: - from _testcapi import get_global_config, get_core_config, get_main_config + from _testinternalcapi import get_configs except ImportError: return - for prefix, get_config_func in ( - ('global_config', get_global_config), - ('core_config', get_core_config), - ('main_config', get_main_config), - ): - config = get_config_func() + all_configs = get_configs() + for config_type in sorted(all_configs): + config = all_configs[config_type] for key in sorted(config): - info_add('%s[%s]' % (prefix, key), repr(config[key])) + info_add('%s[%s]' % (config_type, key), repr(config[key])) def collect_subprocess(info_add): diff --git a/Lib/test/re_tests.py b/Lib/test/re_tests.py index a379d33aec6..5ba9f1652e1 100755 --- a/Lib/test/re_tests.py +++ b/Lib/test/re_tests.py @@ -109,7 +109,7 @@ ('(?s)a.b', 'a\nb', SUCCEED, 'found', 'a\nb'), ('(?s)a.*b', 'acc\nccb', SUCCEED, 'found', 'acc\nccb'), ('(?s)a.{4,5}b', 'acc\nccb', SUCCEED, 'found', 'acc\nccb'), - ('(?s)a.b', 'a\nb', SUCCEED, 'found', 'a\nb'), + ('(?s)a.b', 'a\rb', SUCCEED, 'found', 'a\rb'), (')', '', SYNTAX_ERROR), # Unmatched right bracket ('', '', SUCCEED, 'found', ''), # Empty pattern diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 561b09a2d5e..836a43b81dd 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -977,7 +977,7 @@ def test_hash(self): def test_capitalize_nonascii(self): # check that titlecased chars are lowered correctly # \u1ffc is the titlecased char - self.checkequal('\u03a9\u0399\u1ff3\u1ff3\u1ff3', + self.checkequal('\u1ffc\u1ff3\u1ff3\u1ff3', '\u1ff3\u1ff3\u1ffc\u1ffc', 'capitalize') # check with cased non-letter chars self.checkequal('\u24c5\u24e8\u24e3\u24d7\u24de\u24dd', diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 5bd15a2feae..9e60d960ab1 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1006,7 +1006,7 @@ def temp_dir(path=None, quiet=False): yield path finally: # In case the process forks, let only the parent remove the - # directory. The child has a diffent process id. (bpo-30028) + # directory. The child has a different process id. (bpo-30028) if dir_created and pid == os.getpid(): rmtree(path) @@ -1477,6 +1477,22 @@ def __exit__(self, type_=None, value=None, traceback=None): ioerror_peer_reset = TransientResource(OSError, errno=errno.ECONNRESET) +def get_socket_conn_refused_errs(): + """ + Get the different socket error numbers ('errno') which can be received + when a connection is refused. + """ + errors = [errno.ECONNREFUSED] + if hasattr(errno, 'ENETUNREACH'): + # On Solaris, ENETUNREACH is returned sometimes instead of ECONNREFUSED + errors.append(errno.ENETUNREACH) + if hasattr(errno, 'EADDRNOTAVAIL'): + # bpo-31910: socket.create_connection() fails randomly + # with EADDRNOTAVAIL on Travis CI + errors.append(errno.EADDRNOTAVAIL) + return errors + + @contextlib.contextmanager def transient_internet(resource_name, *, timeout=30.0, errnos=()): """Return a context manager that raises ResourceDenied when various issues @@ -1637,7 +1653,7 @@ def python_is_optimized(): _header = 'nP' _align = '0n' -if hasattr(sys, "gettotalrefcount"): +if hasattr(sys, "getobjects"): _header = '2P' + _header _align = '0P' _vheader = _header + 'n' diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e39d1f2e17a..0c5bbf6752a 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -319,14 +319,14 @@ def test_field_attr_existence(self): def test_arguments(self): x = ast.arguments() - self.assertEqual(x._fields, ('args', 'vararg', 'kwonlyargs', + self.assertEqual(x._fields, ('args', 'posonlyargs', 'vararg', 'kwonlyargs', 'kw_defaults', 'kwarg', 'defaults')) with self.assertRaises(AttributeError): x.vararg - x = ast.arguments(*range(1, 7)) - self.assertEqual(x.vararg, 2) + x = ast.arguments(*range(1, 8)) + self.assertEqual(x.vararg, 3) def test_field_attr_writable(self): x = ast.Num() @@ -816,22 +816,25 @@ def test_module(self): self.mod(m, "must have Load context", "eval") def _check_arguments(self, fac, check): - def arguments(args=None, vararg=None, + def arguments(args=None, posonlyargs=None, vararg=None, kwonlyargs=None, kwarg=None, defaults=None, kw_defaults=None): if args is None: args = [] + if posonlyargs is None: + posonlyargs = [] if kwonlyargs is None: kwonlyargs = [] if defaults is None: defaults = [] if kw_defaults is None: kw_defaults = [] - args = ast.arguments(args, vararg, kwonlyargs, kw_defaults, - kwarg, defaults) + args = ast.arguments(args, posonlyargs, vararg, kwonlyargs, + kw_defaults, kwarg, defaults) return fac(args) args = [ast.arg("x", ast.Name("x", ast.Store()))] check(arguments(args=args), "must have Load context") + check(arguments(posonlyargs=args), "must have Load context") check(arguments(kwonlyargs=args), "must have Load context") check(arguments(defaults=[ast.Num(3)]), "more positional defaults than args") @@ -847,7 +850,7 @@ def arguments(args=None, vararg=None, "must have Load context") def test_funcdef(self): - a = ast.arguments([], None, [], [], None, []) + a = ast.arguments([], [], None, [], [], None, []) f = ast.FunctionDef("x", a, [], [], None) self.stmt(f, "empty body on FunctionDef") f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())], @@ -1013,7 +1016,7 @@ def test_unaryop(self): self.expr(u, "must have Load context") def test_lambda(self): - a = ast.arguments([], None, [], [], None, []) + a = ast.arguments([], [], None, [], [], None, []) self.expr(ast.Lambda(a, ast.Name("x", ast.Store())), "must have Load context") def fac(args): @@ -1636,17 +1639,17 @@ def main(): exec_results = [ ('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []), ('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 0, None)]), [('Pass', (1, 12))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42, None)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1, None), ('Constant', (1, 16), None, None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()', None))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 0, None)]), [('Pass', (1, 12))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], [], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42, None)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1, None), ('Constant', (1, 16), None, None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()', None))], [], None, None)], []), ('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []), ('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []), ('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1, None))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1, None))], [], None, None)], []), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []), ('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []), @@ -1677,16 +1680,16 @@ def main(): ('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], []), ('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], []), ('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], []), -('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function', None)), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []), -('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1, None))], [('Expr', (3, 7), ('Constant', (3, 7), 2, None))], None)], [], None, None)], []), -('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1, None))], None)], [], None, None)], []), +('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function', None)), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []), +('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1, None))], [('Expr', (3, 7), ('Constant', (3, 7), 2, None))], None)], [], None, None)], []), +('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1, None))], None)], [], None, None)], []), ('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2, None)], [('Dict', (1, 3), [('Constant', (1, 4), 1, None)], [('Constant', (1, 6), 2, None)]), ('Constant', (1, 12), 3, None)]))], []), ('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1, None), ('Constant', (1, 6), 2, None)]), ('Load',)), ('Constant', (1, 10), 3, None)]))], []), -('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []), -('Module', [('FunctionDef', (3, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []), -('Module', [('AsyncFunctionDef', (3, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (3, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []), +('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []), +('Module', [('FunctionDef', (3, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []), +('Module', [('AsyncFunctionDef', (3, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (3, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []), ('Module', [('ClassDef', (3, 0), 'C', [], [], [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])])], []), -('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []), +('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []), ('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []), ] single_results = [ @@ -1697,7 +1700,7 @@ def main(): ('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])), ('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))), ('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))), -('Expression', ('Lambda', (1, 0), ('arguments', [], None, [], [], None, []), ('Constant', (1, 7), None, None))), +('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))), ('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])), ('Expression', ('Dict', (1, 0), [], [])), ('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])), diff --git a/Lib/test/test_asyncio/functional.py b/Lib/test/test_asyncio/functional.py index 6b5b3cc907c..70cd140f479 100644 --- a/Lib/test/test_asyncio/functional.py +++ b/Lib/test/test_asyncio/functional.py @@ -60,21 +60,13 @@ def tcp_server(self, server_prog, *, else: addr = ('127.0.0.1', 0) - sock = socket.socket(family, socket.SOCK_STREAM) - + sock = socket.create_server(addr, family=family, backlog=backlog) if timeout is None: raise RuntimeError('timeout is required') if timeout <= 0: raise RuntimeError('only blocking sockets are supported') sock.settimeout(timeout) - try: - sock.bind(addr) - sock.listen(backlog) - except OSError as ex: - sock.close() - raise ex - return TestThreadedServer( self, sock, server_prog, timeout, max_clients) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 53854758a27..25420b2ff6f 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1586,6 +1586,23 @@ def test_create_datagram_endpoint_connect_err(self): self.assertRaises( OSError, self.loop.run_until_complete, coro) + def test_create_datagram_endpoint_allow_broadcast(self): + protocol = MyDatagramProto(create_future=True, loop=self.loop) + self.loop.sock_connect = sock_connect = mock.Mock() + sock_connect.return_value = [] + + coro = self.loop.create_datagram_endpoint( + lambda: protocol, + remote_addr=('127.0.0.1', 0), + allow_broadcast=True) + + transport, _ = self.loop.run_until_complete(coro) + self.assertFalse(sock_connect.called) + + transport.close() + self.loop.run_until_complete(protocol.done) + self.assertEqual('CLOSED', protocol.state) + @patch_socket def test_create_datagram_endpoint_socket_err(self, m_socket): m_socket.getaddrinfo = socket.getaddrinfo @@ -1662,6 +1679,20 @@ def test_create_datagram_endpoint_sock_unix(self): self.loop.run_until_complete(protocol.done) self.assertEqual('CLOSED', protocol.state) + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_datagram_endpoint_existing_sock_unix(self): + with test_utils.unix_socket_path() as path: + sock = socket.socket(socket.AF_UNIX, type=socket.SOCK_DGRAM) + sock.bind(path) + sock.close() + + coro = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(create_future=True, loop=self.loop), + path, family=socket.AF_UNIX) + transport, protocol = self.loop.run_until_complete(coro) + transport.close() + self.loop.run_until_complete(protocol.done) + def test_create_datagram_endpoint_sock_sockopts(self): class FakeSock: type = socket.SOCK_DGRAM diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index a2b954eec4a..b46b614e556 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -667,9 +667,7 @@ def data_received(self, data): super().data_received(data) self.transport.write(expected_response) - lsock = socket.socket() - lsock.bind(('127.0.0.1', 0)) - lsock.listen(1) + lsock = socket.create_server(('127.0.0.1', 0), backlog=1) addr = lsock.getsockname() message = b'test data' @@ -1118,9 +1116,7 @@ def connection_made(self, transport): super().connection_made(transport) proto.set_result(self) - sock_ob = socket.socket(type=socket.SOCK_STREAM) - sock_ob.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock_ob.bind(('0.0.0.0', 0)) + sock_ob = socket.create_server(('0.0.0.0', 0)) f = self.loop.create_server(TestMyProto, sock=sock_ob) server = self.loop.run_until_complete(f) @@ -1136,9 +1132,7 @@ def connection_made(self, transport): server.close() def test_create_server_addr_in_use(self): - sock_ob = socket.socket(type=socket.SOCK_STREAM) - sock_ob.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock_ob.bind(('0.0.0.0', 0)) + sock_ob = socket.create_server(('0.0.0.0', 0)) f = self.loop.create_server(MyProto, sock=sock_ob) server = self.loop.run_until_complete(f) diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index d0d171a9853..bf721b0005b 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -1065,6 +1065,7 @@ def setUp(self): self.sock.fileno.return_value = 7 def datagram_transport(self, address=None): + self.sock.getpeername.side_effect = None if address else OSError transport = _SelectorDatagramTransport(self.loop, self.sock, self.protocol, address=address) diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index 6de058a1e9b..ab7f3debbc1 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -73,7 +73,7 @@ class SelectorStartServerTests(BaseStartServer, unittest.TestCase): def new_loop(self): return asyncio.SelectorEventLoop() - @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'no Unix sockets') + @support.skip_unless_bind_unix_socket def test_start_unix_server_1(self): HELLO_MSG = b'1' * 1024 * 5 + b'\n' started = threading.Event() diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 043fac7c6a2..905141ca89c 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -42,7 +42,7 @@ def tearDown(self): @mock.patch('asyncio.streams.events') def test_ctor_global_loop(self, m_events): - stream = asyncio.StreamReader() + stream = asyncio.StreamReader(_asyncio_internal=True) self.assertIs(stream._loop, m_events.get_event_loop.return_value) def _basetest_open_connection(self, open_connection_fut): @@ -109,6 +109,29 @@ def test_open_unix_connection_no_loop_ssl(self): self._basetest_open_connection_no_loop_ssl(conn_fut) + @unittest.skipIf(ssl is None, 'No ssl module') + def test_drain_on_closed_writer_ssl(self): + + async def inner(httpd): + reader, writer = await asyncio.open_connection( + *httpd.address, + ssl=test_utils.dummy_ssl_context()) + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + writer.write(b'GET / HTTP/1.0\r\n\r\n') + data = await reader.read() + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + + writer.close() + with self.assertRaises(ConnectionResetError): + await writer.drain() + + self.assertEqual(messages, []) + + with test_utils.run_test_server(use_ssl=True) as httpd: + self.loop.run_until_complete(inner(httpd)) + def _basetest_open_connection_error(self, open_connection_fut): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) @@ -135,20 +158,23 @@ def test_open_unix_connection_error(self): self._basetest_open_connection_error(conn_fut) def test_feed_empty_data(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'') self.assertEqual(b'', stream._buffer) def test_feed_nonempty_data(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) self.assertEqual(self.DATA, stream._buffer) def test_read_zero(self): # Read zero bytes. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.read(0)) @@ -157,7 +183,8 @@ def test_read_zero(self): def test_read(self): # Read bytes. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) read_task = asyncio.Task(stream.read(30), loop=self.loop) def cb(): @@ -170,7 +197,8 @@ def cb(): def test_read_line_breaks(self): # Read bytes without line breaks. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line1') stream.feed_data(b'line2') @@ -181,7 +209,8 @@ def test_read_line_breaks(self): def test_read_eof(self): # Read bytes, stop at eof. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) read_task = asyncio.Task(stream.read(1024), loop=self.loop) def cb(): @@ -194,7 +223,8 @@ def cb(): def test_read_until_eof(self): # Read all bytes until eof. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) read_task = asyncio.Task(stream.read(-1), loop=self.loop) def cb(): @@ -209,7 +239,8 @@ def cb(): self.assertEqual(b'', stream._buffer) def test_read_exception(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.read(2)) @@ -221,13 +252,16 @@ def test_read_exception(self): def test_invalid_limit(self): with self.assertRaisesRegex(ValueError, 'imit'): - asyncio.StreamReader(limit=0, loop=self.loop) + asyncio.StreamReader(limit=0, loop=self.loop, + _asyncio_internal=True) with self.assertRaisesRegex(ValueError, 'imit'): - asyncio.StreamReader(limit=-1, loop=self.loop) + asyncio.StreamReader(limit=-1, loop=self.loop, + _asyncio_internal=True) def test_read_limit(self): - stream = asyncio.StreamReader(limit=3, loop=self.loop) + stream = asyncio.StreamReader(limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'chunk') data = self.loop.run_until_complete(stream.read(5)) self.assertEqual(b'chunk', data) @@ -236,7 +270,8 @@ def test_read_limit(self): def test_readline(self): # Read one line. 'readline' will need to wait for the data # to come from 'cb' - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'chunk1 ') read_task = asyncio.Task(stream.readline(), loop=self.loop) @@ -254,7 +289,8 @@ def test_readline_limit_with_existing_data(self): # Read one line. The data is in StreamReader's buffer # before the event loop is run. - stream = asyncio.StreamReader(limit=3, loop=self.loop) + stream = asyncio.StreamReader(limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'li') stream.feed_data(b'ne1\nline2\n') @@ -263,7 +299,8 @@ def test_readline_limit_with_existing_data(self): # The buffer should contain the remaining data after exception self.assertEqual(b'line2\n', stream._buffer) - stream = asyncio.StreamReader(limit=3, loop=self.loop) + stream = asyncio.StreamReader(limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'li') stream.feed_data(b'ne1') stream.feed_data(b'li') @@ -278,7 +315,8 @@ def test_readline_limit_with_existing_data(self): self.assertEqual(b'', stream._buffer) def test_at_eof(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) self.assertFalse(stream.at_eof()) stream.feed_data(b'some data\n') @@ -296,7 +334,8 @@ def test_readline_limit(self): # Read one line. StreamReaders are fed with data after # their 'readline' methods are called. - stream = asyncio.StreamReader(limit=7, loop=self.loop) + stream = asyncio.StreamReader(limit=7, loop=self.loop, + _asyncio_internal=True) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2') @@ -310,7 +349,8 @@ def cb(): # a ValueError it should be empty. self.assertEqual(b'', stream._buffer) - stream = asyncio.StreamReader(limit=7, loop=self.loop) + stream = asyncio.StreamReader(limit=7, loop=self.loop, + _asyncio_internal=True) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2\n') @@ -323,7 +363,8 @@ def cb(): self.assertEqual(b'chunk3\n', stream._buffer) # check strictness of the limit - stream = asyncio.StreamReader(limit=7, loop=self.loop) + stream = asyncio.StreamReader(limit=7, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'1234567\n') line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'1234567\n', line) @@ -342,7 +383,8 @@ def cb(): def test_readline_nolimit_nowait(self): # All needed data for the first 'readline' call will be # in the buffer. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA[:6]) stream.feed_data(self.DATA[6:]) @@ -352,7 +394,8 @@ def test_readline_nolimit_nowait(self): self.assertEqual(b'line2\nline3\n', stream._buffer) def test_readline_eof(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'some data') stream.feed_eof() @@ -360,14 +403,16 @@ def test_readline_eof(self): self.assertEqual(b'some data', line) def test_readline_empty_eof(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_eof() line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'', line) def test_readline_read_byte_count(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) self.loop.run_until_complete(stream.readline()) @@ -378,7 +423,8 @@ def test_readline_read_byte_count(self): self.assertEqual(b'ine3\n', stream._buffer) def test_readline_exception(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readline()) @@ -390,12 +436,14 @@ def test_readline_exception(self): self.assertEqual(b'', stream._buffer) def test_readuntil_separator(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) with self.assertRaisesRegex(ValueError, 'Separator should be'): self.loop.run_until_complete(stream.readuntil(separator=b'')) def test_readuntil_multi_chunks(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'lineAAA') data = self.loop.run_until_complete(stream.readuntil(separator=b'AAA')) @@ -413,7 +461,8 @@ def test_readuntil_multi_chunks(self): self.assertEqual(b'xxx', stream._buffer) def test_readuntil_multi_chunks_1(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'QWEaa') stream.feed_data(b'XYaa') @@ -448,7 +497,8 @@ def test_readuntil_multi_chunks_1(self): self.assertEqual(b'', stream._buffer) def test_readuntil_eof(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'some dataAA') stream.feed_eof() @@ -459,7 +509,8 @@ def test_readuntil_eof(self): self.assertEqual(b'', stream._buffer) def test_readuntil_limit_found_sep(self): - stream = asyncio.StreamReader(loop=self.loop, limit=3) + stream = asyncio.StreamReader(loop=self.loop, limit=3, + _asyncio_internal=True) stream.feed_data(b'some dataAA') with self.assertRaisesRegex(asyncio.LimitOverrunError, @@ -477,7 +528,8 @@ def test_readuntil_limit_found_sep(self): def test_readexactly_zero_or_less(self): # Read exact number of bytes (zero or less). - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.readexactly(0)) @@ -490,7 +542,8 @@ def test_readexactly_zero_or_less(self): def test_readexactly(self): # Read exact number of bytes. - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) n = 2 * len(self.DATA) read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) @@ -506,7 +559,8 @@ def cb(): self.assertEqual(self.DATA, stream._buffer) def test_readexactly_limit(self): - stream = asyncio.StreamReader(limit=3, loop=self.loop) + stream = asyncio.StreamReader(limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'chunk') data = self.loop.run_until_complete(stream.readexactly(5)) self.assertEqual(b'chunk', data) @@ -514,7 +568,8 @@ def test_readexactly_limit(self): def test_readexactly_eof(self): # Read exact number of bytes (eof). - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) n = 2 * len(self.DATA) read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) @@ -532,7 +587,8 @@ def cb(): self.assertEqual(b'', stream._buffer) def test_readexactly_exception(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readexactly(2)) @@ -543,7 +599,8 @@ def test_readexactly_exception(self): ValueError, self.loop.run_until_complete, stream.readexactly(2)) def test_exception(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) self.assertIsNone(stream.exception()) exc = ValueError() @@ -551,7 +608,8 @@ def test_exception(self): self.assertIs(stream.exception(), exc) def test_exception_waiter(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) @asyncio.coroutine def set_err(): @@ -565,7 +623,8 @@ def set_err(): self.assertRaises(ValueError, t1.result) def test_exception_cancel(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) t = asyncio.Task(stream.readline(), loop=self.loop) test_utils.run_briefly(self.loop) @@ -592,8 +651,7 @@ async def handle_client(self, client_reader, client_writer): await client_writer.wait_closed() def start(self): - sock = socket.socket() - sock.bind(('127.0.0.1', 0)) + sock = socket.create_server(('127.0.0.1', 0)) self.server = self.loop.run_until_complete( asyncio.start_server(self.handle_client, sock=sock, @@ -605,8 +663,7 @@ def handle_client_callback(self, client_reader, client_writer): client_writer)) def start_callback(self): - sock = socket.socket() - sock.bind(('127.0.0.1', 0)) + sock = socket.create_server(('127.0.0.1', 0)) addr = sock.getsockname() sock.close() self.server = self.loop.run_until_complete( @@ -744,8 +801,10 @@ def test_read_all_from_pipe_reader(self): args = [sys.executable, '-c', code, str(wfd)] pipe = open(rfd, 'rb', 0) - reader = asyncio.StreamReader(loop=self.loop, limit=1) - protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop) + reader = asyncio.StreamReader(loop=self.loop, limit=1, + _asyncio_internal=True) + protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop, + _asyncio_internal=True) transport, _ = self.loop.run_until_complete( self.loop.connect_read_pipe(lambda: protocol, pipe)) @@ -771,7 +830,7 @@ def test_streamreader_constructor(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor # retrieves the current loop if the loop parameter is not set - reader = asyncio.StreamReader() + reader = asyncio.StreamReader(_asyncio_internal=True) self.assertIs(reader._loop, self.loop) def test_streamreaderprotocol_constructor(self): @@ -781,7 +840,7 @@ def test_streamreaderprotocol_constructor(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor # retrieves the current loop if the loop parameter is not set reader = mock.Mock() - protocol = asyncio.StreamReaderProtocol(reader) + protocol = asyncio.StreamReaderProtocol(reader, _asyncio_internal=True) self.assertIs(protocol._loop, self.loop) def test_drain_raises(self): @@ -796,10 +855,7 @@ def test_drain_raises(self): def server(): # Runs in a separate thread. - sock = socket.socket() - with sock: - sock.bind(('localhost', 0)) - sock.listen(1) + with socket.create_server(('localhost', 0)) as sock: addr = sock.getsockname() q.put(addr) clt, _ = sock.accept() @@ -829,32 +885,38 @@ async def client(host, port): thread.join() def test___repr__(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) self.assertEqual("", repr(stream)) def test___repr__nondefault_limit(self): - stream = asyncio.StreamReader(loop=self.loop, limit=123) + stream = asyncio.StreamReader(loop=self.loop, limit=123, + _asyncio_internal=True) self.assertEqual("", repr(stream)) def test___repr__eof(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_eof() self.assertEqual("", repr(stream)) def test___repr__data(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'data') self.assertEqual("", repr(stream)) def test___repr__exception(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) exc = RuntimeError() stream.set_exception(exc) self.assertEqual("", repr(stream)) def test___repr__waiter(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream._waiter = asyncio.Future(loop=self.loop) self.assertRegex( repr(stream), @@ -865,7 +927,8 @@ def test___repr__waiter(self): self.assertEqual("", repr(stream)) def test___repr__transport(self): - stream = asyncio.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) stream._transport = mock.Mock() stream._transport.__repr__ = mock.Mock() stream._transport.__repr__.return_value = "" @@ -952,8 +1015,10 @@ def test_del_stream_before_connection_made(self): self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) with test_utils.run_test_server() as httpd: - rd = asyncio.StreamReader(loop=self.loop) - pr = asyncio.StreamReaderProtocol(rd, loop=self.loop) + rd = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) + pr = asyncio.StreamReaderProtocol(rd, loop=self.loop, + _asyncio_internal=True) del rd gc.collect() tr, _ = self.loop.run_until_complete( @@ -1010,6 +1075,25 @@ def test_eof_feed_when_closing_writer(self): self.assertEqual(messages, []) + def test_stream_reader_create_warning(self): + with self.assertWarns(DeprecationWarning): + asyncio.StreamReader(loop=self.loop) + + def test_stream_reader_protocol_create_warning(self): + reader = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) + with self.assertWarns(DeprecationWarning): + asyncio.StreamReaderProtocol(reader, loop=self.loop) + + def test_stream_writer_create_warning(self): + reader = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) + proto = asyncio.StreamReaderProtocol(reader, loop=self.loop, + _asyncio_internal=True) + with self.assertWarns(DeprecationWarning): + asyncio.StreamWriter('transport', proto, reader, self.loop) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index a5bdb8eca51..3908aabf5a1 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -510,6 +510,18 @@ async def execute(): self.loop.run_until_complete(execute()) + def test_subprocess_protocol_create_warning(self): + with self.assertWarns(DeprecationWarning): + subprocess.SubprocessStreamProtocol(limit=10, loop=self.loop) + + def test_process_create_warning(self): + proto = subprocess.SubprocessStreamProtocol(limit=10, loop=self.loop, + _asyncio_internal=True) + transp = mock.Mock() + + with self.assertWarns(DeprecationWarning): + subprocess.Process(transp, proto, loop=self.loop) + if sys.platform != 'win32': # Unix diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 1cdff528def..fa9783f2ff2 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -236,6 +236,15 @@ def test_ensure_future_neither(self): with self.assertRaises(TypeError): asyncio.ensure_future('ok') + def test_ensure_future_error_msg(self): + loop = asyncio.new_event_loop() + f = self.new_future(self.loop) + with self.assertRaisesRegex(ValueError, 'The future belongs to a ' + 'different loop than the one specified as ' + 'the loop argument'): + asyncio.ensure_future(f, loop=loop) + loop.close() + def test_get_stack(self): T = None @@ -1768,7 +1777,7 @@ def test_shield_exception(self): test_utils.run_briefly(self.loop) self.assertIs(outer.exception(), exc) - def test_shield_cancel(self): + def test_shield_cancel_inner(self): inner = self.new_future(self.loop) outer = asyncio.shield(inner) test_utils.run_briefly(self.loop) @@ -1776,6 +1785,15 @@ def test_shield_cancel(self): test_utils.run_briefly(self.loop) self.assertTrue(outer.cancelled()) + def test_shield_cancel_outer(self): + inner = self.new_future(self.loop) + outer = asyncio.shield(inner) + test_utils.run_briefly(self.loop) + outer.cancel() + test_utils.run_briefly(self.loop) + self.assertTrue(outer.cancelled()) + self.assertEqual(0, 0 if outer._callbacks is None else len(outer._callbacks)) + def test_shield_shortcut(self): fut = self.new_future(self.loop) fut.set_result(42) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 7c68b2c0fc2..31dab6a423e 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -480,11 +480,11 @@ def test_buffer_overflow(self): r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" r" at tail\+0: 0x78 \*\*\* OUCH\n" - r" at tail\+1: 0xfb\n" - r" at tail\+2: 0xfb\n" + r" at tail\+1: 0xfd\n" + r" at tail\+2: 0xfd\n" r" .*\n" - r" The block was made by call #[0-9]+ to debug malloc/realloc.\n" - r" Data at p: cb cb cb .*\n" + r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" + r" Data at p: cd cd cd .*\n" r"\n" r"Enable tracemalloc to get the memory block allocation traceback\n" r"\n" @@ -499,8 +499,8 @@ def test_api_misuse(self): r" 16 bytes originally requested\n" r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" - r" The block was made by call #[0-9]+ to debug malloc/realloc.\n" - r" Data at p: cb cb cb .*\n" + r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" + r" Data at p: cd cd cd .*\n" r"\n" r"Enable tracemalloc to get the memory block allocation traceback\n" r"\n" @@ -526,6 +526,29 @@ def test_pyobject_malloc_without_gil(self): code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' self.check_malloc_without_gil(code) + def check_pyobject_is_freed(self, func): + code = textwrap.dedent(''' + import gc, os, sys, _testcapi + # Disable the GC to avoid crash on GC collection + gc.disable() + obj = _testcapi.{func}() + error = (_testcapi.pyobject_is_freed(obj) == False) + # Exit immediately to avoid a crash while deallocating + # the invalid object + os._exit(int(error)) + ''') + code = code.format(func=func) + assert_python_ok('-c', code, PYTHONMALLOC=self.PYTHONMALLOC) + + def test_pyobject_is_freed_uninitialized(self): + self.check_pyobject_is_freed('pyobject_uninitialized') + + def test_pyobject_is_freed_forbidden_bytes(self): + self.check_pyobject_is_freed('pyobject_forbidden_bytes') + + def test_pyobject_is_freed_free(self): + self.check_pyobject_is_freed('pyobject_freed') + class PyMemMallocDebugTests(PyMemDebugTests): PYTHONMALLOC = 'malloc_debug' diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 21511b896ca..f7925eb795c 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -369,6 +369,8 @@ def test_closed_stdout(self): # Issue #7111: Python should work without standard streams @unittest.skipIf(os.name != 'posix', "test needs POSIX semantics") + @unittest.skipIf(sys.platform == "vxworks", + "test needs preexec support in subprocess.Popen") def _test_no_stdio(self, streams): code = """if 1: import os, sys diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 85d2a4be069..d138ca027c6 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -409,6 +409,23 @@ def test_issue8202_dash_m_file_ignored(self): script_name, script_name, script_dir, '', importlib.machinery.SourceFileLoader) + def test_issue20884(self): + # On Windows, script with encoding cookie and LF line ending + # will be failed. + with support.temp_dir() as script_dir: + script_name = os.path.join(script_dir, "issue20884.py") + with open(script_name, "w", newline='\n') as f: + f.write("#coding: iso-8859-1\n") + f.write('"""\n') + for _ in range(30): + f.write('x'*80 + '\n') + f.write('"""\n') + + with support.change_cwd(path=script_dir): + rc, out, err = assert_python_ok(script_name) + self.assertEqual(b"", out) + self.assertEqual(b"", err) + @contextlib.contextmanager def setup_test_pkg(self, *args): with support.temp_dir() as script_dir, \ diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 55faf4c4279..e49121ef169 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -9,6 +9,7 @@ >>> dump(f.__code__) name: f argcount: 1 +posonlyargcount: 0 kwonlyargcount: 0 names: () varnames: ('x', 'g') @@ -21,6 +22,7 @@ >>> dump(f(4).__code__) name: g argcount: 1 +posonlyargcount: 0 kwonlyargcount: 0 names: () varnames: ('y',) @@ -40,6 +42,7 @@ >>> dump(h.__code__) name: h argcount: 2 +posonlyargcount: 0 kwonlyargcount: 0 names: () varnames: ('x', 'y', 'a', 'b', 'c') @@ -57,6 +60,7 @@ >>> dump(attrs.__code__) name: attrs argcount: 1 +posonlyargcount: 0 kwonlyargcount: 0 names: ('print', 'attr1', 'attr2', 'attr3') varnames: ('obj',) @@ -75,6 +79,7 @@ >>> dump(optimize_away.__code__) name: optimize_away argcount: 0 +posonlyargcount: 0 kwonlyargcount: 0 names: () varnames: () @@ -91,6 +96,7 @@ >>> dump(keywordonly_args.__code__) name: keywordonly_args argcount: 2 +posonlyargcount: 0 kwonlyargcount: 1 names: () varnames: ('a', 'b', 'k1') @@ -100,6 +106,23 @@ flags: 67 consts: ('None',) +>>> def posonly_args(a,b,/,c): +... return a,b,c +... + +>>> dump(posonly_args.__code__) +name: posonly_args +argcount: 1 +posonlyargcount: 2 +kwonlyargcount: 0 +names: () +varnames: ('a', 'b', 'c') +cellvars: () +freevars: () +nlocals: 3 +flags: 67 +consts: ('None',) + """ import inspect @@ -126,7 +149,8 @@ def consts(t): def dump(co): """Print out a text representation of a code object.""" - for attr in ["name", "argcount", "kwonlyargcount", "names", "varnames", + for attr in ["name", "argcount", "posonlyargcount", + "kwonlyargcount", "names", "varnames", "cellvars", "freevars", "nlocals", "flags"]: print("%s: %s" % (attr, getattr(co, "co_" + attr))) print("consts:", tuple(consts(co.co_consts))) @@ -157,7 +181,7 @@ def create_closure(__class__): def new_code(c): '''A new code object with a __class__ cell added to freevars''' return CodeType( - c.co_argcount, c.co_kwonlyargcount, c.co_nlocals, + c.co_argcount, c.co_posonlyargcount, c.co_kwonlyargcount, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code, c.co_consts, c.co_names, c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno, c.co_lnotab, c.co_freevars + ('__class__',), c.co_cellvars) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 331449397e3..027a84e275e 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -27,6 +27,26 @@ def check(input, expect): self.assertEqual(coder(input), (expect, len(input))) return check +# On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present +def is_code_page_present(cp): + from ctypes import POINTER, WINFUNCTYPE, windll, WinError, Structure, WinDLL + from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD + + MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term. + MAX_DEFAULTCHAR = 2 # single or double byte + MAX_PATH = 260 + class CPINFOEXW(ctypes.Structure): + _fields_ = [("MaxCharSize", UINT), + ("DefaultChar", BYTE*MAX_DEFAULTCHAR), + ("LeadByte", BYTE*MAX_LEADBYTES), + ("UnicodeDefaultChar", WCHAR), + ("CodePage", UINT), + ("CodePageName", WCHAR*MAX_PATH)] + + prototype = WINFUNCTYPE(BOOL, UINT, DWORD, POINTER(CPINFOEXW)) + GetCPInfoEx = prototype(("GetCPInfoExW", WinDLL("kernel32"))) + info = CPINFOEXW() + return GetCPInfoEx(cp, 0, info) class Queue(object): """ @@ -406,6 +426,15 @@ def test_lone_surrogates(self): self.assertEqual(test_sequence.decode(self.encoding, "backslashreplace"), before + backslashreplace + after) + def test_incremental_surrogatepass(self): + # Test incremental decoder for surrogatepass handler: + # see issue #24214 + data = '\uD901'.encode(self.encoding, 'surrogatepass') + for i in range(1, len(data)): + dec = codecs.getincrementaldecoder(self.encoding)('surrogatepass') + self.assertEqual(dec.decode(data[:i]), '') + self.assertEqual(dec.decode(data[i:], True), '\uD901') + class UTF32Test(ReadTest, unittest.TestCase): encoding = "utf-32" @@ -3069,9 +3098,19 @@ def test_multibyte_encoding(self): def test_code_page_decode_flags(self): # Issue #36312: For some code pages (e.g. UTF-7) flags for # MultiByteToWideChar() must be set to 0. + if support.verbose: + sys.stdout.write('\n') for cp in (50220, 50221, 50222, 50225, 50227, 50229, *range(57002, 57011+1), 65000): - self.assertEqual(codecs.code_page_decode(cp, b'abc'), ('abc', 3)) + # On small versions of Windows like Windows IoT + # not all codepages are present. + # A missing codepage causes an OSError exception + # so check for the codepage before decoding + if is_code_page_present(cp): + self.assertEqual(codecs.code_page_decode(cp, b'abc'), ('abc', 3), f'cp{cp}') + else: + if support.verbose: + print(f" skipping cp={cp}") self.assertEqual(codecs.code_page_decode(42, b'abc'), ('\uf061\uf062\uf063', 3)) diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 01125c79ba5..903afbd2a4f 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -49,6 +49,9 @@ def create_future(state=PENDING, exception=None, result=None): def mul(x, y): return x * y +def capture(*args, **kwargs): + return args, kwargs + def sleep_and_raise(t): time.sleep(t) raise Exception('this is an exception') @@ -658,6 +661,13 @@ def test_submit(self): def test_submit_keyword(self): future = self.executor.submit(mul, 2, y=8) self.assertEqual(16, future.result()) + future = self.executor.submit(capture, 1, self=2, fn=3) + self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) + with self.assertWarns(DeprecationWarning): + future = self.executor.submit(fn=capture, arg=1) + self.assertEqual(future.result(), ((), {'arg': 1})) + with self.assertRaises(TypeError): + self.executor.submit(arg=1) def test_map(self): self.assertEqual( diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index 755d9b95a67..188a29d9f9f 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -574,6 +574,7 @@ def test_callback(self): ((), dict(example=1)), ((1,), dict(example=1)), ((1,2), dict(example=1)), + ((1,2), dict(self=3, callback=4)), ] result = [] def _exit(*args, **kwds): @@ -596,6 +597,16 @@ def _exit(*args, **kwds): self.assertIsNone(wrapper[1].__doc__, _exit.__doc__) self.assertEqual(result, expected) + result = [] + with self.exit_stack() as stack: + with self.assertRaises(TypeError): + stack.callback(arg=1) + with self.assertRaises(TypeError): + self.exit_stack.callback(arg=2) + with self.assertWarns(DeprecationWarning): + stack.callback(callback=_exit, arg=3) + self.assertEqual(result, [((), {'arg': 3})]) + def test_push(self): exc_raised = ZeroDivisionError def _expect_exc(exc_type, exc, exc_tb): diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index 57716aea905..492b226a0d5 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -352,6 +352,16 @@ async def _exit(*args, **kwds): self.assertEqual(result, expected) + result = [] + async with AsyncExitStack() as stack: + with self.assertRaises(TypeError): + stack.push_async_callback(arg=1) + with self.assertRaises(TypeError): + self.exit_stack.push_async_callback(arg=2) + with self.assertWarns(DeprecationWarning): + stack.push_async_callback(callback=_exit, arg=3) + self.assertEqual(result, [((), {'arg': 3})]) + @_async_test async def test_async_push(self): exc_raised = ZeroDivisionError diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 9c83459f09e..867210688f5 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -697,7 +697,7 @@ class C: y: int self.assertNotEqual(Point(1, 3), C(1, 3)) - def test_not_tuple(self): + def test_not_other_dataclass(self): # Test that some of the problems with namedtuple don't happen # here. @dataclass @@ -1403,7 +1403,7 @@ class GroupDict: self.assertEqual(asdict(gd), {'id': 0, 'users': {'first': {'name': 'Alice', 'id': 1}, 'second': {'name': 'Bob', 'id': 2}}}) - def test_helper_asdict_builtin_containers(self): + def test_helper_asdict_builtin_object_containers(self): @dataclass class Child: d: object @@ -1458,7 +1458,7 @@ class C: } ) - # Make sure that the returned dicts are actuall OrderedDicts. + # Make sure that the returned dicts are actually OrderedDicts. self.assertIs(type(d), OrderedDict) self.assertIs(type(d['y'][1]), OrderedDict) @@ -1576,7 +1576,7 @@ class GroupDict: self.assertEqual(astuple(gt), (0, (('Alice', 1), ('Bob', 2)))) self.assertEqual(astuple(gd), (0, {'first': ('Alice', 1), 'second': ('Bob', 2)})) - def test_helper_astuple_builtin_containers(self): + def test_helper_astuple_builtin_object_containers(self): @dataclass class Child: d: object @@ -3242,18 +3242,6 @@ class E: "..D(f=TestReplace.test_recursive_repr_indirection_two" "..E(f=...)))") - def test_recursive_repr_two_attrs(self): - @dataclass - class C: - f: "C" - g: "C" - - c = C(None, None) - c.f = c - c.g = c - self.assertEqual(repr(c), "TestReplace.test_recursive_repr_two_attrs" - "..C(f=..., g=...)") - def test_recursive_repr_misc_attrs(self): @dataclass class C: diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index e39fea615db..e37a98417f5 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1597,12 +1597,31 @@ class SubSpam(spam.spamlist): pass self.assertEqual(x2, SubSpam) self.assertEqual(a2, a1) self.assertEqual(d2, d1) - with self.assertRaises(TypeError): + + with self.assertRaises(TypeError) as cm: spam_cm() - with self.assertRaises(TypeError): + self.assertEqual( + str(cm.exception), + "descriptor 'classmeth' of 'xxsubtype.spamlist' " + "object needs an argument") + + with self.assertRaises(TypeError) as cm: spam_cm(spam.spamlist()) - with self.assertRaises(TypeError): + self.assertEqual( + str(cm.exception), + "descriptor 'classmeth' requires a type " + "but received a 'xxsubtype.spamlist' instance") + + with self.assertRaises(TypeError) as cm: spam_cm(list) + expected_errmsg = ( + "descriptor 'classmeth' requires a subtype of 'xxsubtype.spamlist' " + "but received 'list'") + self.assertEqual(str(cm.exception), expected_errmsg) + + with self.assertRaises(TypeError) as cm: + spam_cm.__get__(None, list) + self.assertEqual(str(cm.exception), expected_errmsg) def test_staticmethods(self): # Testing static methods... @@ -1937,6 +1956,29 @@ class E(object): self.assertEqual(E().foo.__func__, C.foo) # i.e., unbound self.assertTrue(repr(C.foo.__get__(C(1))).startswith(" 2: 'tricky..f' Variable names: - 0: x - 1: y - 2: z - 3: c - 4: d - 5: e - 6: args - 7: kwds + 0: a + 1: b + 2: x + 3: y + 4: z + 5: c + 6: d + 7: e + 8: args + 9: kwds Cell variables: - 0: [edfxyz] - 1: [edfxyz] - 2: [edfxyz] - 3: [edfxyz] - 4: [edfxyz] - 5: [edfxyz]""" + 0: [abedfxyz] + 1: [abedfxyz] + 2: [abedfxyz] + 3: [abedfxyz] + 4: [abedfxyz] + 5: [abedfxyz]""" # NOTE: the order of the cell variables above depends on dictionary order! co_tricky_nested_f = tricky.__func__.__code__.co_consts[1] code_info_tricky_nested_f = """\ -Name: f Filename: (.*) Argument count: 1 +Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 1 -Stack size: 8 +Stack size: 10 Flags: OPTIMIZED, NEWLOCALS, NESTED Constants: 0: None @@ -683,17 +687,18 @@ def f(c=c): Variable names: 0: c Free variables: - 0: [edfxyz] - 1: [edfxyz] - 2: [edfxyz] - 3: [edfxyz] - 4: [edfxyz] - 5: [edfxyz]""" + 0: [abedfxyz] + 1: [abedfxyz] + 2: [abedfxyz] + 3: [abedfxyz] + 4: [abedfxyz] + 5: [abedfxyz]""" code_info_expr_str = """\ Name: Filename: Argument count: 0 +Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 0 Stack size: 2 @@ -707,6 +712,7 @@ def f(c=c): Name: Filename: Argument count: 0 +Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 0 Stack size: 2 @@ -721,6 +727,7 @@ def f(c=c): Name: Filename: Argument count: 0 +Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 0 Stack size: 2 @@ -742,6 +749,7 @@ async def async_def(): Name: async_def Filename: (.*) Argument count: 0 +Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 2 Stack size: 10 diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 374346e3cc8..fdf5793789d 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -53,7 +53,12 @@ def run_embedded_interpreter(self, *args, env=None): stderr=subprocess.PIPE, universal_newlines=True, env=env) - (out, err) = p.communicate() + try: + (out, err) = p.communicate() + except: + p.terminate() + p.wait() + raise if p.returncode != 0 and support.verbose: print(f"--- {cmd} failed ---") print(f"stdout:\n{out}") @@ -254,6 +259,11 @@ def test_initialize_pymain(self): self.assertEqual(out.rstrip(), "Py_Main() after Py_Initialize: sys.argv=['-c', 'arg2']") self.assertEqual(err, '') + def test_run_main(self): + out, err = self.run_embedded_interpreter("run_main") + self.assertEqual(out.rstrip(), "_Py_RunMain(): sys.argv=['-c', 'arg2']") + self.assertEqual(err, '') + class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): maxDiff = 4096 @@ -268,13 +278,26 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ) # Mark config which should be get by get_default_config() GET_DEFAULT_CONFIG = object() + DEFAULT_PRE_CONFIG = { + 'allocator': None, + 'coerce_c_locale': 0, + 'coerce_c_locale_warn': 0, + 'utf8_mode': 0, + } + COPY_PRE_CONFIG = [ + 'dev_mode', + 'isolated', + 'use_environment', + ] + DEFAULT_CORE_CONFIG = { - 'install_signal_handlers': 1, + 'isolated': 0, 'use_environment': 1, + 'dev_mode': 0, + + 'install_signal_handlers': 1, 'use_hash_seed': 0, 'hash_seed': 0, - 'allocator': None, - 'dev_mode': 0, 'faulthandler': 0, 'tracemalloc': 0, 'import_time': 0, @@ -286,14 +309,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'filesystem_encoding': GET_DEFAULT_CONFIG, 'filesystem_errors': GET_DEFAULT_CONFIG, - 'utf8_mode': 0, - 'coerce_c_locale': 0, - 'coerce_c_locale_warn': 0, - 'pycache_prefix': None, 'program_name': './_testembed', 'argv': [""], - 'program': None, + 'program': '', 'xoptions': [], 'warnoptions': [], @@ -306,7 +325,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'exec_prefix': GET_DEFAULT_CONFIG, 'base_exec_prefix': GET_DEFAULT_CONFIG, - 'isolated': 0, 'site_import': 1, 'bytes_warning': 0, 'inspect': 0, @@ -328,37 +346,26 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'run_filename': None, '_install_importlib': 1, - '_check_hash_pycs_mode': 'default', + 'check_hash_pycs_mode': 'default', '_frozen': 0, } if MS_WINDOWS: - DEFAULT_CORE_CONFIG.update({ + DEFAULT_PRE_CONFIG.update({ 'legacy_windows_fs_encoding': 0, + }) + DEFAULT_CORE_CONFIG.update({ 'legacy_windows_stdio': 0, }) - # main config - COPY_MAIN_CONFIG = ( - # Copy core config to main config for expected values - 'argv', - 'base_exec_prefix', - 'base_prefix', - 'exec_prefix', - 'executable', - 'install_signal_handlers', - 'prefix', - 'pycache_prefix', - 'warnoptions', - # xoptions is created from core_config in check_main_config(). - # 'module_search_paths' is copied to 'module_search_path'. - ) - # global config DEFAULT_GLOBAL_CONFIG = { 'Py_HasFileSystemDefaultEncoding': 0, 'Py_HashRandomizationFlag': 1, '_Py_HasFileSystemDefaultEncodeErrors': 0, } + COPY_GLOBAL_PRE_CONFIG = [ + ('Py_UTF8Mode', 'utf8_mode'), + ] COPY_GLOBAL_CONFIG = [ # Copy core config to global config for expected values # True means that the core config value is inverted (0 => 1 and 1 => 0) @@ -376,13 +383,14 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ('Py_NoUserSiteDirectory', 'user_site_directory', True), ('Py_OptimizeFlag', 'optimization_level'), ('Py_QuietFlag', 'quiet'), - ('Py_UTF8Mode', 'utf8_mode'), ('Py_UnbufferedStdioFlag', 'buffered_stdio', True), ('Py_VerboseFlag', 'verbose'), ] if MS_WINDOWS: - COPY_GLOBAL_CONFIG.extend(( + COPY_GLOBAL_PRE_CONFIG.extend(( ('Py_LegacyWindowsFSEncodingFlag', 'legacy_windows_fs_encoding'), + )) + COPY_GLOBAL_CONFIG.extend(( ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'), )) @@ -396,18 +404,6 @@ def main_xoptions(self, xoptions_list): xoptions[opt] = True return xoptions - def check_main_config(self, config): - core_config = config['core_config'] - main_config = config['main_config'] - - # main config - expected = {} - for key in self.COPY_MAIN_CONFIG: - expected[key] = core_config[key] - expected['module_search_path'] = core_config['module_search_paths'] - expected['xoptions'] = self.main_xoptions(core_config['xoptions']) - self.assertEqual(main_config, expected) - def get_expected_config(self, expected, env): expected = dict(self.DEFAULT_CORE_CONFIG, **expected) @@ -446,13 +442,21 @@ def get_expected_config(self, expected, env): raise Exception(f"failed to get the default config: " f"stdout={proc.stdout!r} stderr={proc.stderr!r}") stdout = proc.stdout.decode('utf-8') - config = json.loads(stdout) + try: + config = json.loads(stdout) + except json.JSONDecodeError: + self.fail(f"fail to decode stdout: {stdout!r}") for key, value in expected.items(): if value is self.GET_DEFAULT_CONFIG: expected[key] = config[key] return expected + def check_pre_config(self, config, expected): + pre_config = dict(config['pre_config']) + core_config = dict(config['core_config']) + self.assertEqual(pre_config, expected) + def check_core_config(self, config, expected): core_config = dict(config['core_config']) for key in self.UNTESTED_CORE_CONFIG: @@ -460,6 +464,7 @@ def check_core_config(self, config, expected): self.assertEqual(core_config, expected) def check_global_config(self, config): + pre_config = config['pre_config'] core_config = config['core_config'] expected = dict(self.DEFAULT_GLOBAL_CONFIG) @@ -470,10 +475,17 @@ def check_global_config(self, config): else: global_key, core_key = item expected[global_key] = core_config[core_key] + for item in self.COPY_GLOBAL_PRE_CONFIG: + if len(item) == 3: + global_key, core_key, opposite = item + expected[global_key] = 0 if pre_config[core_key] else 1 + else: + global_key, core_key = item + expected[global_key] = pre_config[core_key] self.assertEqual(config['global_config'], expected) - def check_config(self, testname, expected): + def check_config(self, testname, expected_config, expected_preconfig): env = dict(os.environ) # Remove PYTHON* environment variables to get deterministic environment for key in list(env): @@ -486,21 +498,33 @@ def check_config(self, testname, expected): out, err = self.run_embedded_interpreter(testname, env=env) # Ignore err - config = json.loads(out) + try: + config = json.loads(out) + except json.JSONDecodeError: + self.fail(f"fail to decode stdout: {out!r}") - expected = self.get_expected_config(expected, env) - self.check_core_config(config, expected) - self.check_main_config(config) + expected_preconfig = dict(self.DEFAULT_PRE_CONFIG, **expected_preconfig) + expected_config = self.get_expected_config(expected_config, env) + for key in self.COPY_PRE_CONFIG: + if key not in expected_preconfig: + expected_preconfig[key] = expected_config[key] + + self.check_pre_config(config, expected_preconfig) + self.check_core_config(config, expected_config) self.check_global_config(config) def test_init_default_config(self): - self.check_config("init_default_config", {}) + self.check_config("init_default_config", {}, {}) def test_init_global_config(self): + preconfig = { + 'utf8_mode': 1, + } config = { 'program_name': './globalvar', 'site_import': 0, 'bytes_warning': 1, + 'warnoptions': ['default::BytesWarning'], 'inspect': 1, 'interactive': 1, 'optimization_level': 2, @@ -509,29 +533,29 @@ def test_init_global_config(self): 'quiet': 1, 'buffered_stdio': 0, - 'utf8_mode': 1, 'stdio_encoding': 'utf-8', 'stdio_errors': 'surrogateescape', 'filesystem_encoding': 'utf-8', 'filesystem_errors': self.UTF8_MODE_ERRORS, 'user_site_directory': 0, - '_frozen': 1, } - self.check_config("init_global_config", config) + self.check_config("init_global_config", config, preconfig) def test_init_from_config(self): + preconfig = { + 'allocator': 'malloc', + 'utf8_mode': 1, + } config = { 'install_signal_handlers': 0, 'use_hash_seed': 1, 'hash_seed': 123, - 'allocator': 'malloc', 'tracemalloc': 2, 'import_time': 1, 'show_ref_count': 1, 'show_alloc_count': 1, 'malloc_stats': 1, - 'utf8_mode': 1, 'stdio_encoding': 'iso8859-1', 'stdio_errors': 'replace', 'filesystem_encoding': 'utf-8', @@ -539,10 +563,11 @@ def test_init_from_config(self): 'pycache_prefix': 'conf_pycache_prefix', 'program_name': './conf_program_name', - 'argv': ['-c', 'pass'], + 'argv': ['-c', 'arg2'], 'program': 'conf_program', 'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'], - 'warnoptions': ['default', 'error::ResourceWarning'], + 'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'], + 'run_command': 'pass\n', 'site_import': 0, 'bytes_warning': 1, @@ -556,21 +581,19 @@ def test_init_from_config(self): 'user_site_directory': 0, 'faulthandler': 1, - '_check_hash_pycs_mode': 'always', - '_frozen': 1, + 'check_hash_pycs_mode': 'always', } - self.check_config("init_from_config", config) + self.check_config("init_from_config", config, preconfig) + INIT_ENV_PRECONFIG = { + 'allocator': 'malloc', + } INIT_ENV_CONFIG = { 'use_hash_seed': 1, 'hash_seed': 42, - 'allocator': 'malloc', 'tracemalloc': 2, 'import_time': 1, 'malloc_stats': 1, - 'utf8_mode': 1, - 'filesystem_encoding': 'utf-8', - 'filesystem_errors': UTF8_MODE_ERRORS, 'inspect': 1, 'optimization_level': 2, 'pycache_prefix': 'env_pycache_prefix', @@ -584,35 +607,63 @@ def test_init_from_config(self): } def test_init_env(self): - self.check_config("init_env", self.INIT_ENV_CONFIG) + self.check_config("init_env", self.INIT_ENV_CONFIG, self.INIT_ENV_PRECONFIG) def test_init_env_dev_mode(self): + preconfig = dict(self.INIT_ENV_PRECONFIG, + allocator='debug') config = dict(self.INIT_ENV_CONFIG, - allocator='debug', - dev_mode=1) - self.check_config("init_env_dev_mode", config) + dev_mode=1, + warnoptions=['default']) + self.check_config("init_env_dev_mode", config, preconfig) - def test_init_env_dev_mode(self): + def test_init_env_dev_mode_alloc(self): + preconfig = dict(self.INIT_ENV_PRECONFIG, + allocator='malloc') config = dict(self.INIT_ENV_CONFIG, - allocator='malloc', - dev_mode=1) - self.check_config("init_env_dev_mode_alloc", config) + dev_mode=1, + warnoptions=['default']) + self.check_config("init_env_dev_mode_alloc", config, preconfig) def test_init_dev_mode(self): - config = { - 'dev_mode': 1, - 'faulthandler': 1, + preconfig = { 'allocator': 'debug', } - self.check_config("init_dev_mode", config) + config = { + 'faulthandler': 1, + 'dev_mode': 1, + 'warnoptions': ['default'], + } + self.check_config("init_dev_mode", config, preconfig) def test_init_isolated(self): + preconfig = {} config = { 'isolated': 1, 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("init_isolated", config) + self.check_config("init_isolated", config, preconfig) + + def test_preinit_isolated1(self): + # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set + preconfig = {} + config = { + 'isolated': 1, + 'use_environment': 0, + 'user_site_directory': 0, + } + self.check_config("preinit_isolated1", config, preconfig) + + def test_preinit_isolated2(self): + # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 + preconfig = {} + config = { + 'isolated': 1, + 'use_environment': 0, + 'user_site_directory': 0, + } + self.check_config("preinit_isolated2", config, preconfig) if __name__ == "__main__": diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py index 53ce1d55ff9..8ac0f31d805 100644 --- a/Lib/test/test_epoll.py +++ b/Lib/test/test_epoll.py @@ -41,9 +41,7 @@ class TestEPoll(unittest.TestCase): def setUp(self): - self.serverSocket = socket.socket() - self.serverSocket.bind(('127.0.0.1', 0)) - self.serverSocket.listen() + self.serverSocket = socket.create_server(('127.0.0.1', 0)) self.connections = [self.serverSocket] def tearDown(self): diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index acd5c7cc586..5d4abe388f7 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -34,7 +34,7 @@ def get_lockdata(): fcntl.F_WRLCK, 0) elif sys.platform.startswith('gnukfreebsd'): lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0) - elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']: + elif sys.platform in ['hp-uxB', 'unixware7']: lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) else: lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index 3857401ca60..8b7577b0205 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -329,6 +329,16 @@ def test_readline_binary_mode(self): self.assertEqual(fi.readline(), b'') self.assertEqual(fi.readline(), b'') + def test_inplace_binary_write_mode(self): + temp_file = self.writeTmp(b'Initial text.', mode='wb') + with FileInput(temp_file, mode='rb', inplace=True) as fobj: + line = fobj.readline() + self.assertEqual(line, b'Initial text.') + # print() cannot be used with files opened in binary mode. + sys.stdout.write(b'New line.') + with open(temp_file, 'rb') as f: + self.assertEqual(f.read(), b'New line.') + def test_context_manager(self): t1 = self.writeTmp("A\nB\nC") t2 = self.writeTmp("D\nE\nF") diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index da8ba32917b..b0e46411a2e 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -132,9 +132,7 @@ def cmd_port(self, arg): self.push('200 active data connection established') def cmd_pasv(self, arg): - with socket.socket() as sock: - sock.bind((self.socket.getsockname()[0], 0)) - sock.listen() + with socket.create_server((self.socket.getsockname()[0], 0)) as sock: sock.settimeout(TIMEOUT) ip, port = sock.getsockname()[:2] ip = ip.replace('.', ','); p1 = port / 256; p2 = port % 256 @@ -150,9 +148,8 @@ def cmd_eprt(self, arg): self.push('200 active data connection established') def cmd_epsv(self, arg): - with socket.socket(socket.AF_INET6) as sock: - sock.bind((self.socket.getsockname()[0], 0)) - sock.listen() + with socket.create_server((self.socket.getsockname()[0], 0), + family=socket.AF_INET6) as sock: sock.settimeout(TIMEOUT) port = sock.getsockname()[1] self.push('229 entering extended passive mode (|||%d|)' %port) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 63a9ade5480..85c65d18326 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -464,6 +464,7 @@ class A(object): positional = functools.partialmethod(capture, 1) keywords = functools.partialmethod(capture, a=2) both = functools.partialmethod(capture, 3, b=4) + spec_keywords = functools.partialmethod(capture, self=1, func=2) nested = functools.partialmethod(positional, 5) @@ -497,6 +498,8 @@ def test_arg_combinations(self): self.assertEqual(self.A.both(self.a, 5, c=6), ((self.a, 3, 5), {'b': 4, 'c': 6})) + self.assertEqual(self.a.spec_keywords(), ((self.a,), {'self': 1, 'func': 2})) + def test_nested(self): self.assertEqual(self.a.nested(), ((self.a, 1, 5), {})) self.assertEqual(self.a.nested(6), ((self.a, 1, 5, 6), {})) @@ -550,6 +553,14 @@ def test_invalid_args(self): with self.assertRaises(TypeError): class B(object): method = functools.partialmethod(None, 1) + with self.assertRaises(TypeError): + class B: + method = functools.partialmethod() + with self.assertWarns(DeprecationWarning): + class B: + method = functools.partialmethod(func=capture, a=1) + b = B() + self.assertEqual(b.method(2, x=3), ((b, 2), {'a': 1, 'x': 3})) def test_repr(self): self.assertEqual(repr(vars(self.A)['both']), @@ -570,6 +581,13 @@ def add(self, x, y): for func in [self.A.static, self.A.cls, self.A.over_partial, self.A.nested, self.A.both]: self.assertFalse(getattr(func, '__isabstractmethod__', False)) + def test_positional_only(self): + def f(a, b, /): + return a + b + + p = functools.partial(f, 1) + self.assertEqual(p(2), f(1, 2)) + class TestUpdateWrapper(unittest.TestCase): @@ -1260,6 +1278,20 @@ def f(x): self.assertEqual(f(20), '.20.') self.assertEqual(f.cache_info().currsize, 10) + def test_lru_bug_36650(self): + # C version of lru_cache was treating a call with an empty **kwargs + # dictionary as being distinct from a call with no keywords at all. + # This did not result in an incorrect answer, but it did trigger + # an unexpected cache miss. + + @self.module.lru_cache() + def f(x): + pass + + f(0) + f(0, **{}) + self.assertEqual(f.cache_info().hits, 1) + def test_lru_hash_only_once(self): # To protect against weird reentrancy bugs and to improve # efficiency when faced with slow __hash__ methods, the diff --git a/Lib/test/test_genericclass.py b/Lib/test/test_genericclass.py index 37a87bc6815..27420d4f2ba 100644 --- a/Lib/test/test_genericclass.py +++ b/Lib/test/test_genericclass.py @@ -158,7 +158,7 @@ def __class_getitem__(*args, **kwargs): self.assertEqual(getitem_args[0], (C, (int, str))) self.assertEqual(getitem_args[1], {}) - def test_class_getitem(self): + def test_class_getitem_format(self): class C: def __class_getitem__(cls, item): return f'C[{item.__name__}]' diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 2c8f854c643..3583b47336f 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -746,7 +746,7 @@ def test_compress_stdin_outfile(self): self.assertEqual(out[:2], b"\x1f\x8b") @create_and_remove_directory(TEMPDIR) - def test_compress_infile_outfile(self): + def test_compress_infile_outfile_default(self): local_testgzip = os.path.join(TEMPDIR, 'testgzip') gzipname = local_testgzip + '.gz' self.assertFalse(os.path.exists(gzipname)) diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index f816eac83b6..968cbd86a1e 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -4,6 +4,7 @@ import itertools import os import array +import re import socket import threading @@ -348,7 +349,8 @@ def test_headers_debuglevel(self): body = ( b'HTTP/1.1 200 OK\r\n' b'First: val\r\n' - b'Second: val\r\n' + b'Second: val1\r\n' + b'Second: val2\r\n' ) sock = FakeSocket(body) resp = client.HTTPResponse(sock, debuglevel=1) @@ -357,7 +359,8 @@ def test_headers_debuglevel(self): lines = output.getvalue().splitlines() self.assertEqual(lines[0], "reply: 'HTTP/1.1 200 OK\\r\\n'") self.assertEqual(lines[1], "header: First: val") - self.assertEqual(lines[2], "header: Second: val") + self.assertEqual(lines[2], "header: Second: val1") + self.assertEqual(lines[3], "header: Second: val2") class TransferEncodingTest(TestCase): @@ -1116,11 +1119,8 @@ def test_read1_bound_content_length(self): def test_response_fileno(self): # Make sure fd returned by fileno is valid. - serv = socket.socket( - socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) + serv = socket.create_server((HOST, 0)) self.addCleanup(serv.close) - serv.bind((HOST, 0)) - serv.listen() result = None def run_server(): @@ -1620,14 +1620,30 @@ def test_networked_good_cert(self): # We feed the server's cert as a validating cert import ssl support.requires('network') - with support.transient_internet('self-signed.pythontest.net'): + selfsigned_pythontestdotnet = 'self-signed.pythontest.net' + with support.transient_internet(selfsigned_pythontestdotnet): context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED) self.assertEqual(context.check_hostname, True) context.load_verify_locations(CERT_selfsigned_pythontestdotnet) - h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context) - h.request('GET', '/') - resp = h.getresponse() + try: + h = client.HTTPSConnection(selfsigned_pythontestdotnet, 443, + context=context) + h.request('GET', '/') + resp = h.getresponse() + except ssl.SSLError as ssl_err: + ssl_err_str = str(ssl_err) + # In the error message of [SSL: CERTIFICATE_VERIFY_FAILED] on + # modern Linux distros (Debian Buster, etc) default OpenSSL + # configurations it'll fail saying "key too weak" until we + # address https://bugs.python.org/issue36816 to use a proper + # key size on self-signed.pythontest.net. + if re.search(r'(?i)key.too.weak', ssl_err_str): + raise unittest.SkipTest( + f'Got {ssl_err_str} trying to connect ' + f'to {selfsigned_pythontestdotnet}. ' + 'See https://bugs.python.org/issue36816.') + raise server_string = resp.getheader('server') resp.close() h.close() diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index a060143e1f6..9305e47ee99 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -81,14 +81,8 @@ def test_imap4_host_default_value(self): except socket.error: pass - expected_errnos = [ - # This is the exception that should be raised. - errno.ECONNREFUSED, - ] - if hasattr(errno, 'EADDRNOTAVAIL'): - # socket.create_connection() fails randomly with - # EADDRNOTAVAIL on Travis CI. - expected_errnos.append(errno.EADDRNOTAVAIL) + # This is the exception that should be raised. + expected_errnos = support.get_socket_conn_refused_errs() with self.assertRaises(OSError) as cm: imaplib.IMAP4() self.assertIn(cm.exception.errno, expected_errnos) @@ -476,8 +470,8 @@ def test_logout(self): self.assertEqual(typ, 'OK') self.assertEqual(data[0], b'LOGIN completed') typ, data = client.logout() - self.assertEqual(typ, 'BYE') - self.assertEqual(data[0], b'IMAP4ref1 Server logging out') + self.assertEqual(typ, 'BYE', (typ, data)) + self.assertEqual(data[0], b'IMAP4ref1 Server logging out', (typ, data)) self.assertEqual(client.state, 'LOGOUT') def test_lsub(self): @@ -943,7 +937,7 @@ def test_logout(self): with transient_internet(self.host): rs = self.server.logout() self.server = None - self.assertEqual(rs[0], 'BYE') + self.assertEqual(rs[0], 'BYE', rs) @unittest.skipUnless(ssl, "SSL not available") @@ -1001,7 +995,7 @@ def test_logout(self): with transient_internet(self.host): _server = self.imap_class(self.host, self.port) rs = _server.logout() - self.assertEqual(rs[0], 'BYE') + self.assertEqual(rs[0], 'BYE', rs) def test_ssl_context_certfile_exclusive(self): with transient_internet(self.host): diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 7306e0f7f72..109b01413b2 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -8,6 +8,8 @@ import platform import py_compile import random +import shutil +import subprocess import stat import sys import threading @@ -17,6 +19,7 @@ import textwrap import errno import contextlib +import glob import test.support from test.support import ( @@ -460,6 +463,51 @@ def run(): finally: del sys.path[0] + @unittest.skipUnless(sys.platform == "win32", "Windows-specific") + def test_dll_dependency_import(self): + from _winapi import GetModuleFileName + dllname = GetModuleFileName(sys.dllhandle) + pydname = importlib.util.find_spec("_sqlite3").origin + depname = os.path.join( + os.path.dirname(pydname), + "sqlite3{}.dll".format("_d" if "_d" in pydname else "")) + + with test.support.temp_dir() as tmp: + tmp2 = os.path.join(tmp, "DLLs") + os.mkdir(tmp2) + + pyexe = os.path.join(tmp, os.path.basename(sys.executable)) + shutil.copy(sys.executable, pyexe) + shutil.copy(dllname, tmp) + for f in glob.glob(os.path.join(sys.prefix, "vcruntime*.dll")): + shutil.copy(f, tmp) + + shutil.copy(pydname, tmp2) + + env = None + env = {k.upper(): os.environ[k] for k in os.environ} + env["PYTHONPATH"] = tmp2 + ";" + os.path.dirname(os.__file__) + + # Test 1: import with added DLL directory + subprocess.check_call([ + pyexe, "-Sc", ";".join([ + "import os", + "p = os.add_dll_directory({!r})".format( + os.path.dirname(depname)), + "import _sqlite3", + "p.close" + ])], + stderr=subprocess.STDOUT, + env=env, + cwd=os.path.dirname(pyexe)) + + # Test 2: import with DLL adjacent to PYD + shutil.copy(depname, tmp2) + subprocess.check_call([pyexe, "-Sc", "import _sqlite3"], + stderr=subprocess.STDOUT, + env=env, + cwd=os.path.dirname(pyexe)) + @skip_if_dont_write_bytecode class FilePermissionTests(unittest.TestCase): @@ -626,7 +674,8 @@ def test_foreign_code(self): foreign_code = importlib.import_module.__code__ pos = constants.index(1) constants[pos] = foreign_code - code = type(code)(code.co_argcount, code.co_kwonlyargcount, + code = type(code)(code.co_argcount, code.co_posonlyargcount, + code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize, code.co_flags, code.co_code, tuple(constants), code.co_names, code.co_varnames, code.co_filename, diff --git a/Lib/test/test_importlib/test_lazy.py b/Lib/test/test_importlib/test_lazy.py index ffd8dc6cb04..28608e95d06 100644 --- a/Lib/test/test_importlib/test_lazy.py +++ b/Lib/test/test_importlib/test_lazy.py @@ -56,7 +56,7 @@ class LazyLoaderTests(unittest.TestCase): def test_init(self): with self.assertRaises(TypeError): - # Classes that dono't define exec_module() trigger TypeError. + # Classes that don't define exec_module() trigger TypeError. util.LazyLoader(object) def new_module(self, source_code=None): diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index d134e3c3b04..db0899aff6b 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -682,7 +682,7 @@ def test_sep_altsep_and_sep_cache_from_source(self): @unittest.skipIf(sys.implementation.cache_tag is None, 'requires sys.implementation.cache_tag not be None') - def test_source_from_cache_path_like_arg(self): + def test_cache_from_source_path_like_arg(self): path = pathlib.PurePath('foo', 'bar', 'baz', 'qux.py') expect = os.path.join('foo', 'bar', 'baz', '__pycache__', 'qux.{}.pyc'.format(self.tag)) @@ -862,7 +862,7 @@ def test_magic_number(self): in advance. Such exceptional releases will then require an adjustment to this test case. """ - EXPECTED_MAGIC_NUMBER = 3400 + EXPECTED_MAGIC_NUMBER = 3410 actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') msg = ( diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index b9072e0137e..c54cdb23c24 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -146,6 +146,7 @@ def test_excluding_predicates(self): self.istest(inspect.isfunction, 'mod.spam') self.istest(inspect.isfunction, 'mod.StupidGit.abuse') self.istest(inspect.ismethod, 'git.argue') + self.istest(inspect.ismethod, 'mod.custom_method') self.istest(inspect.ismodule, 'mod') self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory') self.istest(inspect.isgenerator, '(x for x in range(2))') @@ -375,6 +376,11 @@ def assertSourceEqual(self, obj, top, bottom): self.assertEqual(inspect.getsource(obj), self.sourcerange(top, bottom)) +class SlotUser: + 'Docstrings for __slots__' + __slots__ = {'power': 'measured in kilowatts', + 'distance': 'measured in kilometers'} + class TestRetrievingSourceCode(GetSourceBase): fodderModule = mod @@ -429,6 +435,10 @@ def test_getdoc(self): 'A longer,\n\nindented\n\ndocstring.') self.assertEqual(inspect.getdoc(git.abuse), 'Another\n\ndocstring\n\ncontaining\n\ntabs') + self.assertEqual(inspect.getdoc(SlotUser.power), + 'measured in kilowatts') + self.assertEqual(inspect.getdoc(SlotUser.distance), + 'measured in kilometers') @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -753,10 +763,12 @@ def assertArgSpecEquals(self, routine, args_e, varargs_e=None, def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None, varkw_e=None, defaults_e=None, - kwonlyargs_e=[], kwonlydefaults_e=None, + posonlyargs_e=[], kwonlyargs_e=[], + kwonlydefaults_e=None, ann_e={}, formatted=None): - args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \ - inspect.getfullargspec(routine) + with self.assertWarns(DeprecationWarning): + args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \ + inspect.getfullargspec(routine) self.assertEqual(args, args_e) self.assertEqual(varargs, varargs_e) self.assertEqual(varkw, varkw_e) @@ -800,6 +812,23 @@ def test_getfullargspec(self): kwonlyargs_e=['arg'], formatted='(*, arg)') + self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'], + kwonlyargs_e=['e', 'f'], + formatted='(a, b, c, d, *, e, f)') + + self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs, + ['a', 'b', 'c', 'd'], + varargs_e='args', + varkw_e='kwargs', + kwonlyargs_e=['e', 'f'], + formatted='(a, b, c, d, *args, e, f, **kwargs)') + + self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'], + defaults_e=(1,2,3), + kwonlyargs_e=['e', 'f'], + kwonlydefaults_e={'e': 4, 'f': 5}, + formatted='(a, b=1, c=2, d=3, *, e=4, f=5)') + def test_argspec_api_ignores_wrapped(self): # Issue 20684: low level introspection API must ignore __wrapped__ @functools.wraps(mod.spam) @@ -846,25 +875,27 @@ def test(): spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY) test.__signature__ = inspect.Signature(parameters=(spam_param,)) - self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)') + self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)') def test_getfullargspec_signature_annos(self): def test(a:'spam') -> 'ham': pass - spec = inspect.getfullargspec(test) + with self.assertWarns(DeprecationWarning): + spec = inspect.getfullargspec(test) self.assertEqual(test.__annotations__, spec.annotations) def test(): pass - spec = inspect.getfullargspec(test) + with self.assertWarns(DeprecationWarning): + spec = inspect.getfullargspec(test) self.assertEqual(test.__annotations__, spec.annotations) @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") def test_getfullargspec_builtin_methods(self): - self.assertFullArgSpecEquals(_pickle.Pickler.dump, - args_e=['self', 'obj'], formatted='(self, obj)') + self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'], + formatted='(self, obj)') - self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, - args_e=['self', 'obj'], formatted='(self, obj)') + self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'], + formatted='(self, obj)') self.assertFullArgSpecEquals( os.stat, @@ -879,7 +910,8 @@ def test_getfullargspec_builtin_methods(self): def test_getfullargspec_builtin_func(self): import _testcapi builtin = _testcapi.docstring_with_signature_with_defaults - spec = inspect.getfullargspec(builtin) + with self.assertWarns(DeprecationWarning): + spec = inspect.getfullargspec(builtin) self.assertEqual(spec.defaults[0], 'avocado') @cpython_only @@ -888,17 +920,20 @@ def test_getfullargspec_builtin_func(self): def test_getfullargspec_builtin_func_no_signature(self): import _testcapi builtin = _testcapi.docstring_no_signature - with self.assertRaises(TypeError): - inspect.getfullargspec(builtin) + with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): + inspect.getfullargspec(builtin) def test_getfullargspec_definition_order_preserved_on_kwonly(self): for fn in signatures_with_lexicographic_keyword_only_parameters(): - signature = inspect.getfullargspec(fn) + with self.assertWarns(DeprecationWarning): + signature = inspect.getfullargspec(fn) l = list(signature.kwonlyargs) sorted_l = sorted(l) self.assertTrue(l) self.assertEqual(l, sorted_l) - signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn) + with self.assertWarns(DeprecationWarning): + signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn) l = list(signature.kwonlyargs) self.assertEqual(l, unsorted_keyword_only_parameters) @@ -1355,8 +1390,9 @@ class TestGetcallargsFunctions(unittest.TestCase): def assertEqualCallArgs(self, func, call_params_string, locs=None): locs = dict(locs or {}, func=func) r1 = eval('func(%s)' % call_params_string, None, locs) - r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None, - locs) + with self.assertWarns(DeprecationWarning): + r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None, + locs) self.assertEqual(r1, r2) def assertEqualException(self, func, call_param_string, locs=None): @@ -1368,8 +1404,9 @@ def assertEqualException(self, func, call_param_string, locs=None): else: self.fail('Exception not raised') try: - eval('inspect.getcallargs(func, %s)' % call_param_string, None, - locs) + with self.assertWarns(DeprecationWarning): + eval('inspect.getcallargs(func, %s)' % call_param_string, None, + locs) except Exception as e: ex2 = e else: @@ -1527,14 +1564,16 @@ def test_errors(self): def f5(*, a): pass with self.assertRaisesRegex(TypeError, 'missing 1 required keyword-only'): - inspect.getcallargs(f5) + with self.assertWarns(DeprecationWarning): + inspect.getcallargs(f5) # issue20817: def f6(a, b, c): pass with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"): - inspect.getcallargs(f6) + with self.assertWarns(DeprecationWarning): + inspect.getcallargs(f6) # bpo-33197 with self.assertRaisesRegex(ValueError, @@ -3743,6 +3782,17 @@ def test_builtins_have_signatures(self): with self.subTest(builtin=name): self.assertIsNone(obj.__text_signature__) + def test_python_function_override_signature(self): + def func(*args, **kwargs): + pass + func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)' + sig = inspect.signature(func) + self.assertIsNotNone(sig) + self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)') + func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)' + sig = inspect.signature(func) + self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)') + class NTimesUnwrappable: def __init__(self, n): diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index d245c5d846a..5406a2891bb 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -67,6 +67,11 @@ class EmptyStruct(ctypes.Structure): '--with-memory-sanitizer' in _config_args ) +# Does io.IOBase logs unhandled exceptions on calling close()? +# They are silenced by default in release build. +DESTRUCTOR_LOG_ERRORS = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) + + def _default_chunk_size(): """Get the default TextIOWrapper chunk size""" with open(__file__, "r", encoding="latin-1") as f: @@ -986,6 +991,9 @@ def flush(self): # This would cause an assertion failure. self.assertRaises(OSError, f.close) + # Silence destructor error + R.flush = lambda self: None + class CIOTest(IOTest): @@ -1097,9 +1105,16 @@ def f(): s = s.getvalue().strip() if s: # The destructor *may* have printed an unraisable error, check it - self.assertEqual(len(s.splitlines()), 1) - self.assertTrue(s.startswith("Exception OSError: "), s) - self.assertTrue(s.endswith(" ignored"), s) + lines = s.splitlines() + if DESTRUCTOR_LOG_ERRORS: + self.assertEqual(len(lines), 5) + self.assertTrue(lines[0].startswith("Exception ignored in: "), lines) + self.assertEqual(lines[1], "Traceback (most recent call last):", lines) + self.assertEqual(lines[4], 'OSError:', lines) + else: + self.assertEqual(len(lines), 1) + self.assertTrue(lines[-1].startswith("Exception OSError: "), lines) + self.assertTrue(lines[-1].endswith(" ignored"), lines) def test_repr(self): raw = self.MockRawIO() @@ -1155,6 +1170,10 @@ def bad_close(): self.assertEqual(err.exception.__context__.args, ('flush',)) self.assertFalse(b.closed) + # Silence destructor error + raw.close = lambda: None + b.flush = lambda: None + def test_nonnormalized_close_error_on_close(self): # Issue #21677 raw = self.MockRawIO() @@ -1172,6 +1191,10 @@ def bad_close(): self.assertIn('non_existing_flush', str(err.exception.__context__)) self.assertFalse(b.closed) + # Silence destructor error + b.flush = lambda: None + raw.close = lambda: None + def test_multi_close(self): raw = self.MockRawIO() b = self.tp(raw) @@ -2027,6 +2050,9 @@ def reader_close(): self.assertFalse(reader.closed) self.assertTrue(writer.closed) + # Silence destructor error + reader.close = lambda: None + def test_writer_close_error_on_close(self): def writer_close(): writer_non_existing @@ -2041,6 +2067,9 @@ def writer_close(): self.assertTrue(reader.closed) self.assertFalse(writer.closed) + # Silence destructor error + writer.close = lambda: None + def test_reader_writer_close_error_on_close(self): def reader_close(): reader_non_existing @@ -2060,6 +2089,10 @@ def writer_close(): self.assertFalse(reader.closed) self.assertFalse(writer.closed) + # Silence destructor error + reader.close = lambda: None + writer.close = lambda: None + def test_isatty(self): class SelectableIsAtty(MockRawIO): def __init__(self, isatty): @@ -2833,9 +2866,16 @@ def f(): s = s.getvalue().strip() if s: # The destructor *may* have printed an unraisable error, check it - self.assertEqual(len(s.splitlines()), 1) - self.assertTrue(s.startswith("Exception OSError: "), s) - self.assertTrue(s.endswith(" ignored"), s) + lines = s.splitlines() + if DESTRUCTOR_LOG_ERRORS: + self.assertEqual(len(lines), 5) + self.assertTrue(lines[0].startswith("Exception ignored in: "), lines) + self.assertEqual(lines[1], "Traceback (most recent call last):", lines) + self.assertEqual(lines[4], 'OSError:', lines) + else: + self.assertEqual(len(lines), 1) + self.assertTrue(lines[-1].startswith("Exception OSError: "), lines) + self.assertTrue(lines[-1].endswith(" ignored"), lines) # Systematic tests of the text I/O API @@ -3251,6 +3291,10 @@ def bad_close(): self.assertEqual(err.exception.__context__.args, ('flush',)) self.assertFalse(txt.closed) + # Silence destructor error + buffer.close = lambda: None + txt.flush = lambda: None + def test_nonnormalized_close_error_on_close(self): # Issue #21677 buffer = self.BytesIO(self.testdata) @@ -3268,6 +3312,10 @@ def bad_close(): self.assertIn('non_existing_flush', str(err.exception.__context__)) self.assertFalse(txt.closed) + # Silence destructor error + buffer.close = lambda: None + txt.flush = lambda: None + def test_multi_close(self): txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") txt.close() diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 0e0753f34c4..20316f15f8c 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -92,11 +92,14 @@ def pickle_test(self, addr): y = pickle.loads(pickle.dumps(x, proto)) self.assertEqual(y, x) + class CommonTestMixin_v4(CommonTestMixin): def test_leading_zeros(self): self.assertInstancesEqual("000.000.000.000", "0.0.0.0") self.assertInstancesEqual("192.168.000.001", "192.168.0.1") + self.assertInstancesEqual("016.016.016.016", "16.16.16.16") + self.assertInstancesEqual("001.000.008.016", "1.0.8.16") def test_int(self): self.assertInstancesEqual(0, "0.0.0.0") @@ -229,15 +232,6 @@ def assertBadOctet(addr, octet): assertBadOctet("1.2.3.4::", "4::") assertBadOctet("1.a.2.3", "a") - def test_octal_decimal_ambiguity(self): - def assertBadOctet(addr, octet): - msg = "Ambiguous (octal/decimal) value in %r not permitted in %r" - with self.assertAddressError(re.escape(msg % (octet, addr))): - ipaddress.IPv4Address(addr) - - assertBadOctet("016.016.016.016", "016") - assertBadOctet("001.000.008.016", "008") - def test_octet_length(self): def assertBadOctet(addr, octet): msg = "At most 3 characters permitted in %r in %r" @@ -405,7 +399,13 @@ class NetmaskTestMixin_v4(CommonTestMixin_v4): """Input validation on interfaces and networks is very similar""" def test_no_mask(self): - self.assertEqual(str(self.factory('1.2.3.4')), '1.2.3.4/32') + for address in ('1.2.3.4', 0x01020304, b'\x01\x02\x03\x04'): + net = self.factory(address) + self.assertEqual(str(net), '1.2.3.4/32') + self.assertEqual(str(net.netmask), '255.255.255.255') + self.assertEqual(str(net.hostmask), '0.0.0.0') + # IPv4Network has prefixlen, but IPv4Interface doesn't. + # Should we add it to IPv4Interface too? (bpo-36392) def test_split_netmask(self): addr = "1.2.3.4/32/24" @@ -533,6 +533,15 @@ def test_subnet_of_mixed_types(self): class NetmaskTestMixin_v6(CommonTestMixin_v6): """Input validation on interfaces and networks is very similar""" + def test_no_mask(self): + for address in ('::1', 1, b'\x00'*15 + b'\x01'): + net = self.factory(address) + self.assertEqual(str(net), '::1/128') + self.assertEqual(str(net.netmask), 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff') + self.assertEqual(str(net.hostmask), '::') + # IPv6Network has prefixlen, but IPv6Interface doesn't. + # Should we add it to IPv4Interface too? (bpo-36392) + def test_split_netmask(self): addr = "cafe:cafe::/128/190" with self.assertAddressError("Only one '/' permitted in %r" % addr): @@ -967,20 +976,6 @@ def testInternals(self): self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128)) self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network)) - def testMissingNetworkVersion(self): - class Broken(ipaddress._BaseNetwork): - pass - broken = Broken('127.0.0.1') - with self.assertRaisesRegex(NotImplementedError, "Broken.*version"): - broken.version - - def testMissingAddressClass(self): - class Broken(ipaddress._BaseNetwork): - pass - broken = Broken('127.0.0.1') - with self.assertRaisesRegex(NotImplementedError, "Broken.*address"): - broken._address_class - def testGetNetwork(self): self.assertEqual(int(self.ipv4_network.network_address), 16909056) self.assertEqual(str(self.ipv4_network.network_address), '1.2.3.0') @@ -1046,27 +1041,12 @@ def testZeroNetmask(self): ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0') self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0) self.assertEqual(ipv4_zero_netmask._prefix_from_prefix_string('0'), 0) - self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0')) - self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0.0.0.0')) - self.assertFalse(ipv4_zero_netmask._is_valid_netmask('invalid')) ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0') self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0) self.assertEqual(ipv6_zero_netmask._prefix_from_prefix_string('0'), 0) - def testIPv4NetAndHostmasks(self): - net = self.ipv4_network - self.assertFalse(net._is_valid_netmask('invalid')) - self.assertTrue(net._is_valid_netmask('128.128.128.128')) - self.assertFalse(net._is_valid_netmask('128.128.128.127')) - self.assertFalse(net._is_valid_netmask('128.128.128.255')) - self.assertTrue(net._is_valid_netmask('255.128.128.128')) - - self.assertFalse(net._is_hostmask('invalid')) - self.assertTrue(net._is_hostmask('128.255.255.255')) - self.assertFalse(net._is_hostmask('255.255.255.255')) - self.assertFalse(net._is_hostmask('1.2.3.4')) - + def testIPv4Net(self): net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255') self.assertEqual(net.prefixlen, 24) @@ -2007,25 +1987,22 @@ def testWithStar(self): def testNetworkElementCaching(self): # V4 - make sure we're empty - self.assertNotIn('network_address', self.ipv4_network._cache) - self.assertNotIn('broadcast_address', self.ipv4_network._cache) - self.assertNotIn('hostmask', self.ipv4_network._cache) + self.assertNotIn('broadcast_address', self.ipv4_network.__dict__) + self.assertNotIn('hostmask', self.ipv4_network.__dict__) # V4 - populate and test - self.assertEqual(self.ipv4_network.network_address, - ipaddress.IPv4Address('1.2.3.0')) self.assertEqual(self.ipv4_network.broadcast_address, ipaddress.IPv4Address('1.2.3.255')) self.assertEqual(self.ipv4_network.hostmask, ipaddress.IPv4Address('0.0.0.255')) # V4 - check we're cached - self.assertIn('broadcast_address', self.ipv4_network._cache) - self.assertIn('hostmask', self.ipv4_network._cache) + self.assertIn('broadcast_address', self.ipv4_network.__dict__) + self.assertIn('hostmask', self.ipv4_network.__dict__) # V6 - make sure we're empty - self.assertNotIn('broadcast_address', self.ipv6_network._cache) - self.assertNotIn('hostmask', self.ipv6_network._cache) + self.assertNotIn('broadcast_address', self.ipv6_network.__dict__) + self.assertNotIn('hostmask', self.ipv6_network.__dict__) # V6 - populate and test self.assertEqual(self.ipv6_network.network_address, @@ -2045,10 +2022,10 @@ def testNetworkElementCaching(self): ipaddress.IPv6Address('::ffff:ffff:ffff:ffff')) # V6 - check we're cached - self.assertIn('broadcast_address', self.ipv6_network._cache) - self.assertIn('hostmask', self.ipv6_network._cache) - self.assertIn('broadcast_address', self.ipv6_interface.network._cache) - self.assertIn('hostmask', self.ipv6_interface.network._cache) + self.assertIn('broadcast_address', self.ipv6_network.__dict__) + self.assertIn('hostmask', self.ipv6_network.__dict__) + self.assertIn('broadcast_address', self.ipv6_interface.network.__dict__) + self.assertIn('hostmask', self.ipv6_interface.network.__dict__) def testTeredo(self): # stolen from wikipedia diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py index fdb9e62124e..895c95b54c3 100644 --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@ -95,5 +95,9 @@ def test_negative_index(self): d = self.json.JSONDecoder() self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000) + def test_deprecated_encode(self): + with self.assertWarns(DeprecationWarning): + self.loads('{}', encoding='fake') + class TestPyDecode(TestDecode, PyTest): pass class TestCDecode(TestDecode, CTest): pass diff --git a/Lib/test/test_keyword.py b/Lib/test/test_keyword.py index af99f52c630..3e2a8b3fb7f 100644 --- a/Lib/test/test_keyword.py +++ b/Lib/test/test_keyword.py @@ -1,20 +1,5 @@ import keyword import unittest -from test import support -import filecmp -import os -import sys -import subprocess -import shutil -import textwrap - -KEYWORD_FILE = support.findfile('keyword.py') -GRAMMAR_FILE = os.path.join(os.path.split(__file__)[0], - '..', '..', 'Python', 'graminit.c') -TEST_PY_FILE = 'keyword_test.py' -GRAMMAR_TEST_FILE = 'graminit_test.c' -PY_FILE_WITHOUT_KEYWORDS = 'minimal_keyword.py' -NONEXISTENT_FILE = 'not_here.txt' class Test_iskeyword(unittest.TestCase): @@ -35,103 +20,17 @@ def test_changing_the_kwlist_does_not_affect_iskeyword(self): keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice'] self.assertFalse(keyword.iskeyword('eggs')) + def test_all_keywords_fail_to_be_used_as_names(self): + for key in keyword.kwlist: + with self.assertRaises(SyntaxError): + exec(f"{key} = 42") -class TestKeywordGeneration(unittest.TestCase): + def test_async_and_await_are_keywords(self): + self.assertIn("async", keyword.kwlist) + self.assertIn("await", keyword.kwlist) - def _copy_file_without_generated_keywords(self, source_file, dest_file): - with open(source_file, 'rb') as fp: - lines = fp.readlines() - nl = lines[0][len(lines[0].strip()):] - with open(dest_file, 'wb') as fp: - fp.writelines(lines[:lines.index(b"#--start keywords--" + nl) + 1]) - fp.writelines(lines[lines.index(b"#--end keywords--" + nl):]) - - def _generate_keywords(self, grammar_file, target_keyword_py_file): - proc = subprocess.Popen([sys.executable, - KEYWORD_FILE, - grammar_file, - target_keyword_py_file], stderr=subprocess.PIPE) - stderr = proc.communicate()[1] - return proc.returncode, stderr - - @unittest.skipIf(not os.path.exists(GRAMMAR_FILE), - 'test only works from source build directory') - def test_real_grammar_and_keyword_file(self): - self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE) - self.addCleanup(support.unlink, TEST_PY_FILE) - self.assertFalse(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE)) - self.assertEqual((0, b''), self._generate_keywords(GRAMMAR_FILE, - TEST_PY_FILE)) - self.assertTrue(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE)) - - def test_grammar(self): - self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE) - self.addCleanup(support.unlink, TEST_PY_FILE) - with open(GRAMMAR_TEST_FILE, 'w') as fp: - # Some of these are probably implementation accidents. - fp.writelines(textwrap.dedent("""\ - {2, 1}, - {11, "encoding_decl", 0, 2, states_79, - "\000\000\040\000\000\000\000\000\000\000\000\000" - "\000\000\000\000\000\000\000\000\000"}, - {1, "jello"}, - {326, 0}, - {1, "turnip"}, - \t{1, "This one is tab indented" - {278, 0}, - {1, "crazy but legal" - "also legal" {1, " - {1, "continue"}, - {1, "lemon"}, - {1, "tomato"}, - {1, "wigii"}, - {1, 'no good'} - {283, 0}, - {1, "too many spaces"}""")) - self.addCleanup(support.unlink, GRAMMAR_TEST_FILE) - self._generate_keywords(GRAMMAR_TEST_FILE, TEST_PY_FILE) - expected = [ - " 'This one is tab indented',", - " 'also legal',", - " 'continue',", - " 'crazy but legal',", - " 'jello',", - " 'lemon',", - " 'tomato',", - " 'turnip',", - " 'wigii',", - ] - with open(TEST_PY_FILE) as fp: - lines = fp.read().splitlines() - start = lines.index("#--start keywords--") + 1 - end = lines.index("#--end keywords--") - actual = lines[start:end] - self.assertEqual(actual, expected) - - def test_empty_grammar_results_in_no_keywords(self): - self._copy_file_without_generated_keywords(KEYWORD_FILE, - PY_FILE_WITHOUT_KEYWORDS) - self.addCleanup(support.unlink, PY_FILE_WITHOUT_KEYWORDS) - shutil.copyfile(KEYWORD_FILE, TEST_PY_FILE) - self.addCleanup(support.unlink, TEST_PY_FILE) - self.assertEqual((0, b''), self._generate_keywords(os.devnull, - TEST_PY_FILE)) - self.assertTrue(filecmp.cmp(TEST_PY_FILE, PY_FILE_WITHOUT_KEYWORDS)) - - def test_keywords_py_without_markers_produces_error(self): - rc, stderr = self._generate_keywords(os.devnull, os.devnull) - self.assertNotEqual(rc, 0) - self.assertRegex(stderr, b'does not contain format markers') - - def test_missing_grammar_file_produces_error(self): - rc, stderr = self._generate_keywords(NONEXISTENT_FILE, KEYWORD_FILE) - self.assertNotEqual(rc, 0) - self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode()) - - def test_missing_keywords_py_file_produces_error(self): - rc, stderr = self._generate_keywords(os.devnull, NONEXISTENT_FILE) - self.assertNotEqual(rc, 0) - self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode()) + def test_keywords_are_sorted(self): + self.assertListEqual(sorted(keyword.kwlist), keyword.kwlist) if __name__ == "__main__": diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index 1099c759a79..998fd9d4649 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -110,9 +110,7 @@ def test_create_event(self): def test_queue_event(self): - serverSocket = socket.socket() - serverSocket.bind(('127.0.0.1', 0)) - serverSocket.listen() + serverSocket = socket.create_server(('127.0.0.1', 0)) client = socket.socket() client.setblocking(False) try: diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index b23ae24920b..bc99c3adbe3 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -315,12 +315,6 @@ def test_regression_22386(self): self.assertEqual(logging.getLevelName('INFO'), logging.INFO) self.assertEqual(logging.getLevelName(logging.INFO), 'INFO') - def test_regression_29220(self): - """See issue #29220 for more information.""" - logging.addLevelName(logging.INFO, '') - self.addCleanup(logging.addLevelName, logging.INFO, 'INFO') - self.assertEqual(logging.getLevelName(logging.INFO), '') - def test_issue27935(self): fatal = logging.getLevelName('FATAL') self.assertEqual(fatal, logging.FATAL) @@ -674,10 +668,28 @@ def remove_loop(fname, tries): # register_at_fork mechanism is also present and used. @unittest.skipIf(not hasattr(os, 'fork'), 'Test requires os.fork().') def test_post_fork_child_no_deadlock(self): - """Ensure forked child logging locks are not held; bpo-6721.""" - refed_h = logging.Handler() + """Ensure child logging locks are not held; bpo-6721 & bpo-36533.""" + class _OurHandler(logging.Handler): + def __init__(self): + super().__init__() + self.sub_handler = logging.StreamHandler( + stream=open('/dev/null', 'wt')) + + def emit(self, record): + self.sub_handler.acquire() + try: + self.sub_handler.emit(record) + finally: + self.sub_handler.release() + + self.assertEqual(len(logging._handlers), 0) + refed_h = _OurHandler() refed_h.name = 'because we need at least one for this test' self.assertGreater(len(logging._handlers), 0) + self.assertGreater(len(logging._at_fork_reinit_lock_weakset), 1) + test_logger = logging.getLogger('test_post_fork_child_no_deadlock') + test_logger.addHandler(refed_h) + test_logger.setLevel(logging.DEBUG) locks_held__ready_to_fork = threading.Event() fork_happened__release_locks_and_end_thread = threading.Event() @@ -715,19 +727,24 @@ def lock_holder_thread_fn(): locks_held__ready_to_fork.wait() pid = os.fork() if pid == 0: # Child. - logging.error(r'Child process did not deadlock. \o/') - os._exit(0) + try: + test_logger.info(r'Child process did not deadlock. \o/') + finally: + os._exit(0) else: # Parent. + test_logger.info(r'Parent process returned from fork. \o/') fork_happened__release_locks_and_end_thread.set() lock_holder_thread.join() start_time = time.monotonic() while True: + test_logger.debug('Waiting for child process.') waited_pid, status = os.waitpid(pid, os.WNOHANG) if waited_pid == pid: break # child process exited. if time.monotonic() - start_time > 7: break # so long? implies child deadlock. time.sleep(0.05) + test_logger.debug('Done waiting.') if waited_pid != pid: os.kill(pid, signal.SIGKILL) waited_pid, status = os.waitpid(pid, 0) @@ -743,6 +760,10 @@ class TestStreamHandler(logging.StreamHandler): def handleError(self, record): self.error_record = record +class StreamWithIntName(object): + level = logging.NOTSET + name = 2 + class StreamHandlerTest(BaseTest): def test_error_handling(self): h = TestStreamHandler(BadStream()) @@ -780,6 +801,10 @@ def test_stream_setting(self): actual = h.setStream(old) self.assertIsNone(actual) + def test_can_represent_stream_with_int_name(self): + h = logging.StreamHandler(StreamWithIntName()) + self.assertEqual(repr(h), '') + # -- The following section could be moved into a server_helper.py module # -- if it proves to be of wider utility than just test_logging @@ -3505,6 +3530,19 @@ def test_queue_listener_with_StreamHandler(self): listener.stop() self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1) + @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), + 'logging.handlers.QueueListener required for this test') + def test_queue_listener_with_multiple_handlers(self): + # Test that queue handler format doesn't affect other handler formats (bpo-35726). + self.que_hdlr.setFormatter(self.root_formatter) + self.que_logger.addHandler(self.root_hdlr) + + listener = logging.handlers.QueueListener(self.queue, self.que_hdlr) + listener.start() + self.que_logger.error("error") + listener.stop() + self.assertEqual(self.stream.getvalue().strip(), "que -> ERROR: error") + if hasattr(logging.handlers, 'QueueListener'): import multiprocessing from unittest.mock import patch diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 554d3d5cead..c4b2fe2047a 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -6,6 +6,7 @@ import unittest from test import support +from platform import win32_edition # Tell it we don't know about external files: mimetypes.knownfiles = [] @@ -116,6 +117,8 @@ def tearDown(self): mimetypes.types_map.clear() mimetypes.types_map.update(self.original_types_map) + @unittest.skipIf(win32_edition() in ('NanoServer', 'WindowsCoreHeadless', 'IoTEdgeOS'), + "MIME types registry keys unavailable") def test_registry_parsing(self): # the original, minimum contents of the MIME database in the # Windows registry is undocumented AFAIK. diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index f3ef958b535..70965854ed1 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1631,5 +1631,21 @@ def test_toprettyxml_with_attributes_ordered(self): '\n' '\n') + def test_toprettyxml_with_cdata(self): + xml_str = ']]>' + doc = parseString(xml_str) + self.assertEqual(doc.toprettyxml(), + '\n' + '\n' + '\t]]>\n' + '\n') + + def test_cdata_parsing(self): + xml_str = ']]>' + dom1 = parseString(xml_str) + self.checkWholeText(dom1.getElementsByTagName('node')[0].firstChild, '') + dom2 = parseString(dom1.toprettyxml()) + self.checkWholeText(dom2.getElementsByTagName('node')[0].firstChild, '') + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py index e4df2a90d4a..ebd96e1c8a2 100644 --- a/Lib/test/test_modulefinder.py +++ b/Lib/test/test_modulefinder.py @@ -218,6 +218,33 @@ def foo(): pass "" ] +syntax_error_test = [ + "a.module", + ["a", "a.module", "b"], + ["b.module"], [], + """\ +a/__init__.py +a/module.py + import b.module +b/__init__.py +b/module.py + ? # SyntaxError: invalid syntax +"""] + + +same_name_as_bad_test = [ + "a.module", + ["a", "a.module", "b", "b.c"], + ["c"], [], + """\ +a/__init__.py +a/module.py + import c + from b import c +b/__init__.py +b/c.py +"""] + def open_file(path): dirname = os.path.dirname(path) @@ -299,6 +326,12 @@ def test_relative_imports_3(self): def test_relative_imports_4(self): self._do_test(relative_import_test_4) + def test_syntax_error(self): + self._do_test(syntax_error_test) + + def test_same_name_as_bad(self): + self._do_test(same_name_as_bad_test) + def test_bytecode(self): base_path = os.path.join(TEST_DIR, 'a') source_path = base_path + importlib.machinery.SOURCE_SUFFIXES[0] diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 8c1032b986b..618b403bfb5 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -6,6 +6,7 @@ import functools import contextlib import os.path +import re import threading from test import support @@ -21,6 +22,13 @@ TIMEOUT = 30 certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem') +if ssl is not None: + SSLError = ssl.SSLError +else: + class SSLError(Exception): + """Non-existent exception class when we lack SSL support.""" + reason = "This will never be raised." + # TODO: # - test the `file` arg to more commands # - test error conditions @@ -261,14 +269,21 @@ def is_connected(): return False return True - with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server: - self.assertTrue(is_connected()) - self.assertTrue(server.help()) - self.assertFalse(is_connected()) + try: + with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server: + self.assertTrue(is_connected()) + self.assertTrue(server.help()) + self.assertFalse(is_connected()) - with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server: - server.quit() - self.assertFalse(is_connected()) + with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server: + server.quit() + self.assertFalse(is_connected()) + except SSLError as ssl_err: + # matches "[SSL: DH_KEY_TOO_SMALL] dh key too small" + if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason): + raise unittest.SkipTest(f"Got {ssl_err} connecting " + f"to {self.NNTP_HOST!r}") + raise NetworkedNNTPTestsMixin.wrap_methods() @@ -294,6 +309,12 @@ def setUpClass(cls): try: cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) + except SSLError as ssl_err: + # matches "[SSL: DH_KEY_TOO_SMALL] dh key too small" + if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason): + raise unittest.SkipTest(f"{cls} got {ssl_err} connecting " + f"to {cls.NNTP_HOST!r}") + raise except EOF_ERRORS: raise unittest.SkipTest(f"{cls} got EOF error on connecting " f"to {cls.NNTP_HOST!r}") diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 4c620ccae9c..a2021b1eba0 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -28,6 +28,7 @@ import uuid import warnings from test import support +from platform import win32_is_iot try: import resource @@ -2337,19 +2338,10 @@ def test_unlink_removes_junction(self): @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") class Win32NtTests(unittest.TestCase): - def setUp(self): - from test import support - self.nt = support.import_module('nt') - pass - - def tearDown(self): - pass - def test_getfinalpathname_handles(self): - try: - import ctypes, ctypes.wintypes - except ImportError: - raise unittest.SkipTest('ctypes module is required for this test') + nt = support.import_module('nt') + ctypes = support.import_module('ctypes') + import ctypes.wintypes kernel = ctypes.WinDLL('Kernel32.dll', use_last_error=True) kernel.GetCurrentProcess.restype = ctypes.wintypes.HANDLE @@ -2368,21 +2360,23 @@ def test_getfinalpathname_handles(self): before_count = handle_count.value # The first two test the error path, __file__ tests the success path - filenames = [ r'\\?\C:', - r'\\?\NUL', - r'\\?\CONIN', - __file__ ] + filenames = [ + r'\\?\C:', + r'\\?\NUL', + r'\\?\CONIN', + __file__, + ] - for i in range(10): + for _ in range(10): for name in filenames: try: - tmp = self.nt._getfinalpathname(name) - except: + nt._getfinalpathname(name) + except Exception: # Failure is expected pass try: - tmp = os.stat(name) - except: + os.stat(name) + except Exception: pass ok = kernel.GetProcessHandleCount(hproc, ctypes.byref(handle_count)) @@ -2446,7 +2440,7 @@ def test_bad_fd(self): # Return None when an fd doesn't actually exist. self.assertIsNone(os.device_encoding(123456)) - @unittest.skipUnless(os.isatty(0) and (sys.platform.startswith('win') or + @unittest.skipUnless(os.isatty(0) and not win32_is_iot() and (sys.platform.startswith('win') or (hasattr(locale, 'nl_langinfo') and hasattr(locale, 'CODESET'))), 'test requires a tty and either Windows or nl_langinfo(CODESET)') def test_device_encoding(self): diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index bfa0a5a34e2..b830459b190 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -233,6 +233,18 @@ def test_function_defs(self): self.check_suite("def f(*args, a, b = 5): pass") self.check_suite("def f(*args, a, b = 5, **kwds): pass") + # positional-only arguments + self.check_suite("def f(a, /): pass") + self.check_suite("def f(a, /,): pass") + self.check_suite("def f(a, b, /): pass") + self.check_suite("def f(a, b, /, c): pass") + self.check_suite("def f(a, b, /, c = 6): pass") + self.check_suite("def f(a, b, /, c, *, d): pass") + self.check_suite("def f(a, b, /, c = 1, *, d): pass") + self.check_suite("def f(a, b, /, c, *, d = 1): pass") + self.check_suite("def f(a, b=1, /, c=2, *, d = 3): pass") + self.check_suite("def f(a=0, b=1, /, c=2, *, d = 3): pass") + # function annotations self.check_suite("def f(a: int): pass") self.check_suite("def f(a: int = 5): pass") @@ -749,6 +761,22 @@ def test_illegal_encoding(self): with self.assertRaises(UnicodeEncodeError): parser.sequence2st(tree) + def test_invalid_node_id(self): + tree = (257, (269, (-7, ''))) + self.check_bad_tree(tree, "negative node id") + tree = (257, (269, (99, ''))) + self.check_bad_tree(tree, "invalid token id") + tree = (257, (269, (9999, (0, '')))) + self.check_bad_tree(tree, "invalid symbol id") + + def test_ParserError_message(self): + try: + parser.sequence2st((257,(269,(257,(0,''))))) + except parser.ParserError as why: + self.assertIn("compound_stmt", str(why)) # Expected + self.assertIn("file_input", str(why)) # Got + + class CompileTestCase(unittest.TestCase): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index f8325eb9327..990207b9c4e 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1643,6 +1643,25 @@ def test_rmdir(self): self.assertFileNotFound(p.stat) self.assertFileNotFound(p.unlink) + def test_link_to(self): + P = self.cls(BASE) + p = P / 'fileA' + size = p.stat().st_size + # linking to another path. + q = P / 'dirA' / 'fileAA' + try: + p.link_to(q) + except PermissionError as e: + self.skipTest('os.link(): %s' % e) + self.assertEqual(q.stat().st_size, size) + self.assertEqual(os.path.samefile(p, q), True) + self.assertTrue(p.stat) + # Linking to a str of a relative path. + r = rel_join('fileAAA') + q.link_to(r) + self.assertEqual(os.stat(r).st_size, size) + self.assertTrue(q.stat) + def test_rename(self): P = self.cls(BASE) p = P / 'fileA' diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 7e03df02946..56d82324954 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1266,9 +1266,9 @@ def bar(): any('main.py(5)foo()->None' in l for l in stdout.splitlines()), 'Fail to step into the caller after a return') - def test_issue13210(self): - # invoking "continue" on a non-main thread triggered an exception - # inside signal.signal + def test_issue13120(self): + # Invoking "continue" on a non-main thread triggered an exception + # inside signal.signal. with open(support.TESTFN, 'wb') as f: f.write(textwrap.dedent(""" diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py new file mode 100644 index 00000000000..d4d259ef269 --- /dev/null +++ b/Lib/test/test_positional_only_arg.py @@ -0,0 +1,403 @@ +"""Unit tests for the positional only argument syntax specified in PEP 570.""" + +import pickle +import unittest + +from test.support import check_syntax_error + + +def global_pos_only_f(a, b, /): + return a, b + +def global_pos_only_and_normal(a, /, b): + return a, b + +def global_pos_only_defaults(a=1, /, b=2): + return a, b + + +class PositionalOnlyTestCase(unittest.TestCase): + + def assertRaisesSyntaxError(self, codestr, regex="invalid syntax"): + with self.assertRaisesRegex(SyntaxError, regex): + compile(codestr + "\n", "", "single") + + def test_invalid_syntax_errors(self): + check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(*args, /): pass") + check_syntax_error(self, "def f(*args, a, /): pass") + check_syntax_error(self, "def f(**kwargs, /): pass") + check_syntax_error(self, "def f(/, a = 1): pass") + check_syntax_error(self, "def f(/, a): pass") + check_syntax_error(self, "def f(/): pass") + check_syntax_error(self, "def f(*, a, /): pass") + check_syntax_error(self, "def f(*, /, a): pass") + check_syntax_error(self, "def f(a, /, a): pass", "duplicate argument 'a' in function definition") + check_syntax_error(self, "def f(a, /, *, a): pass", "duplicate argument 'a' in function definition") + check_syntax_error(self, "def f(a, b/2, c): pass") + check_syntax_error(self, "def f(a, /, c, /): pass") + check_syntax_error(self, "def f(a, /, c, /, d): pass") + check_syntax_error(self, "def f(a, /, c, /, d, *, e): pass") + check_syntax_error(self, "def f(a, *, c, /, d, e): pass") + + def test_invalid_syntax_errors_async(self): + check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(*args, /): pass") + check_syntax_error(self, "async def f(*args, a, /): pass") + check_syntax_error(self, "async def f(**kwargs, /): pass") + check_syntax_error(self, "async def f(/, a = 1): pass") + check_syntax_error(self, "async def f(/, a): pass") + check_syntax_error(self, "async def f(/): pass") + check_syntax_error(self, "async def f(*, a, /): pass") + check_syntax_error(self, "async def f(*, /, a): pass") + check_syntax_error(self, "async def f(a, /, a): pass", "duplicate argument 'a' in function definition") + check_syntax_error(self, "async def f(a, /, *, a): pass", "duplicate argument 'a' in function definition") + check_syntax_error(self, "async def f(a, b/2, c): pass") + check_syntax_error(self, "async def f(a, /, c, /): pass") + check_syntax_error(self, "async def f(a, /, c, /, d): pass") + check_syntax_error(self, "async def f(a, /, c, /, d, *, e): pass") + check_syntax_error(self, "async def f(a, *, c, /, d, e): pass") + + def test_optional_positional_only_args(self): + def f(a, b=10, /, c=100): + return a + b + c + + self.assertEqual(f(1, 2, 3), 6) + self.assertEqual(f(1, 2, c=3), 6) + with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"): + f(1, b=2, c=3) + + self.assertEqual(f(1, 2), 103) + with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"): + f(1, b=2) + self.assertEqual(f(1, c=2), 13) + + def f(a=1, b=10, /, c=100): + return a + b + c + + self.assertEqual(f(1, 2, 3), 6) + self.assertEqual(f(1, 2, c=3), 6) + with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"): + f(1, b=2, c=3) + + self.assertEqual(f(1, 2), 103) + with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"): + f(1, b=2) + self.assertEqual(f(1, c=2), 13) + + def test_syntax_for_many_positional_only(self): + # more than 255 positional only arguments, should compile ok + fundef = "def f(%s, /):\n pass\n" % ', '.join('i%d' % i for i in range(300)) + compile(fundef, "", "single") + + def test_pos_only_definition(self): + def f(a, b, c, /, d, e=1, *, f, g=2): + pass + + self.assertEqual(2, f.__code__.co_argcount) # 2 "standard args" + self.assertEqual(3, f.__code__.co_posonlyargcount) + self.assertEqual((1,), f.__defaults__) + + def f(a, b, c=1, /, d=2, e=3, *, f, g=4): + pass + + self.assertEqual(2, f.__code__.co_argcount) # 2 "standard args" + self.assertEqual(3, f.__code__.co_posonlyargcount) + self.assertEqual((1, 2, 3), f.__defaults__) + + def test_pos_only_call_via_unpacking(self): + def f(a, b, /): + return a + b + + self.assertEqual(f(*[1, 2]), 3) + + def test_use_positional_as_keyword(self): + def f(a, /): + pass + expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'" + with self.assertRaisesRegex(TypeError, expected): + f(a=1) + + def f(a, /, b): + pass + expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'" + with self.assertRaisesRegex(TypeError, expected): + f(a=1, b=2) + + def f(a, b, /): + pass + expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'a, b'" + with self.assertRaisesRegex(TypeError, expected): + f(a=1, b=2) + + def test_positional_only_and_arg_invalid_calls(self): + def f(a, b, /, c): + pass + with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'c'"): + f(1, 2) + with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'b' and 'c'"): + f(1) + with self.assertRaisesRegex(TypeError, r"f\(\) missing 3 required positional arguments: 'a', 'b', and 'c'"): + f() + with self.assertRaisesRegex(TypeError, r"f\(\) takes 3 positional arguments but 4 were given"): + f(1, 2, 3, 4) + + def test_positional_only_and_optional_arg_invalid_calls(self): + def f(a, b, /, c=3): + pass + f(1, 2) # does not raise + with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'b'"): + f(1) + with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'a' and 'b'"): + f() + with self.assertRaisesRegex(TypeError, r"f\(\) takes from 2 to 3 positional arguments but 4 were given"): + f(1, 2, 3, 4) + + def test_positional_only_and_kwonlyargs_invalid_calls(self): + def f(a, b, /, c, *, d, e): + pass + f(1, 2, 3, d=1, e=2) # does not raise + with self.assertRaisesRegex(TypeError, r"missing 1 required keyword-only argument: 'd'"): + f(1, 2, 3, e=2) + with self.assertRaisesRegex(TypeError, r"missing 2 required keyword-only arguments: 'd' and 'e'"): + f(1, 2, 3) + with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'c'"): + f(1, 2) + with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'b' and 'c'"): + f(1) + with self.assertRaisesRegex(TypeError, r" missing 3 required positional arguments: 'a', 'b', and 'c'"): + f() + with self.assertRaisesRegex(TypeError, r"f\(\) takes 3 positional arguments but 6 positional arguments " + r"\(and 2 keyword-only arguments\) were given"): + f(1, 2, 3, 4, 5, 6, d=7, e=8) + with self.assertRaisesRegex(TypeError, r"f\(\) got an unexpected keyword argument 'f'"): + f(1, 2, 3, d=1, e=4, f=56) + + def test_positional_only_invalid_calls(self): + def f(a, b, /): + pass + f(1, 2) # does not raise + with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'b'"): + f(1) + with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'a' and 'b'"): + f() + with self.assertRaisesRegex(TypeError, r"f\(\) takes 2 positional arguments but 3 were given"): + f(1, 2, 3) + + def test_positional_only_with_optional_invalid_calls(self): + def f(a, b=2, /): + pass + f(1) # does not raise + with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'a'"): + f() + + with self.assertRaisesRegex(TypeError, r"f\(\) takes from 1 to 2 positional arguments but 3 were given"): + f(1, 2, 3) + + def test_no_standard_args_usage(self): + def f(a, b, /, *, c): + pass + + f(1, 2, c=3) + with self.assertRaises(TypeError): + f(1, b=2, c=3) + + def test_change_default_pos_only(self): + def f(a, b=2, /, c=3): + return a + b + c + + self.assertEqual((2,3), f.__defaults__) + f.__defaults__ = (1, 2, 3) + self.assertEqual(f(1, 2, 3), 6) + + def test_lambdas(self): + x = lambda a, /, b: a + b + self.assertEqual(x(1,2), 3) + self.assertEqual(x(1,b=2), 3) + + x = lambda a, /, b=2: a + b + self.assertEqual(x(1), 3) + + x = lambda a, b, /: a + b + self.assertEqual(x(1, 2), 3) + + x = lambda a, b, /, : a + b + self.assertEqual(x(1, 2), 3) + + def test_invalid_syntax_lambda(self): + check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda *args, /: None") + check_syntax_error(self, "lambda *args, a, /: None") + check_syntax_error(self, "lambda **kwargs, /: None") + check_syntax_error(self, "lambda /, a = 1: None") + check_syntax_error(self, "lambda /, a: None") + check_syntax_error(self, "lambda /: None") + check_syntax_error(self, "lambda *, a, /: None") + check_syntax_error(self, "lambda *, /, a: None") + check_syntax_error(self, "lambda a, /, a: None", "duplicate argument 'a' in function definition") + check_syntax_error(self, "lambda a, /, *, a: None", "duplicate argument 'a' in function definition") + check_syntax_error(self, "lambda a, /, b, /: None") + check_syntax_error(self, "lambda a, /, b, /, c: None") + check_syntax_error(self, "lambda a, /, b, /, c, *, d: None") + check_syntax_error(self, "lambda a, *, b, /, c: None") + + def test_posonly_methods(self): + class Example: + def f(self, a, b, /): + return a, b + + self.assertEqual(Example().f(1, 2), (1, 2)) + self.assertEqual(Example.f(Example(), 1, 2), (1, 2)) + self.assertRaises(TypeError, Example.f, 1, 2) + expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'" + with self.assertRaisesRegex(TypeError, expected): + Example().f(1, b=2) + + def test_mangling(self): + class X: + def f(self, *, __a=42): + return __a + self.assertEqual(X().f(), 42) + + def test_module_function(self): + with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'a' and 'b'"): + global_pos_only_f() + + + def test_closures(self): + def f(x,y): + def g(x2,/,y2): + return x + y + x2 + y2 + return g + + self.assertEqual(f(1,2)(3,4), 10) + with self.assertRaisesRegex(TypeError, r"g\(\) missing 1 required positional argument: 'y2'"): + f(1,2)(3) + with self.assertRaisesRegex(TypeError, r"g\(\) takes 2 positional arguments but 3 were given"): + f(1,2)(3,4,5) + + def f(x,/,y): + def g(x2,y2): + return x + y + x2 + y2 + return g + + self.assertEqual(f(1,2)(3,4), 10) + + def f(x,/,y): + def g(x2,/,y2): + return x + y + x2 + y2 + return g + + self.assertEqual(f(1,2)(3,4), 10) + with self.assertRaisesRegex(TypeError, r"g\(\) missing 1 required positional argument: 'y2'"): + f(1,2)(3) + with self.assertRaisesRegex(TypeError, r"g\(\) takes 2 positional arguments but 3 were given"): + f(1,2)(3,4,5) + + def test_same_keyword_as_positional_with_kwargs(self): + def f(something,/,**kwargs): + return (something, kwargs) + + self.assertEqual(f(42, something=42), (42, {'something': 42})) + + with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'something'"): + f(something=42) + + self.assertEqual(f(42), (42, {})) + + def test_mangling(self): + class X: + def f(self, __a=42, /): + return __a + + def f2(self, __a=42, /, __b=43): + return (__a, __b) + + def f3(self, __a=42, /, __b=43, *, __c=44): + return (__a, __b, __c) + + self.assertEqual(X().f(), 42) + self.assertEqual(X().f2(), (42, 43)) + self.assertEqual(X().f3(), (42, 43, 44)) + + def test_too_many_arguments(self): + # more than 255 positional-only arguments, should compile ok + fundef = "def f(%s, /):\n pass\n" % ', '.join('i%d' % i for i in range(300)) + compile(fundef, "", "single") + + def test_serialization(self): + pickled_posonly = pickle.dumps(global_pos_only_f) + pickled_optional = pickle.dumps(global_pos_only_and_normal) + pickled_defaults = pickle.dumps(global_pos_only_defaults) + + unpickled_posonly = pickle.loads(pickled_posonly) + unpickled_optional = pickle.loads(pickled_optional) + unpickled_defaults = pickle.loads(pickled_defaults) + + self.assertEqual(unpickled_posonly(1,2), (1,2)) + expected = r"global_pos_only_f\(\) got some positional-only arguments "\ + r"passed as keyword arguments: 'a, b'" + with self.assertRaisesRegex(TypeError, expected): + unpickled_posonly(a=1,b=2) + + self.assertEqual(unpickled_optional(1,2), (1,2)) + expected = r"global_pos_only_and_normal\(\) got some positional-only arguments "\ + r"passed as keyword arguments: 'a'" + with self.assertRaisesRegex(TypeError, expected): + unpickled_optional(a=1,b=2) + + self.assertEqual(unpickled_defaults(), (1,2)) + expected = r"global_pos_only_defaults\(\) got some positional-only arguments "\ + r"passed as keyword arguments: 'a'" + with self.assertRaisesRegex(TypeError, expected): + unpickled_defaults(a=1,b=2) + + def test_async(self): + + async def f(a=1, /, b=2): + return a, b + + with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'"): + f(a=1, b=2) + + def _check_call(*args, **kwargs): + try: + coro = f(*args, **kwargs) + coro.send(None) + except StopIteration as e: + result = e.value + self.assertEqual(result, (1, 2)) + + _check_call(1, 2) + _check_call(1, b=2) + _check_call(1) + _check_call() + + def test_generator(self): + + def f(a=1, /, b=2): + yield a, b + + with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'"): + f(a=1, b=2) + + gen = f(1, 2) + self.assertEqual(next(gen), (1, 2)) + gen = f(1, b=2) + self.assertEqual(next(gen), (1, 2)) + gen = f(1) + self.assertEqual(next(gen), (1, 2)) + gen = f() + self.assertEqual(next(gen), (1, 2)) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index fe21b21b338..843402930ff 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -310,6 +310,14 @@ def test_preadv_flags(self): buf = [bytearray(i) for i in [5, 3, 2]] self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10) self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf)) + except OSError as inst: + # Is possible that the macro RWF_HIPRI was defined at compilation time + # but the option is not supported by the kernel or the runtime libc shared + # library. + if inst.errno in {errno.EINVAL, errno.ENOTSUP}: + raise unittest.SkipTest("RWF_HIPRI is not supported by the current system") + else: + raise finally: os.close(fd) diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index c2bd9f3012c..67c6c5d42d4 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -1250,7 +1250,6 @@ def __get__(self, obj, cls): class X: attr = Descr() - text = pydoc.plain(pydoc.render_doc(X.attr)) self.assertEqual(self._get_summary_lines(X.attr), """\ .Descr object>""") @@ -1276,17 +1275,14 @@ def __set__(self, obj, cls): class X: attr = Descr() - text = pydoc.plain(pydoc.render_doc(X.attr)) self.assertEqual(self._get_summary_lines(X.attr), "") X.attr.__doc__ = 'Custom descriptor' - text = pydoc.plain(pydoc.render_doc(X.attr)) self.assertEqual(self._get_summary_lines(X.attr), """\ Custom descriptor """) X.attr.__name__ = 'foo' - text = pydoc.plain(pydoc.render_doc(X.attr)) self.assertEqual(self._get_summary_lines(X.attr), """\ foo Custom descriptor diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index e818a7b28d4..ff1ddcaf140 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -719,7 +719,7 @@ def test_choices_algorithms(self): c = self.gen.choices(range(n), cum_weights=range(1, n+1), k=10000) self.assertEqual(a, c) - # Amerian Roulette + # American Roulette population = ['Red', 'Black', 'Green'] weights = [18, 18, 2] cum_weights = [18, 36, 38] diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 61937767ec1..9155522c273 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -21,7 +21,7 @@ from test.libregrtest import utils -Py_DEBUG = hasattr(sys, 'getobjects') +Py_DEBUG = hasattr(sys, 'gettotalrefcount') ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..') ROOT_DIR = os.path.abspath(os.path.normpath(ROOT_DIR)) @@ -108,7 +108,7 @@ def test_quiet(self): self.assertTrue(ns.quiet) self.assertEqual(ns.verbose, 0) - def test_slow(self): + def test_slowest(self): for opt in '-o', '--slowest': with self.subTest(opt=opt): ns = libregrtest._parse_args([opt]) @@ -254,9 +254,7 @@ def test_multiprocess(self): self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo'], 'invalid int value') self.checkError([opt, '2', '-T'], "don't go together") - self.checkError([opt, '2', '-l'], "don't go together") self.checkError([opt, '0', '-T'], "don't go together") - self.checkError([opt, '0', '-l'], "don't go together") def test_coverage(self): for opt in '-T', '--coverage': @@ -453,8 +451,8 @@ def list_regex(line_format, tests): regex = list_regex('%s re-run test%s', rerun) self.check_line(output, regex) self.check_line(output, "Re-running failed tests in verbose mode") - for name in rerun: - regex = "Re-running test %r in verbose mode" % name + for test_name in rerun: + regex = f"Re-running {test_name} in verbose mode" self.check_line(output, regex) if no_test_ran: @@ -486,7 +484,7 @@ def list_regex(line_format, tests): result.append('SUCCESS') result = ', '.join(result) if rerun: - self.check_line(output, 'Tests result: %s' % result) + self.check_line(output, 'Tests result: FAILURE') result = 'FAILURE then %s' % result self.check_line(output, 'Tests result: %s' % result) @@ -780,22 +778,23 @@ def test_slowest(self): % (self.TESTNAME_REGEX, len(tests))) self.check_line(output, regex) - def test_slow_interrupted(self): + def test_slowest_interrupted(self): # Issue #25373: test --slowest with an interrupted test code = TEST_INTERRUPTED test = self.create_test("sigint", code=code) for multiprocessing in (False, True): - if multiprocessing: - args = ("--slowest", "-j2", test) - else: - args = ("--slowest", test) - output = self.run_tests(*args, exitcode=130) - self.check_executed_tests(output, test, - omitted=test, interrupted=True) + with self.subTest(multiprocessing=multiprocessing): + if multiprocessing: + args = ("--slowest", "-j2", test) + else: + args = ("--slowest", test) + output = self.run_tests(*args, exitcode=130) + self.check_executed_tests(output, test, + omitted=test, interrupted=True) - regex = ('10 slowest tests:\n') - self.check_line(output, regex) + regex = ('10 slowest tests:\n') + self.check_line(output, regex) def test_coverage(self): # test --coverage @@ -914,13 +913,13 @@ def test_method2(self): testname) self.assertEqual(output.splitlines(), all_methods) + @support.cpython_only def test_crashed(self): # Any code which causes a crash code = 'import faulthandler; faulthandler._sigsegv()' crash_test = self.create_test(name="crash", code=code) - ok_test = self.create_test(name="ok") - tests = [crash_test, ok_test] + tests = [crash_test] output = self.run_tests("-j2", *tests, exitcode=2) self.check_executed_tests(output, tests, failed=crash_test, randomize=True) @@ -990,6 +989,7 @@ def test_env_changed(self): fail_env_changed=True) def test_rerun_fail(self): + # FAILURE then FAILURE code = textwrap.dedent(""" import unittest @@ -1004,6 +1004,26 @@ def test_bug(self): self.check_executed_tests(output, [testname], failed=testname, rerun=testname) + def test_rerun_success(self): + # FAILURE then SUCCESS + code = textwrap.dedent(""" + import builtins + import unittest + + class Tests(unittest.TestCase): + failed = False + + def test_fail_once(self): + if not hasattr(builtins, '_test_failed'): + builtins._test_failed = True + self.fail("bug") + """) + testname = self.create_test(code=code) + + output = self.run_tests("-w", testname, exitcode=0) + self.check_executed_tests(output, [testname], + rerun=testname) + def test_no_tests_ran(self): code = textwrap.dedent(""" import unittest @@ -1068,6 +1088,38 @@ def test_other_bug(self): self.check_executed_tests(output, [testname, testname2], no_test_ran=[testname]) + @support.cpython_only + def test_findleaks(self): + code = textwrap.dedent(r""" + import _testcapi + import gc + import unittest + + @_testcapi.with_tp_del + class Garbage: + def __tp_del__(self): + pass + + class Tests(unittest.TestCase): + def test_garbage(self): + # create an uncollectable object + obj = Garbage() + obj.ref_cycle = obj + obj = None + """) + testname = self.create_test(code=code) + + output = self.run_tests("--fail-env-changed", testname, exitcode=3) + self.check_executed_tests(output, [testname], + env_changed=[testname], + fail_env_changed=True) + + # --findleaks is now basically an alias to --fail-env-changed + output = self.run_tests("--findleaks", testname, exitcode=3) + self.check_executed_tests(output, [testname], + env_changed=[testname], + fail_env_changed=True) + class TestUtils(unittest.TestCase): def test_format_duration(self): diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py index 62c7963fe69..e5ece5284cf 100644 --- a/Lib/test/test_resource.py +++ b/Lib/test/test_resource.py @@ -16,6 +16,8 @@ def test_args(self): self.assertRaises(TypeError, resource.setrlimit) self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42) + @unittest.skipIf(sys.platform == "vxworks", + "setting RLIMIT_FSIZE is not supported on VxWorks") def test_fsize_ismax(self): try: (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE) @@ -110,6 +112,8 @@ def test_getrusage(self): pass # Issue 6083: Reference counting bug + @unittest.skipIf(sys.platform == "vxworks", + "setting RLIMIT_CPU is not supported on VxWorks") def test_setrusage_refcount(self): try: limits = resource.getrlimit(resource.RLIMIT_CPU) diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index 9addc06f20d..da4eb1da3c6 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -21,7 +21,7 @@ import shutil from urllib.error import URLError from test import support -from test.support import findfile, run_unittest, TESTFN +from test.support import findfile, run_unittest, FakePath, TESTFN TEST_XMLFILE = findfile("test.xml", subdir="xmltestdata") TEST_XMLFILE_OUT = findfile("test.xml.out", subdir="xmltestdata") @@ -182,6 +182,10 @@ def test_parse_bytes(self): with self.assertRaises(SAXException): self.check_parse(f) + def test_parse_path_object(self): + make_xml_file(self.data, 'utf-8', None) + self.check_parse(FakePath(TESTFN)) + def test_parse_InputSource(self): # accept data without declared but with explicitly specified encoding make_xml_file(self.data, 'iso-8859-1', None) @@ -397,6 +401,13 @@ def test_string(self): self.checkContent(prep.getByteStream(), b"This was read from a file.") + def test_path_objects(self): + # If the source is a Path object, use it as a system ID and open it. + prep = prepare_input_source(FakePath(self.file)) + self.assertIsNone(prep.getCharacterStream()) + self.checkContent(prep.getByteStream(), + b"This was read from a file.") + def test_binary_file(self): # If the source is a binary file-like object, use it as a byte # stream. diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 678a190bcf5..e709a5661bf 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1619,6 +1619,57 @@ def test_environ_path(self): rv = shutil.which(self.file) self.assertEqual(rv, self.temp_file.name) + def test_environ_path_empty(self): + # PATH='': no match + with support.EnvironmentVarGuard() as env: + env['PATH'] = '' + with unittest.mock.patch('os.confstr', return_value=self.dir, \ + create=True), \ + support.swap_attr(os, 'defpath', self.dir), \ + support.change_cwd(self.dir): + rv = shutil.which(self.file) + self.assertIsNone(rv) + + def test_environ_path_cwd(self): + expected_cwd = os.path.basename(self.temp_file.name) + if sys.platform == "win32": + curdir = os.curdir + if isinstance(expected_cwd, bytes): + curdir = os.fsencode(curdir) + expected_cwd = os.path.join(curdir, expected_cwd) + + # PATH=':': explicitly looks in the current directory + with support.EnvironmentVarGuard() as env: + env['PATH'] = os.pathsep + with unittest.mock.patch('os.confstr', return_value=self.dir, \ + create=True), \ + support.swap_attr(os, 'defpath', self.dir): + rv = shutil.which(self.file) + self.assertIsNone(rv) + + # look in current directory + with support.change_cwd(self.dir): + rv = shutil.which(self.file) + self.assertEqual(rv, expected_cwd) + + def test_environ_path_missing(self): + with support.EnvironmentVarGuard() as env: + env.pop('PATH', None) + + # without confstr + with unittest.mock.patch('os.confstr', side_effect=ValueError, \ + create=True), \ + support.swap_attr(os, 'defpath', self.dir): + rv = shutil.which(self.file) + self.assertEqual(rv, self.temp_file.name) + + # with confstr + with unittest.mock.patch('os.confstr', return_value=self.dir, \ + create=True), \ + support.swap_attr(os, 'defpath', ''): + rv = shutil.which(self.file) + self.assertEqual(rv, self.temp_file.name) + def test_empty_path(self): base_dir = os.path.dirname(self.dir) with support.change_cwd(path=self.dir), \ @@ -1633,6 +1684,23 @@ def test_empty_path_no_PATH(self): rv = shutil.which(self.file) self.assertIsNone(rv) + @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') + def test_pathext(self): + ext = ".xyz" + temp_filexyz = tempfile.NamedTemporaryFile(dir=self.temp_dir, + prefix="Tmp2", suffix=ext) + os.chmod(temp_filexyz.name, stat.S_IXUSR) + self.addCleanup(temp_filexyz.close) + + # strip path and extension + program = os.path.basename(temp_filexyz.name) + program = os.path.splitext(program)[0] + + with support.EnvironmentVarGuard() as env: + env['PATHEXT'] = ext + rv = shutil.which(program, path=self.temp_dir) + self.assertEqual(rv, temp_filexyz.name) + class TestWhichBytes(TestWhich): def setUp(self): diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 8643da0540f..41c42299195 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -526,15 +526,15 @@ def test_startup_imports(self): # http://bugs.python.org/issue19205 re_mods = {'re', '_sre', 'sre_compile', 'sre_constants', 'sre_parse'} - # _osx_support uses the re module in many placs - if sys.platform != 'darwin': - self.assertFalse(modules.intersection(re_mods), stderr) + self.assertFalse(modules.intersection(re_mods), stderr) + # http://bugs.python.org/issue9548 self.assertNotIn('locale', modules, stderr) - if sys.platform != 'darwin': - # http://bugs.python.org/issue19209 - self.assertNotIn('copyreg', modules, stderr) - # http://bugs.python.org/issue19218> + + # http://bugs.python.org/issue19209 + self.assertNotIn('copyreg', modules, stderr) + + # http://bugs.python.org/issue19218 collection_mods = {'_collections', 'collections', 'functools', 'heapq', 'itertools', 'keyword', 'operator', 'reprlib', 'types', 'weakref' diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 08c7cdef73d..0094cecb79c 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -867,6 +867,8 @@ def testSendtoErrors(self): def testCrucialConstants(self): # Testing for mission critical constants socket.AF_INET + if socket.has_ipv6: + socket.AF_INET6 socket.SOCK_STREAM socket.SOCK_DGRAM socket.SOCK_RAW @@ -875,6 +877,23 @@ def testCrucialConstants(self): socket.SOL_SOCKET socket.SO_REUSEADDR + def testCrucialIpProtoConstants(self): + socket.IPPROTO_TCP + socket.IPPROTO_UDP + if socket.has_ipv6: + socket.IPPROTO_IPV6 + + @unittest.skipUnless(os.name == "nt", "Windows specific") + def testWindowsSpecificConstants(self): + socket.IPPROTO_ICLFXBM + socket.IPPROTO_ST + socket.IPPROTO_CBT + socket.IPPROTO_IGP + socket.IPPROTO_RDP + socket.IPPROTO_PGM + socket.IPPROTO_L2TP + socket.IPPROTO_SCTP + def testHostnameRes(self): # Testing hostname resolution mechanisms hostname = socket.gethostname() @@ -1777,8 +1796,13 @@ def test_socket_fileno(self): self.addCleanup(shutil.rmtree, tmpdir) s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.addCleanup(s.close) - s.bind(os.path.join(tmpdir, 'socket')) - self._test_socket_fileno(s, socket.AF_UNIX, socket.SOCK_STREAM) + try: + s.bind(os.path.join(tmpdir, 'socket')) + except PermissionError: + pass + else: + self._test_socket_fileno(s, socket.AF_UNIX, + socket.SOCK_STREAM) def test_socket_fileno_rejects_float(self): with self.assertRaisesRegex(TypeError, "integer argument expected"): @@ -4785,14 +4809,7 @@ def test_create_connection(self): # On Solaris, ENETUNREACH is returned in this circumstance instead # of ECONNREFUSED. So, if that errno exists, add it to our list of # expected errnos. - expected_errnos = [ errno.ECONNREFUSED, ] - if hasattr(errno, 'ENETUNREACH'): - expected_errnos.append(errno.ENETUNREACH) - if hasattr(errno, 'EADDRNOTAVAIL'): - # bpo-31910: socket.create_connection() fails randomly - # with EADDRNOTAVAIL on Travis CI - expected_errnos.append(errno.EADDRNOTAVAIL) - + expected_errnos = support.get_socket_conn_refused_errs() self.assertIn(cm.exception.errno, expected_errnos) def test_create_connection_timeout(self): @@ -6049,9 +6066,133 @@ def test_new_tcp_flags(self): self.assertEqual([], unknown, "New TCP flags were discovered. See bpo-32394 for more information") + +class CreateServerTest(unittest.TestCase): + + def test_address(self): + port = support.find_unused_port() + with socket.create_server(("127.0.0.1", port)) as sock: + self.assertEqual(sock.getsockname()[0], "127.0.0.1") + self.assertEqual(sock.getsockname()[1], port) + if support.IPV6_ENABLED: + with socket.create_server(("::1", port), + family=socket.AF_INET6) as sock: + self.assertEqual(sock.getsockname()[0], "::1") + self.assertEqual(sock.getsockname()[1], port) + + def test_family_and_type(self): + with socket.create_server(("127.0.0.1", 0)) as sock: + self.assertEqual(sock.family, socket.AF_INET) + self.assertEqual(sock.type, socket.SOCK_STREAM) + if support.IPV6_ENABLED: + with socket.create_server(("::1", 0), family=socket.AF_INET6) as s: + self.assertEqual(s.family, socket.AF_INET6) + self.assertEqual(sock.type, socket.SOCK_STREAM) + + def test_reuse_port(self): + if not hasattr(socket, "SO_REUSEPORT"): + with self.assertRaises(ValueError): + socket.create_server(("localhost", 0), reuse_port=True) + else: + with socket.create_server(("localhost", 0)) as sock: + opt = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) + self.assertEqual(opt, 0) + with socket.create_server(("localhost", 0), reuse_port=True) as sock: + opt = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) + self.assertNotEqual(opt, 0) + + @unittest.skipIf(not hasattr(_socket, 'IPPROTO_IPV6') or + not hasattr(_socket, 'IPV6_V6ONLY'), + "IPV6_V6ONLY option not supported") + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test') + def test_ipv6_only_default(self): + with socket.create_server(("::1", 0), family=socket.AF_INET6) as sock: + assert sock.getsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY) + + @unittest.skipIf(not socket.has_dualstack_ipv6(), + "dualstack_ipv6 not supported") + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test') + def test_dualstack_ipv6_family(self): + with socket.create_server(("::1", 0), family=socket.AF_INET6, + dualstack_ipv6=True) as sock: + self.assertEqual(sock.family, socket.AF_INET6) + + +class CreateServerFunctionalTest(unittest.TestCase): + timeout = 3 + + def setUp(self): + self.thread = None + + def tearDown(self): + if self.thread is not None: + self.thread.join(self.timeout) + + def echo_server(self, sock): + def run(sock): + with sock: + conn, _ = sock.accept() + with conn: + event.wait(self.timeout) + msg = conn.recv(1024) + if not msg: + return + conn.sendall(msg) + + event = threading.Event() + sock.settimeout(self.timeout) + self.thread = threading.Thread(target=run, args=(sock, )) + self.thread.start() + event.set() + + def echo_client(self, addr, family): + with socket.socket(family=family) as sock: + sock.settimeout(self.timeout) + sock.connect(addr) + sock.sendall(b'foo') + self.assertEqual(sock.recv(1024), b'foo') + + def test_tcp4(self): + port = support.find_unused_port() + with socket.create_server(("", port)) as sock: + self.echo_server(sock) + self.echo_client(("127.0.0.1", port), socket.AF_INET) + + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test') + def test_tcp6(self): + port = support.find_unused_port() + with socket.create_server(("", port), + family=socket.AF_INET6) as sock: + self.echo_server(sock) + self.echo_client(("::1", port), socket.AF_INET6) + + # --- dual stack tests + + @unittest.skipIf(not socket.has_dualstack_ipv6(), + "dualstack_ipv6 not supported") + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test') + def test_dual_stack_client_v4(self): + port = support.find_unused_port() + with socket.create_server(("", port), family=socket.AF_INET6, + dualstack_ipv6=True) as sock: + self.echo_server(sock) + self.echo_client(("127.0.0.1", port), socket.AF_INET) + + @unittest.skipIf(not socket.has_dualstack_ipv6(), + "dualstack_ipv6 not supported") + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test') + def test_dual_stack_client_v6(self): + port = support.find_unused_port() + with socket.create_server(("", port), family=socket.AF_INET6, + dualstack_ipv6=True) as sock: + self.echo_server(sock) + self.echo_client(("::1", port), socket.AF_INET6) + + def test_main(): tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest, - TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, UDPTimeoutTest ] + TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, + UDPTimeoutTest, CreateServerTest, CreateServerFunctionalTest] tests.extend([ NonBlockingTCPTests, diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 55718220d88..5b53b8250f6 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -765,9 +765,7 @@ def test_server_side(self): def test_unknown_channel_binding(self): # should raise ValueError for unknown type - s = socket.socket(socket.AF_INET) - s.bind(('127.0.0.1', 0)) - s.listen() + s = socket.create_server(('127.0.0.1', 0)) c = socket.socket(socket.AF_INET) c.connect(s.getsockname()) with test_wrap_socket(c, do_handshake_on_connect=False) as ss: @@ -1663,11 +1661,8 @@ def test_subclass(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - with socket.socket() as s: - s.bind(("127.0.0.1", 0)) - s.listen() - c = socket.socket() - c.connect(s.getsockname()) + with socket.create_server(("127.0.0.1", 0)) as s: + c = socket.create_connection(s.getsockname()) c.setblocking(False) with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c: with self.assertRaises(ssl.SSLWantReadError) as cm: @@ -4337,7 +4332,7 @@ def test_pha_optional_nocert(self): self.assertEqual(s.recv(1024), b'FALSE\n') s.write(b'PHA') self.assertEqual(s.recv(1024), b'OK\n') - # optional doens't fail when client does not have a cert + # optional doesn't fail when client does not have a cert s.write(b'HASCERT') self.assertEqual(s.recv(1024), b'FALSE\n') diff --git a/Lib/test/test_startfile.py b/Lib/test/test_startfile.py index f59252e97ad..1a26a8025e6 100644 --- a/Lib/test/test_startfile.py +++ b/Lib/test/test_startfile.py @@ -10,6 +10,7 @@ import unittest from test import support import os +import platform import sys from os import path @@ -20,6 +21,7 @@ class TestCase(unittest.TestCase): def test_nonexisting(self): self.assertRaises(OSError, startfile, "nonexisting.vbs") + @unittest.skipIf(platform.win32_is_iot(), "starting files is not supported on Windows IoT Core or nanoserver") def test_empty(self): # We need to make sure the child process starts in a directory # we're not about to delete. If we're running under -j, that diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 38ff2bcf8a6..17443bed073 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -2,7 +2,8 @@ import os import socket import sys -from test.support import TESTFN, import_fresh_module +from test.support import (TESTFN, import_fresh_module, + skip_unless_bind_unix_socket) c_stat = import_fresh_module('stat', fresh=['_stat']) py_stat = import_fresh_module('stat', blocked=['_stat']) @@ -192,7 +193,7 @@ def test_devices(self): self.assertS_IS("BLK", st_mode) break - @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'requires unix socket') + @skip_unless_bind_unix_socket def test_socket(self): with socket.socket(socket.AF_UNIX) as s: s.bind(TESTFN) diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 485ffe24036..1922de5df4b 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -3,6 +3,7 @@ """ +import bisect import collections import collections.abc import copy @@ -2038,6 +2039,264 @@ def test_compare_to_variance(self): expected = math.sqrt(statistics.variance(data)) self.assertEqual(self.func(data), expected) + +class TestGeometricMean(unittest.TestCase): + + def test_basics(self): + geometric_mean = statistics.geometric_mean + self.assertAlmostEqual(geometric_mean([54, 24, 36]), 36.0) + self.assertAlmostEqual(geometric_mean([4.0, 9.0]), 6.0) + self.assertAlmostEqual(geometric_mean([17.625]), 17.625) + + random.seed(86753095551212) + for rng in [ + range(1, 100), + range(1, 1_000), + range(1, 10_000), + range(500, 10_000, 3), + range(10_000, 500, -3), + [12, 17, 13, 5, 120, 7], + [random.expovariate(50.0) for i in range(1_000)], + [random.lognormvariate(20.0, 3.0) for i in range(2_000)], + [random.triangular(2000, 3000, 2200) for i in range(3_000)], + ]: + gm_decimal = math.prod(map(Decimal, rng)) ** (Decimal(1) / len(rng)) + gm_float = geometric_mean(rng) + self.assertTrue(math.isclose(gm_float, float(gm_decimal))) + + def test_various_input_types(self): + geometric_mean = statistics.geometric_mean + D = Decimal + F = Fraction + # https://www.wolframalpha.com/input/?i=geometric+mean+3.5,+4.0,+5.25 + expected_mean = 4.18886 + for data, kind in [ + ([3.5, 4.0, 5.25], 'floats'), + ([D('3.5'), D('4.0'), D('5.25')], 'decimals'), + ([F(7, 2), F(4, 1), F(21, 4)], 'fractions'), + ([3.5, 4, F(21, 4)], 'mixed types'), + ((3.5, 4.0, 5.25), 'tuple'), + (iter([3.5, 4.0, 5.25]), 'iterator'), + ]: + actual_mean = geometric_mean(data) + self.assertIs(type(actual_mean), float, kind) + self.assertAlmostEqual(actual_mean, expected_mean, places=5) + + def test_big_and_small(self): + geometric_mean = statistics.geometric_mean + + # Avoid overflow to infinity + large = 2.0 ** 1000 + big_gm = geometric_mean([54.0 * large, 24.0 * large, 36.0 * large]) + self.assertTrue(math.isclose(big_gm, 36.0 * large)) + self.assertFalse(math.isinf(big_gm)) + + # Avoid underflow to zero + small = 2.0 ** -1000 + small_gm = geometric_mean([54.0 * small, 24.0 * small, 36.0 * small]) + self.assertTrue(math.isclose(small_gm, 36.0 * small)) + self.assertNotEqual(small_gm, 0.0) + + def test_error_cases(self): + geometric_mean = statistics.geometric_mean + StatisticsError = statistics.StatisticsError + with self.assertRaises(StatisticsError): + geometric_mean([]) # empty input + with self.assertRaises(StatisticsError): + geometric_mean([3.5, 0.0, 5.25]) # zero input + with self.assertRaises(StatisticsError): + geometric_mean([3.5, -4.0, 5.25]) # negative input + with self.assertRaises(StatisticsError): + geometric_mean(iter([])) # empty iterator + with self.assertRaises(TypeError): + geometric_mean(None) # non-iterable input + with self.assertRaises(TypeError): + geometric_mean([10, None, 20]) # non-numeric input + with self.assertRaises(TypeError): + geometric_mean() # missing data argument + with self.assertRaises(TypeError): + geometric_mean([10, 20, 60], 70) # too many arguments + + def test_special_values(self): + # Rules for special values are inherited from math.fsum() + geometric_mean = statistics.geometric_mean + NaN = float('Nan') + Inf = float('Inf') + self.assertTrue(math.isnan(geometric_mean([10, NaN])), 'nan') + self.assertTrue(math.isnan(geometric_mean([NaN, Inf])), 'nan and infinity') + self.assertTrue(math.isinf(geometric_mean([10, Inf])), 'infinity') + with self.assertRaises(ValueError): + geometric_mean([Inf, -Inf]) + + +class TestQuantiles(unittest.TestCase): + + def test_specific_cases(self): + # Match results computed by hand and cross-checked + # against the PERCENTILE.EXC function in MS Excel. + quantiles = statistics.quantiles + data = [120, 200, 250, 320, 350] + random.shuffle(data) + for n, expected in [ + (1, []), + (2, [250.0]), + (3, [200.0, 320.0]), + (4, [160.0, 250.0, 335.0]), + (5, [136.0, 220.0, 292.0, 344.0]), + (6, [120.0, 200.0, 250.0, 320.0, 350.0]), + (8, [100.0, 160.0, 212.5, 250.0, 302.5, 335.0, 357.5]), + (10, [88.0, 136.0, 184.0, 220.0, 250.0, 292.0, 326.0, 344.0, 362.0]), + (12, [80.0, 120.0, 160.0, 200.0, 225.0, 250.0, 285.0, 320.0, 335.0, + 350.0, 365.0]), + (15, [72.0, 104.0, 136.0, 168.0, 200.0, 220.0, 240.0, 264.0, 292.0, + 320.0, 332.0, 344.0, 356.0, 368.0]), + ]: + self.assertEqual(expected, quantiles(data, n=n)) + self.assertEqual(len(quantiles(data, n=n)), n - 1) + # Preserve datatype when possible + for datatype in (float, Decimal, Fraction): + result = quantiles(map(datatype, data), n=n) + self.assertTrue(all(type(x) == datatype) for x in result) + self.assertEqual(result, list(map(datatype, expected))) + # Quantiles should be idempotent + if len(expected) >= 2: + self.assertEqual(quantiles(expected, n=n), expected) + # Cross-check against other methods + if len(data) >= n: + # After end caps are added, method='inclusive' should + # give the same result as method='exclusive' whenever + # there are more data points than desired cut points. + padded_data = [min(data) - 1000] + data + [max(data) + 1000] + self.assertEqual( + quantiles(data, n=n), + quantiles(padded_data, n=n, method='inclusive'), + (n, data), + ) + # Invariant under tranlation and scaling + def f(x): + return 3.5 * x - 1234.675 + exp = list(map(f, expected)) + act = quantiles(map(f, data), n=n) + self.assertTrue(all(math.isclose(e, a) for e, a in zip(exp, act))) + # Quartiles of a standard normal distribution + for n, expected in [ + (1, []), + (2, [0.0]), + (3, [-0.4307, 0.4307]), + (4 ,[-0.6745, 0.0, 0.6745]), + ]: + actual = quantiles(statistics.NormalDist(), n=n) + self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) + for e, a in zip(expected, actual))) + + def test_specific_cases_inclusive(self): + # Match results computed by hand and cross-checked + # against the PERCENTILE.INC function in MS Excel + # and against the quantile() function in SciPy. + quantiles = statistics.quantiles + data = [100, 200, 400, 800] + random.shuffle(data) + for n, expected in [ + (1, []), + (2, [300.0]), + (3, [200.0, 400.0]), + (4, [175.0, 300.0, 500.0]), + (5, [160.0, 240.0, 360.0, 560.0]), + (6, [150.0, 200.0, 300.0, 400.0, 600.0]), + (8, [137.5, 175, 225.0, 300.0, 375.0, 500.0,650.0]), + (10, [130.0, 160.0, 190.0, 240.0, 300.0, 360.0, 440.0, 560.0, 680.0]), + (12, [125.0, 150.0, 175.0, 200.0, 250.0, 300.0, 350.0, 400.0, + 500.0, 600.0, 700.0]), + (15, [120.0, 140.0, 160.0, 180.0, 200.0, 240.0, 280.0, 320.0, 360.0, + 400.0, 480.0, 560.0, 640.0, 720.0]), + ]: + self.assertEqual(expected, quantiles(data, n=n, method="inclusive")) + self.assertEqual(len(quantiles(data, n=n, method="inclusive")), n - 1) + # Preserve datatype when possible + for datatype in (float, Decimal, Fraction): + result = quantiles(map(datatype, data), n=n, method="inclusive") + self.assertTrue(all(type(x) == datatype) for x in result) + self.assertEqual(result, list(map(datatype, expected))) + # Invariant under tranlation and scaling + def f(x): + return 3.5 * x - 1234.675 + exp = list(map(f, expected)) + act = quantiles(map(f, data), n=n, method="inclusive") + self.assertTrue(all(math.isclose(e, a) for e, a in zip(exp, act))) + # Quartiles of a standard normal distribution + for n, expected in [ + (1, []), + (2, [0.0]), + (3, [-0.4307, 0.4307]), + (4 ,[-0.6745, 0.0, 0.6745]), + ]: + actual = quantiles(statistics.NormalDist(), n=n, method="inclusive") + self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) + for e, a in zip(expected, actual))) + # Whenever n is smaller than the number of data points, running + # method='inclusive' should give the same result as method='exclusive' + # after the two included extreme points are removed. + data = [random.randrange(10_000) for i in range(501)] + actual = quantiles(data, n=32, method='inclusive') + data.remove(min(data)) + data.remove(max(data)) + expected = quantiles(data, n=32) + self.assertEqual(expected, actual) + + def test_equal_inputs(self): + quantiles = statistics.quantiles + for n in range(2, 10): + data = [10.0] * n + self.assertEqual(quantiles(data), [10.0, 10.0, 10.0]) + self.assertEqual(quantiles(data, method='inclusive'), + [10.0, 10.0, 10.0]) + + def test_equal_sized_groups(self): + quantiles = statistics.quantiles + total = 10_000 + data = [random.expovariate(0.2) for i in range(total)] + while len(set(data)) != total: + data.append(random.expovariate(0.2)) + data.sort() + + # Cases where the group size exactly divides the total + for n in (1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000): + group_size = total // n + self.assertEqual( + [bisect.bisect(data, q) for q in quantiles(data, n=n)], + list(range(group_size, total, group_size))) + + # When the group sizes can't be exactly equal, they should + # differ by no more than one + for n in (13, 19, 59, 109, 211, 571, 1019, 1907, 5261, 9769): + group_sizes = {total // n, total // n + 1} + pos = [bisect.bisect(data, q) for q in quantiles(data, n=n)] + sizes = {q - p for p, q in zip(pos, pos[1:])} + self.assertTrue(sizes <= group_sizes) + + def test_error_cases(self): + quantiles = statistics.quantiles + StatisticsError = statistics.StatisticsError + with self.assertRaises(TypeError): + quantiles() # Missing arguments + with self.assertRaises(TypeError): + quantiles([10, 20, 30], 13, n=4) # Too many arguments + with self.assertRaises(TypeError): + quantiles([10, 20, 30], 4) # n is a positional argument + with self.assertRaises(StatisticsError): + quantiles([10, 20, 30], n=0) # n is zero + with self.assertRaises(StatisticsError): + quantiles([10, 20, 30], n=-1) # n is negative + with self.assertRaises(TypeError): + quantiles([10, 20, 30], n=1.5) # n is not an integer + with self.assertRaises(ValueError): + quantiles([10, 20, 30], method='X') # method is unknown + with self.assertRaises(StatisticsError): + quantiles([10], n=4) # not enough data points + with self.assertRaises(TypeError): + quantiles([10, None, 30], n=4) # data is non-numeric + + class TestNormalDist(unittest.TestCase): # General note on precision: The pdf(), cdf(), and overlap() methods @@ -2051,7 +2310,7 @@ def test_slots(self): nd = statistics.NormalDist(300, 23) with self.assertRaises(TypeError): vars(nd) - self.assertEqual(nd.__slots__, ('mu', 'sigma')) + self.assertEqual(tuple(nd.__slots__), ('mu', 'sigma')) def test_instantiation_and_attributes(self): nd = statistics.NormalDist(500, 17) diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 6e36a6123da..2accad1aeeb 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -1,5 +1,6 @@ """Do a minimal test of all the modules that aren't otherwise tested.""" import importlib +import platform import sys from test import support import unittest @@ -25,7 +26,7 @@ def test_untested_modules_can_be_imported(self): import distutils.unixccompiler import distutils.command.bdist_dumb - if sys.platform.startswith('win'): + if sys.platform.startswith('win') and not platform.win32_is_iot(): import distutils.command.bdist_msi import distutils.command.bdist import distutils.command.bdist_rpm diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 4a8f3c58187..cb664bab171 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -91,14 +91,12 @@ def test_forget(self): support.rmtree('__pycache__') def test_HOST(self): - s = socket.socket() - s.bind((support.HOST, 0)) + s = socket.create_server((support.HOST, 0)) s.close() def test_find_unused_port(self): port = support.find_unused_port() - s = socket.socket() - s.bind((support.HOST, port)) + s = socket.create_server((support.HOST, port)) s.close() def test_bind_port(self): diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 4bd54af3629..d1c7daad7bb 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -767,8 +767,13 @@ def test_getallocatedblocks(self): except ImportError: with_pymalloc = support.with_pymalloc() else: - alloc_name = _testcapi.pymem_getallocatorsname() - with_pymalloc = (alloc_name in ('pymalloc', 'pymalloc_debug')) + try: + alloc_name = _testcapi.pymem_getallocatorsname() + except RuntimeError as exc: + # "cannot get allocators name" (ex: tracemalloc is used) + with_pymalloc = True + else: + with_pymalloc = (alloc_name in ('pymalloc', 'pymalloc_debug')) # Some sanity checks a = sys.getallocatedblocks() diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index c2ecf8eeed9..b64bcbc5b68 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -351,7 +351,7 @@ def f(p): (1, 'return', f_ident)]) # Test an invalid call (bpo-34125) - def test_unbound_method_no_args(self): + def test_unbound_method_no_keyword_args(self): kwargs = {} def f(p): dict.get(**kwargs) @@ -360,7 +360,7 @@ def f(p): (1, 'return', f_ident)]) # Test an invalid call (bpo-34125) - def test_unbound_method_invalid_args(self): + def test_unbound_method_invalid_keyword_args(self): kwargs = {} def f(p): dict.get(print, 42, **kwargs) diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 845096e63c2..81549d14ae2 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -6,6 +6,8 @@ from unittest import TestCase, mock from unittest import mock import errno +import os +import sys import tabnanny import tokenize import tempfile @@ -233,8 +235,8 @@ def test_when_nannynag_error(self): def test_when_no_file(self): """A python file which does not exist actually in system.""" path = 'no_file.py' - err = f"{path!r}: I/O Error: [Errno {errno.ENOENT}] " \ - f"No such file or directory: {path!r}\n" + err = (f"{path!r}: I/O Error: [Errno {errno.ENOENT}] " + f"{os.strerror(errno.ENOENT)}: {path!r}\n") self.verify_tabnanny_check(path, err=err) def test_errored_directory(self): diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 136ad29e20a..42799b2a21c 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -88,6 +88,8 @@ def check_ns(sec, ns): check_ns(time.clock_gettime(time.CLOCK_REALTIME), time.clock_gettime_ns(time.CLOCK_REALTIME)) + @unittest.skipUnless(hasattr(time, 'clock'), + 'need time.clock()') def test_clock(self): with self.assertWarns(DeprecationWarning): time.clock() @@ -468,8 +470,9 @@ def test_monotonic(self): t2 = time.monotonic() dt = t2 - t1 self.assertGreater(t2, t1) - # Issue #20101: On some Windows machines, dt may be slightly low - self.assertTrue(0.45 <= dt <= 1.0, dt) + # bpo-20101: tolerate a difference of 50 ms because of bad timer + # resolution on Windows + self.assertTrue(0.450 <= dt) # monotonic() is a monotonic but non adjustable clock info = time.get_clock_info('monotonic') @@ -549,7 +552,9 @@ def test_localtime_failure(self): self.assertRaises(ValueError, time.ctime, float("nan")) def test_get_clock_info(self): - clocks = ['clock', 'monotonic', 'perf_counter', 'process_time', 'time'] + clocks = ['monotonic', 'perf_counter', 'process_time', 'time'] + if hasattr(time, 'clock'): + clocks.append('clock') for name in clocks: if name == 'clock': diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index 8b2b90d6142..42e20f8f771 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -211,7 +211,7 @@ def foo3(bar: 'func'=lambda x: x) -> {1: 2}: self.assertIn('doc3', msgids) def test_classdocstring_early_colon(self): - """ Test docstring extraction for a class with colons occuring within + """ Test docstring extraction for a class with colons occurring within the parentheses. """ msgids = self.extract_docstrings_from_str(dedent('''\ diff --git a/Lib/test/test_tools/test_lll.py b/Lib/test/test_tools/test_lll.py new file mode 100644 index 00000000000..f3fbe961eee --- /dev/null +++ b/Lib/test/test_tools/test_lll.py @@ -0,0 +1,39 @@ +"""Tests for the lll script in the Tools/script directory.""" + +import os +import tempfile +from test import support +from test.test_tools import skip_if_missing, import_tool +import unittest + +skip_if_missing() + + +class lllTests(unittest.TestCase): + + def setUp(self): + self.lll = import_tool('lll') + + @support.skip_unless_symlink + def test_lll_multiple_dirs(self): + with tempfile.TemporaryDirectory() as dir1, \ + tempfile.TemporaryDirectory() as dir2: + fn1 = os.path.join(dir1, 'foo1') + fn2 = os.path.join(dir2, 'foo2') + for fn, dir in (fn1, dir1), (fn2, dir2): + open(fn, 'w').close() + os.symlink(fn, os.path.join(dir, 'symlink')) + + with support.captured_stdout() as output: + self.lll.main([dir1, dir2]) + self.assertEqual(output.getvalue(), + f'{dir1}:\n' + f'symlink -> {fn1}\n' + f'\n' + f'{dir2}:\n' + f'symlink -> {fn2}\n' + ) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index 5c333b7a0a5..afe79026766 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -70,6 +70,9 @@ def traced_func_calling_generator(): def traced_doubler(num): return num * 2 +def traced_capturer(*args, **kwargs): + return args, kwargs + def traced_caller_list_comprehension(): k = 10 mylist = [traced_doubler(i) for i in range(k)] @@ -270,6 +273,15 @@ def test_simple_caller(self): } self.assertEqual(self.tracer.results().calledfuncs, expected) + def test_arg_errors(self): + res = self.tracer.runfunc(traced_capturer, 1, 2, self=3, func=4) + self.assertEqual(res, ((1, 2), {'self': 3, 'func': 4})) + with self.assertWarns(DeprecationWarning): + res = self.tracer.runfunc(func=traced_capturer, arg=1) + self.assertEqual(res, ((), {'arg': 1})) + with self.assertRaises(TypeError): + self.tracer.runfunc() + def test_loop_caller_importing(self): self.tracer.runfunc(traced_func_importing_caller, 1) diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index cac6e8b25d2..69a48a10403 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -101,7 +101,7 @@ def fab( def fab( a, # type: A - b # type: B + b # type: B ): pass diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 1131efdd26a..36b72e40c7e 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -811,7 +811,7 @@ def test_capitalize(self): self.assertEqual('h\u0130'.capitalize(), 'H\u0069\u0307') exp = '\u0399\u0308\u0300\u0069\u0307' self.assertEqual('\u1fd2\u0130'.capitalize(), exp) - self.assertEqual('finnish'.capitalize(), 'FInnish') + self.assertEqual('finnish'.capitalize(), 'Finnish') self.assertEqual('A\u0345\u03a3'.capitalize(), 'A\u0345\u03c2') def test_title(self): diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 2ac73b58d83..7214492eca9 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -329,6 +329,59 @@ def test_willclose(self): finally: self.unfakehttp() + @unittest.skipUnless(ssl, "ssl module required") + def test_url_with_control_char_rejected(self): + for char_no in list(range(0, 0x21)) + [0x7f]: + char = chr(char_no) + schemeless_url = f"//localhost:7777/test{char}/" + self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") + try: + # We explicitly test urllib.request.urlopen() instead of the top + # level 'def urlopen()' function defined in this... (quite ugly) + # test suite. They use different url opening codepaths. Plain + # urlopen uses FancyURLOpener which goes via a codepath that + # calls urllib.parse.quote() on the URL which makes all of the + # above attempts at injection within the url _path_ safe. + escaped_char_repr = repr(char).replace('\\', r'\\') + InvalidURL = http.client.InvalidURL + with self.assertRaisesRegex( + InvalidURL, f"contain control.*{escaped_char_repr}"): + urllib.request.urlopen(f"http:{schemeless_url}") + with self.assertRaisesRegex( + InvalidURL, f"contain control.*{escaped_char_repr}"): + urllib.request.urlopen(f"https:{schemeless_url}") + # This code path quotes the URL so there is no injection. + resp = urlopen(f"http:{schemeless_url}") + self.assertNotIn(char, resp.geturl()) + finally: + self.unfakehttp() + + @unittest.skipUnless(ssl, "ssl module required") + def test_url_with_newline_header_injection_rejected(self): + self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") + host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" + schemeless_url = "//" + host + ":8080/test/?test=a" + try: + # We explicitly test urllib.request.urlopen() instead of the top + # level 'def urlopen()' function defined in this... (quite ugly) + # test suite. They use different url opening codepaths. Plain + # urlopen uses FancyURLOpener which goes via a codepath that + # calls urllib.parse.quote() on the URL which makes all of the + # above attempts at injection within the url _path_ safe. + InvalidURL = http.client.InvalidURL + with self.assertRaisesRegex( + InvalidURL, r"contain control.*\\r.*(found at least . .)"): + urllib.request.urlopen(f"http:{schemeless_url}") + with self.assertRaisesRegex(InvalidURL, r"contain control.*\\n"): + urllib.request.urlopen(f"https:{schemeless_url}") + # This code path quotes the URL so there is no injection. + resp = urlopen(f"http:{schemeless_url}") + self.assertNotIn(' ', resp.geturl()) + self.assertNotIn('\r', resp.geturl()) + self.assertNotIn('\n', resp.geturl()) + finally: + self.unfakehttp() + def test_read_0_9(self): # "0.9" response accepted (but not "simple responses" without # a status line) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 0faf2bbb645..d0365ecab72 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1011,6 +1011,12 @@ def test_urlsplit_normalization(self): self.assertIn('\u2100', denorm_chars) self.assertIn('\uFF03', denorm_chars) + # bpo-36742: Verify port separators are ignored when they + # existed prior to decomposition + urllib.parse.urlsplit('http://\u30d5\u309a:80') + with self.assertRaises(ValueError): + urllib.parse.urlsplit('http://\u30d5\u309a\ufe1380') + for scheme in ["http", "https", "ftp"]: for c in denorm_chars: url = "{}://netloc{}false.netloc/path".format(scheme, c) diff --git a/Lib/test/test_userlist.py b/Lib/test/test_userlist.py index 8de6c14e392..1ed67dac805 100644 --- a/Lib/test/test_userlist.py +++ b/Lib/test/test_userlist.py @@ -17,6 +17,12 @@ def test_getslice(self): for j in range(-3, 6): self.assertEqual(u[i:j], l[i:j]) + def test_slice_type(self): + l = [0, 1, 2, 3, 4] + u = UserList(l) + self.assertIsInstance(u[:], u.__class__) + self.assertEqual(u[:],u) + def test_add_specials(self): u = UserList("spam") u2 = u + "eggs" diff --git a/Lib/test/test_utf8_mode.py b/Lib/test/test_utf8_mode.py index 220ff34a118..bdb93457cfc 100644 --- a/Lib/test/test_utf8_mode.py +++ b/Lib/test/test_utf8_mode.py @@ -12,7 +12,7 @@ MS_WINDOWS = (sys.platform == 'win32') POSIX_LOCALES = ('C', 'POSIX') - +VXWORKS = (sys.platform == "vxworks") class UTF8ModeTests(unittest.TestCase): DEFAULT_ENV = { @@ -195,7 +195,7 @@ def check_io_encoding(self, module): def test_io_encoding(self): self.check_io_encoding('io') - def test_io_encoding(self): + def test_pyio_encoding(self): self.check_io_encoding('_pyio') def test_locale_getpreferredencoding(self): @@ -225,7 +225,7 @@ def check(utf8_opt, expected, **kw): with self.subTest(LC_ALL=loc): check('utf8', [arg_utf8], LC_ALL=loc) - if sys.platform == 'darwin' or support.is_android: + if sys.platform == 'darwin' or support.is_android or VXWORKS: c_arg = arg_utf8 elif sys.platform.startswith("aix"): c_arg = arg.decode('iso-8859-1') diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 1fac08dafc7..6f15c03ac52 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -285,6 +285,21 @@ def __ifloordiv__(self, other): p //= 5 self.assertEqual(p, 21) + def test_proxy_matmul(self): + class C: + def __matmul__(self, other): + return 1729 + def __rmatmul__(self, other): + return -163 + def __imatmul__(self, other): + return 561 + o = C() + p = weakref.proxy(o) + self.assertEqual(p @ 5, 1729) + self.assertEqual(5 @ p, -163) + p @= 5 + self.assertEqual(p, 561) + # The PyWeakref_* C API is documented as allowing either NULL or # None as the value for the callback, where either means "no # callback". The "no callback" ref and proxy objects are supposed @@ -1839,6 +1854,35 @@ def add(x,y,z): self.assertEqual(f.alive, False) self.assertEqual(res, [199]) + def test_arg_errors(self): + def fin(*args, **kwargs): + res.append((args, kwargs)) + + a = self.A() + + res = [] + f = weakref.finalize(a, fin, 1, 2, func=3, obj=4) + self.assertEqual(f.peek(), (a, fin, (1, 2), {'func': 3, 'obj': 4})) + f() + self.assertEqual(res, [((1, 2), {'func': 3, 'obj': 4})]) + + res = [] + with self.assertWarns(DeprecationWarning): + f = weakref.finalize(a, func=fin, arg=1) + self.assertEqual(f.peek(), (a, fin, (), {'arg': 1})) + f() + self.assertEqual(res, [((), {'arg': 1})]) + + res = [] + with self.assertWarns(DeprecationWarning): + f = weakref.finalize(obj=a, func=fin, arg=1) + self.assertEqual(f.peek(), (a, fin, (), {'arg': 1})) + f() + self.assertEqual(res, [((), {'arg': 1})]) + + self.assertRaises(TypeError, weakref.finalize, a) + self.assertRaises(TypeError, weakref.finalize) + def test_order(self): a = self.A() res = [] diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 11d054e16cd..dc2b46e4252 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -5,7 +5,7 @@ import unittest from test import support import threading -from platform import machine +from platform import machine, win32_edition # Do this first so test will be skipped if module doesn't exist support.import_module('winreg', required_on=['win']) @@ -399,6 +399,7 @@ def test_named_arguments(self): DeleteKeyEx(key=HKEY_CURRENT_USER, sub_key=test_key_name, access=KEY_ALL_ACCESS, reserved=0) + @unittest.skipIf(win32_edition() in ('WindowsCoreHeadless', 'IoTEdgeOS'), "APIs not available on WindowsCoreHeadless") def test_reflection_functions(self): # Test that we can call the query, enable, and disable functions # on a key which isn't on the reflection list with no consequences. diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 737dfed3a51..46f88a94434 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -788,6 +788,24 @@ def flush(self): b"Hello, world!", written) + def testClientConnectionTerminations(self): + environ = {"SERVER_PROTOCOL": "HTTP/1.0"} + for exception in ( + ConnectionAbortedError, + BrokenPipeError, + ConnectionResetError, + ): + with self.subTest(exception=exception): + class AbortingWriter: + def write(self, b): + raise exception + + stderr = StringIO() + h = SimpleHandler(BytesIO(), AbortingWriter(), stderr, environ) + h.run(hello_app) + + self.assertFalse(stderr.getvalue()) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 8a7ec0076ff..ca6862cae44 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -9,15 +9,20 @@ import functools import html import io +import itertools +import locale import operator +import os import pickle import sys +import textwrap import types import unittest import warnings import weakref -from itertools import product +from functools import partial +from itertools import product, islice from test import support from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr @@ -692,12 +697,17 @@ def pi(self, target, data): self.append(("pi", target, data)) def comment(self, data): self.append(("comment", data)) + def start_ns(self, prefix, uri): + self.append(("start-ns", prefix, uri)) + def end_ns(self, prefix): + self.append(("end-ns", prefix)) builder = Builder() parser = ET.XMLParser(target=builder) parser.feed(data) self.assertEqual(builder, [ ('pi', 'pi', 'data'), ('comment', ' comment '), + ('start-ns', '', 'namespace'), ('start', '{namespace}root'), ('start', '{namespace}element'), ('end', '{namespace}element'), @@ -706,8 +716,30 @@ def comment(self, data): ('start', '{namespace}empty-element'), ('end', '{namespace}empty-element'), ('end', '{namespace}root'), + ('end-ns', ''), ]) + def test_custom_builder_only_end_ns(self): + class Builder(list): + def end_ns(self, prefix): + self.append(("end-ns", prefix)) + + builder = Builder() + parser = ET.XMLParser(target=builder) + parser.feed(textwrap.dedent("""\ + + + + text + texttail + + + """)) + self.assertEqual(builder, [ + ('end-ns', 'a'), + ('end-ns', 'p'), + ('end-ns', ''), + ]) # Element.getchildren() and ElementTree.getiterator() are deprecated. @checkwarnings(("This method will be removed in future versions. " @@ -756,6 +788,128 @@ def test_writestring(self): elem = ET.fromstring("text") self.assertEqual(ET.tostring(elem), b'text') + def test_tostring_default_namespace(self): + elem = ET.XML('') + self.assertEqual( + ET.tostring(elem, encoding='unicode'), + '' + ) + self.assertEqual( + ET.tostring(elem, encoding='unicode', default_namespace='http://effbot.org/ns'), + '' + ) + + def test_tostring_default_namespace_different_namespace(self): + elem = ET.XML('') + self.assertEqual( + ET.tostring(elem, encoding='unicode', default_namespace='foobar'), + '' + ) + + def test_tostring_default_namespace_original_no_namespace(self): + elem = ET.XML('') + EXPECTED_MSG = '^cannot use non-qualified names with default_namespace option$' + with self.assertRaisesRegex(ValueError, EXPECTED_MSG): + ET.tostring(elem, encoding='unicode', default_namespace='foobar') + + def test_tostring_no_xml_declaration(self): + elem = ET.XML('') + self.assertEqual( + ET.tostring(elem, encoding='unicode'), + '' + ) + + def test_tostring_xml_declaration(self): + elem = ET.XML('') + self.assertEqual( + ET.tostring(elem, encoding='utf8', xml_declaration=True), + b"\n" + ) + + def test_tostring_xml_declaration_unicode_encoding(self): + elem = ET.XML('') + preferredencoding = locale.getpreferredencoding() + self.assertEqual( + f"\n", + ET.tostring(elem, encoding='unicode', xml_declaration=True) + ) + + def test_tostring_xml_declaration_cases(self): + elem = ET.XML('ø') + preferredencoding = locale.getpreferredencoding() + TESTCASES = [ + # (expected_retval, encoding, xml_declaration) + # ... xml_declaration = None + (b'ø', None, None), + (b'\xc3\xb8', 'UTF-8', None), + (b'ø', 'US-ASCII', None), + (b"\n" + b"\xf8", 'ISO-8859-1', None), + ('ø', 'unicode', None), + + # ... xml_declaration = False + (b"ø", None, False), + (b"\xc3\xb8", 'UTF-8', False), + (b"ø", 'US-ASCII', False), + (b"\xf8", 'ISO-8859-1', False), + ("ø", 'unicode', False), + + # ... xml_declaration = True + (b"\n" + b"ø", None, True), + (b"\n" + b"\xc3\xb8", 'UTF-8', True), + (b"\n" + b"ø", 'US-ASCII', True), + (b"\n" + b"\xf8", 'ISO-8859-1', True), + (f"\n" + "ø", 'unicode', True), + + ] + for expected_retval, encoding, xml_declaration in TESTCASES: + with self.subTest(f'encoding={encoding} ' + f'xml_declaration={xml_declaration}'): + self.assertEqual( + ET.tostring( + elem, + encoding=encoding, + xml_declaration=xml_declaration + ), + expected_retval + ) + + def test_tostringlist_default_namespace(self): + elem = ET.XML('') + self.assertEqual( + ''.join(ET.tostringlist(elem, encoding='unicode')), + '' + ) + self.assertEqual( + ''.join(ET.tostringlist(elem, encoding='unicode', default_namespace='http://effbot.org/ns')), + '' + ) + + def test_tostringlist_xml_declaration(self): + elem = ET.XML('') + self.assertEqual( + ''.join(ET.tostringlist(elem, encoding='unicode')), + '' + ) + self.assertEqual( + b''.join(ET.tostringlist(elem, xml_declaration=True)), + b"\n" + ) + + preferredencoding = locale.getpreferredencoding() + stringlist = ET.tostringlist(elem, encoding='unicode', xml_declaration=True) + self.assertEqual( + ''.join(stringlist), + f"\n" + ) + self.assertRegex(stringlist[0], r"^<\?xml version='1.0' encoding='.+'?>") + self.assertEqual(['', '', ''], stringlist[1:]) + def test_encoding(self): def check(encoding, body=''): xml = ("%s" % @@ -983,16 +1137,21 @@ def test_doctype_public(self): def test_xpath_tokenizer(self): # Test the XPath tokenizer. from xml.etree import ElementPath - def check(p, expected): + def check(p, expected, namespaces=None): self.assertEqual([op or tag - for op, tag in ElementPath.xpath_tokenizer(p)], + for op, tag in ElementPath.xpath_tokenizer(p, namespaces)], expected) # tests from the xml specification check("*", ['*']) + check("{ns}*", ['{ns}*']) + check("{}*", ['{}*']) + check("{*}tag", ['{*}tag']) + check("{*}*", ['{*}*']) check("text()", ['text', '()']) check("@name", ['@', 'name']) check("@*", ['@', '*']) + check("@{ns}attr", ['@', '{ns}attr']) check("para[1]", ['para', '[', '1', ']']) check("para[last()]", ['para', '[', 'last', '()', ']']) check("*/para", ['*', '/', 'para']) @@ -1004,6 +1163,7 @@ def check(p, expected): check("//olist/item", ['//', 'olist', '/', 'item']) check(".", ['.']) check(".//para", ['.', '//', 'para']) + check(".//{*}tag", ['.', '//', '{*}tag']) check("..", ['..']) check("../@lang", ['..', '/', '@', 'lang']) check("chapter[title]", ['chapter', '[', 'title', ']']) @@ -1014,6 +1174,8 @@ def check(p, expected): check("{http://spam}egg", ['{http://spam}egg']) check("./spam.egg", ['.', '/', 'spam.egg']) check(".//{http://spam}egg", ['.', '//', '{http://spam}egg']) + check("./xsd:type", ['.', '/', '{http://www.w3.org/2001/XMLSchema}type'], + {'xsd': 'http://www.w3.org/2001/XMLSchema'}) def test_processinginstruction(self): # Test ProcessingInstruction directly @@ -1070,8 +1232,19 @@ def _feed(self, parser, data, chunk_size=None): for i in range(0, len(data), chunk_size): parser.feed(data[i:i+chunk_size]) - def assert_event_tags(self, parser, expected): - events = parser.read_events() + def assert_events(self, parser, expected, max_events=None): + self.assertEqual( + [(event, (elem.tag, elem.text)) + for event, elem in islice(parser.read_events(), max_events)], + expected) + + def assert_event_tuples(self, parser, expected, max_events=None): + self.assertEqual( + list(islice(parser.read_events(), max_events)), + expected) + + def assert_event_tags(self, parser, expected, max_events=None): + events = islice(parser.read_events(), max_events) self.assertEqual([(action, elem.tag) for action, elem in events], expected) @@ -1146,14 +1319,66 @@ def test_ns_events(self): self.assertEqual(list(parser.read_events()), [('end-ns', None)]) self.assertIsNone(parser.close()) + def test_ns_events_start(self): + parser = ET.XMLPullParser(events=('start-ns', 'start', 'end')) + self._feed(parser, "\n") + self.assert_event_tuples(parser, [ + ('start-ns', ('', 'abc')), + ('start-ns', ('p', 'xyz')), + ], max_events=2) + self.assert_event_tags(parser, [ + ('start', '{abc}tag'), + ], max_events=1) + + self._feed(parser, "\n") + self.assert_event_tags(parser, [ + ('start', '{abc}child'), + ('end', '{abc}child'), + ]) + + self._feed(parser, "\n") + parser.close() + self.assert_event_tags(parser, [ + ('end', '{abc}tag'), + ]) + + def test_ns_events_start_end(self): + parser = ET.XMLPullParser(events=('start-ns', 'start', 'end', 'end-ns')) + self._feed(parser, "\n") + self.assert_event_tuples(parser, [ + ('start-ns', ('', 'abc')), + ('start-ns', ('p', 'xyz')), + ], max_events=2) + self.assert_event_tags(parser, [ + ('start', '{abc}tag'), + ], max_events=1) + + self._feed(parser, "\n") + self.assert_event_tags(parser, [ + ('start', '{abc}child'), + ('end', '{abc}child'), + ]) + + self._feed(parser, "\n") + parser.close() + self.assert_event_tags(parser, [ + ('end', '{abc}tag'), + ], max_events=1) + self.assert_event_tuples(parser, [ + ('end-ns', None), + ('end-ns', None), + ]) + def test_events(self): parser = ET.XMLPullParser(events=()) self._feed(parser, "\n") self.assert_event_tags(parser, []) parser = ET.XMLPullParser(events=('start', 'end')) - self._feed(parser, "\n") - self.assert_event_tags(parser, []) + self._feed(parser, "\n") + self.assert_events(parser, []) + + parser = ET.XMLPullParser(events=('start', 'end')) self._feed(parser, "\n") self.assert_event_tags(parser, [('start', 'root')]) self._feed(parser, "text") self.assertIsNone(parser.close()) + def test_events_comment(self): + parser = ET.XMLPullParser(events=('start', 'comment', 'end')) + self._feed(parser, "\n") + self.assert_events(parser, [('comment', (ET.Comment, ' text here '))]) + self._feed(parser, "\n") + self.assert_events(parser, [('comment', (ET.Comment, ' more text here '))]) + self._feed(parser, "text") + self.assert_event_tags(parser, [('start', 'root-tag')]) + self._feed(parser, "\n") + self.assert_events(parser, [('comment', (ET.Comment, ' inner comment'))]) + self._feed(parser, "\n") + self.assert_event_tags(parser, [('end', 'root-tag')]) + self._feed(parser, "\n") + self.assert_events(parser, [('comment', (ET.Comment, ' outer comment '))]) + + parser = ET.XMLPullParser(events=('comment',)) + self._feed(parser, "\n") + self.assert_events(parser, [('comment', (ET.Comment, ' text here '))]) + + def test_events_pi(self): + parser = ET.XMLPullParser(events=('start', 'pi', 'end')) + self._feed(parser, "\n") + self.assert_events(parser, [('pi', (ET.PI, 'pitarget'))]) + parser = ET.XMLPullParser(events=('pi',)) + self._feed(parser, "\n") + self.assert_events(parser, [('pi', (ET.PI, 'pitarget some text '))]) + def test_events_sequence(self): # Test that events can be some sequence that's not just a tuple or list eventset = {'end', 'start'} @@ -1209,7 +1461,6 @@ def __next__(self): self._feed(parser, "bar") self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')]) - def test_unknown_event(self): with self.assertRaises(ValueError): ET.XMLPullParser(events=('start', 'end', 'bogus')) @@ -1806,6 +2057,88 @@ def test_expat224_utf8_bug_file(self): class BasicElementTest(ElementTestCase, unittest.TestCase): + + def test___init__(self): + tag = "foo" + attrib = { "zix": "wyp" } + + element_foo = ET.Element(tag, attrib) + + # traits of an element + self.assertIsInstance(element_foo, ET.Element) + self.assertIn("tag", dir(element_foo)) + self.assertIn("attrib", dir(element_foo)) + self.assertIn("text", dir(element_foo)) + self.assertIn("tail", dir(element_foo)) + + # string attributes have expected values + self.assertEqual(element_foo.tag, tag) + self.assertIsNone(element_foo.text) + self.assertIsNone(element_foo.tail) + + # attrib is a copy + self.assertIsNot(element_foo.attrib, attrib) + self.assertEqual(element_foo.attrib, attrib) + + # attrib isn't linked + attrib["bar"] = "baz" + self.assertIsNot(element_foo.attrib, attrib) + self.assertNotEqual(element_foo.attrib, attrib) + + def test___copy__(self): + element_foo = ET.Element("foo", { "zix": "wyp" }) + element_foo.append(ET.Element("bar", { "baz": "qix" })) + + element_foo2 = copy.copy(element_foo) + + # elements are not the same + self.assertIsNot(element_foo2, element_foo) + + # string attributes are equal + self.assertEqual(element_foo2.tag, element_foo.tag) + self.assertEqual(element_foo2.text, element_foo.text) + self.assertEqual(element_foo2.tail, element_foo.tail) + + # number of children is the same + self.assertEqual(len(element_foo2), len(element_foo)) + + # children are the same + for (child1, child2) in itertools.zip_longest(element_foo, element_foo2): + self.assertIs(child1, child2) + + # attrib is a copy + self.assertEqual(element_foo2.attrib, element_foo.attrib) + + def test___deepcopy__(self): + element_foo = ET.Element("foo", { "zix": "wyp" }) + element_foo.append(ET.Element("bar", { "baz": "qix" })) + + element_foo2 = copy.deepcopy(element_foo) + + # elements are not the same + self.assertIsNot(element_foo2, element_foo) + + # string attributes are equal + self.assertEqual(element_foo2.tag, element_foo.tag) + self.assertEqual(element_foo2.text, element_foo.text) + self.assertEqual(element_foo2.tail, element_foo.tail) + + # number of children is the same + self.assertEqual(len(element_foo2), len(element_foo)) + + # children are not the same + for (child1, child2) in itertools.zip_longest(element_foo, element_foo2): + self.assertIsNot(child1, child2) + + # attrib is a copy + self.assertIsNot(element_foo2.attrib, element_foo.attrib) + self.assertEqual(element_foo2.attrib, element_foo.attrib) + + # attrib isn't linked + element_foo.attrib["bar"] = "baz" + self.assertIsNot(element_foo2.attrib, element_foo.attrib) + self.assertNotEqual(element_foo2.attrib, element_foo.attrib) + def test_augmentation_type_errors(self): e = ET.Element('joe') self.assertRaises(TypeError, e.append, 'b') @@ -1861,9 +2194,9 @@ class Dummy: e1 = ET.Element('e1') e2 = ET.Element('e2') e3 = ET.Element('e3') - e1.append(e2) - e2.append(e2) e3.append(e1) + e2.append(e3) + e1.append(e2) wref = weakref.ref(e1) del e1, e2, e3 gc_collect() @@ -2340,6 +2673,53 @@ def test_findall_different_nsmaps(self): nsmap = {'xx': 'Y'} self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) + nsmap = {'xx': 'X', '': 'Y'} + self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) + self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1) + + def test_findall_wildcard(self): + root = ET.XML(''' + + + + + ''') + root.append(ET.Comment('test')) + + self.assertEqual(summarize_list(root.findall("{*}b")), + ['{X}b', 'b', '{Y}b']) + self.assertEqual(summarize_list(root.findall("{*}c")), + ['c']) + self.assertEqual(summarize_list(root.findall("{X}*")), + ['{X}b']) + self.assertEqual(summarize_list(root.findall("{Y}*")), + ['{Y}b']) + self.assertEqual(summarize_list(root.findall("{}*")), + ['b', 'c']) + self.assertEqual(summarize_list(root.findall("{}b")), # only for consistency + ['b']) + self.assertEqual(summarize_list(root.findall("{}b")), + summarize_list(root.findall("b"))) + self.assertEqual(summarize_list(root.findall("{*}*")), + ['{X}b', 'b', 'c', '{Y}b']) + # This is an unfortunate difference, but that's how find('*') works. + self.assertEqual(summarize_list(root.findall("{*}*") + [root[-1]]), + summarize_list(root.findall("*"))) + + self.assertEqual(summarize_list(root.findall(".//{*}b")), + ['{X}b', 'b', '{X}b', 'b', '{Y}b']) + self.assertEqual(summarize_list(root.findall(".//{*}c")), + ['c', 'c']) + self.assertEqual(summarize_list(root.findall(".//{X}*")), + ['{X}b', '{X}b']) + self.assertEqual(summarize_list(root.findall(".//{Y}*")), + ['{Y}b']) + self.assertEqual(summarize_list(root.findall(".//{}*")), + ['c', 'b', 'c', 'b']) + self.assertEqual(summarize_list(root.findall(".//{}b")), # only for consistency + ['b', 'b']) + self.assertEqual(summarize_list(root.findall(".//{}b")), + summarize_list(root.findall(".//b"))) def test_bad_find(self): e = ET.XML(SAMPLE_XML) @@ -2532,6 +2912,33 @@ class DummyBuilder(BaseDummyBuilder): parser.feed(self.sample1) self.assertIsNone(parser.close()) + def test_treebuilder_comment(self): + b = ET.TreeBuilder() + self.assertEqual(b.comment('ctext').tag, ET.Comment) + self.assertEqual(b.comment('ctext').text, 'ctext') + + b = ET.TreeBuilder(comment_factory=ET.Comment) + self.assertEqual(b.comment('ctext').tag, ET.Comment) + self.assertEqual(b.comment('ctext').text, 'ctext') + + b = ET.TreeBuilder(comment_factory=len) + self.assertEqual(b.comment('ctext'), len('ctext')) + + def test_treebuilder_pi(self): + b = ET.TreeBuilder() + self.assertEqual(b.pi('target', None).tag, ET.PI) + self.assertEqual(b.pi('target', None).text, 'target') + + b = ET.TreeBuilder(pi_factory=ET.PI) + self.assertEqual(b.pi('target').tag, ET.PI) + self.assertEqual(b.pi('target').text, "target") + self.assertEqual(b.pi('pitarget', ' text ').tag, ET.PI) + self.assertEqual(b.pi('pitarget', ' text ').text, "pitarget text ") + + b = ET.TreeBuilder(pi_factory=lambda target, text: (len(target), text)) + self.assertEqual(b.pi('target'), (len('target'), None)) + self.assertEqual(b.pi('pitarget', ' text '), (len('pitarget'), ' text ')) + def test_treebuilder_elementfactory_none(self): parser = ET.XMLParser(target=ET.TreeBuilder(element_factory=None)) parser.feed(self.sample1) @@ -2552,6 +2959,21 @@ def foobar(self, x): e = parser.close() self._check_sample1_element(e) + def test_subclass_comment_pi(self): + class MyTreeBuilder(ET.TreeBuilder): + def foobar(self, x): + return x * 2 + + tb = MyTreeBuilder(comment_factory=ET.Comment, pi_factory=ET.PI) + self.assertEqual(tb.foobar(10), 20) + + parser = ET.XMLParser(target=tb) + parser.feed(self.sample1) + parser.feed('') + + e = parser.close() + self._check_sample1_element(e) + def test_element_factory(self): lst = [] def myfactory(tag, attrib): @@ -3159,6 +3581,231 @@ def test_correct_import_pyET(self): self.assertIsInstance(pyET.Element.__init__, types.FunctionType) self.assertIsInstance(pyET.XMLParser.__init__, types.FunctionType) + +# -------------------------------------------------------------------- + +def c14n_roundtrip(xml, **options): + return pyET.canonicalize(xml, **options) + + +class C14NTest(unittest.TestCase): + maxDiff = None + + # + # simple roundtrip tests (from c14n.py) + + def test_simple_roundtrip(self): + # Basics + self.assertEqual(c14n_roundtrip(""), '') + self.assertEqual(c14n_roundtrip(""), # FIXME + '') + self.assertEqual(c14n_roundtrip(""), + '') + self.assertEqual(c14n_roundtrip(""), + '') + self.assertEqual(c14n_roundtrip(""), + '') + + # C14N spec + self.assertEqual(c14n_roundtrip("Hello, world!"), + 'Hello, world!') + self.assertEqual(c14n_roundtrip("2"), + '2') + self.assertEqual(c14n_roundtrip('"0" && value<"10" ?"valid":"error"]]>'), + 'value>"0" && value<"10" ?"valid":"error"') + self.assertEqual(c14n_roundtrip('''valid'''), + 'valid') + self.assertEqual(c14n_roundtrip(""), + '') + self.assertEqual(c14n_roundtrip(""), + '') + self.assertEqual(c14n_roundtrip(""), + '') + + # fragments from PJ's tests + #self.assertEqual(c14n_roundtrip(""), + #'') + + def test_c14n_exclusion(self): + xml = textwrap.dedent("""\ + + + abtext + + btext + + dtext + + + """) + self.assertEqual( + c14n_roundtrip(xml, strip_text=True), + '' + 'abtext' + 'btext' + 'dtext' + '') + self.assertEqual( + c14n_roundtrip(xml, strip_text=True, exclude_attrs=['{http://example.com/x}attr']), + '' + 'abtext' + 'btext' + 'dtext' + '') + self.assertEqual( + c14n_roundtrip(xml, strip_text=True, exclude_tags=['{http://example.com/x}d']), + '' + 'abtext' + 'btext' + '' + '') + self.assertEqual( + c14n_roundtrip(xml, strip_text=True, exclude_attrs=['{http://example.com/x}attr'], + exclude_tags=['{http://example.com/x}d']), + '' + 'abtext' + 'btext' + '' + '') + self.assertEqual( + c14n_roundtrip(xml, strip_text=True, exclude_tags=['a', 'b']), + '' + 'dtext' + '') + self.assertEqual( + c14n_roundtrip(xml, exclude_tags=['a', 'b']), + '\n' + ' \n' + ' \n' + ' \n' + ' dtext\n' + ' \n' + '') + self.assertEqual( + c14n_roundtrip(xml, strip_text=True, exclude_tags=['{http://example.com/x}d', 'b']), + '' + '' + '' + '') + self.assertEqual( + c14n_roundtrip(xml, exclude_tags=['{http://example.com/x}d', 'b']), + '\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '') + + # + # basic method=c14n tests from the c14n 2.0 specification. uses + # test files under xmltestdata/c14n-20. + + # note that this uses generated C14N versions of the standard ET.write + # output, not roundtripped C14N (see above). + + def test_xml_c14n2(self): + datadir = findfile("c14n-20", subdir="xmltestdata") + full_path = partial(os.path.join, datadir) + + files = [filename[:-4] for filename in sorted(os.listdir(datadir)) + if filename.endswith('.xml')] + input_files = [ + filename for filename in files + if filename.startswith('in') + ] + configs = { + filename: { + # sequential + option.tag.split('}')[-1]: ((option.text or '').strip(), option) + for option in ET.parse(full_path(filename) + ".xml").getroot() + } + for filename in files + if filename.startswith('c14n') + } + + tests = { + input_file: [ + (filename, configs[filename.rsplit('_', 1)[-1]]) + for filename in files + if filename.startswith(f'out_{input_file}_') + and filename.rsplit('_', 1)[-1] in configs + ] + for input_file in input_files + } + + # Make sure we found all test cases. + self.assertEqual(30, len([ + output_file for output_files in tests.values() + for output_file in output_files])) + + def get_option(config, option_name, default=None): + return config.get(option_name, (default, ()))[0] + + for input_file, output_files in tests.items(): + for output_file, config in output_files: + keep_comments = get_option( + config, 'IgnoreComments') == 'true' # no, it's right :) + strip_text = get_option( + config, 'TrimTextNodes') == 'true' + rewrite_prefixes = get_option( + config, 'PrefixRewrite') == 'sequential' + if 'QNameAware' in config: + qattrs = [ + f"{{{el.get('NS')}}}{el.get('Name')}" + for el in config['QNameAware'][1].findall( + '{http://www.w3.org/2010/xml-c14n2}QualifiedAttr') + ] + qtags = [ + f"{{{el.get('NS')}}}{el.get('Name')}" + for el in config['QNameAware'][1].findall( + '{http://www.w3.org/2010/xml-c14n2}Element') + ] + else: + qtags = qattrs = None + + # Build subtest description from config. + config_descr = ','.join( + f"{name}={value or ','.join(c.tag.split('}')[-1] for c in children)}" + for name, (value, children) in sorted(config.items()) + ) + + with self.subTest(f"{output_file}({config_descr})"): + if input_file == 'inNsRedecl' and not rewrite_prefixes: + self.skipTest( + f"Redeclared namespace handling is not supported in {output_file}") + if input_file == 'inNsSuperfluous' and not rewrite_prefixes: + self.skipTest( + f"Redeclared namespace handling is not supported in {output_file}") + if 'QNameAware' in config and config['QNameAware'][1].find( + '{http://www.w3.org/2010/xml-c14n2}XPathElement') is not None: + self.skipTest( + f"QName rewriting in XPath text is not supported in {output_file}") + + f = full_path(input_file + ".xml") + if input_file == 'inC14N5': + # Hack: avoid setting up external entity resolution in the parser. + with open(full_path('world.txt'), 'rb') as entity_file: + with open(f, 'rb') as f: + f = io.BytesIO(f.read().replace(b'&ent2;', entity_file.read())) + + text = ET.canonicalize( + from_file=f, + with_comments=keep_comments, + strip_text=strip_text, + rewrite_prefixes=rewrite_prefixes, + qname_aware_tags=qtags, qname_aware_attrs=qattrs) + + with open(full_path(output_file + ".xml"), 'r', encoding='utf8') as f: + expected = f.read() + if input_file == 'inC14N3': + # FIXME: cET resolves default attributes but ET does not! + expected = expected.replace(' attr="default"', '') + text = text.replace(' attr="default"', '') + self.assertEqual(expected, text) + # -------------------------------------------------------------------- @@ -3191,6 +3838,8 @@ def test_main(module=None): XMLParserTest, XMLPullParserTest, BugsTest, + KeywordArgsTest, + C14NTest, ] # These tests will only run for the pure-Python version that doesn't import @@ -3209,6 +3858,12 @@ def test_main(module=None): # Copy the path cache (should be empty) path_cache = ElementPath._cache ElementPath._cache = path_cache.copy() + # Align the Comment/PI factories. + if hasattr(ET, '_set_factories'): + old_factories = ET._set_factories(ET.Comment, ET.PI) + else: + old_factories = None + try: support.run_unittest(*test_classes) finally: @@ -3217,6 +3872,8 @@ def test_main(module=None): nsmap.clear() nsmap.update(nsmap_copy) ElementPath._cache = path_cache + if old_factories is not None: + ET._set_factories(*old_factories) # don't interfere with subsequent tests ET = pyET = None diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 9c8b6958c62..52bacc1eafa 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -943,8 +943,13 @@ def test_unicode_host(self): def test_partial_post(self): # Check that a partial POST doesn't make the server loop: issue #14001. - with contextlib.closing(http.client.HTTPConnection(ADDR, PORT)) as conn: - conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') + with contextlib.closing(socket.create_connection((ADDR, PORT))) as conn: + conn.send('POST /RPC2 HTTP/1.0\r\n' + 'Content-Length: 100\r\n\r\n' + 'bye HTTP/1.1\r\n' + f'Host: {ADDR}:{PORT}\r\n' + 'Accept-Encoding: identity\r\n' + 'Content-Length: 0\r\n\r\n'.encode('ascii')) def test_context_manager(self): with xmlrpclib.ServerProxy(URL) as server: diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 7b8922f4e05..538d4ee55df 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,13 +1,15 @@ import contextlib +import importlib.util import io import os -import importlib.util import pathlib import posixpath -import time +import shutil import struct -import zipfile +import tempfile +import time import unittest +import zipfile from tempfile import TemporaryFile @@ -402,6 +404,43 @@ def test_per_file_compresslevel(self): self.assertEqual(one_info._compresslevel, 1) self.assertEqual(nine_info._compresslevel, 9) + def test_writing_errors(self): + class BrokenFile(io.BytesIO): + def write(self, data): + nonlocal count + if count is not None: + if count == stop: + raise OSError + count += 1 + super().write(data) + + stop = 0 + while True: + testfile = BrokenFile() + count = None + with zipfile.ZipFile(testfile, 'w', self.compression) as zipfp: + with zipfp.open('file1', 'w') as f: + f.write(b'data1') + count = 0 + try: + with zipfp.open('file2', 'w') as f: + f.write(b'data2') + except OSError: + stop += 1 + else: + break + finally: + count = None + with zipfile.ZipFile(io.BytesIO(testfile.getvalue())) as zipfp: + self.assertEqual(zipfp.namelist(), ['file1']) + self.assertEqual(zipfp.read('file1'), b'data1') + + with zipfile.ZipFile(io.BytesIO(testfile.getvalue())) as zipfp: + self.assertEqual(zipfp.namelist(), ['file1', 'file2']) + self.assertEqual(zipfp.read('file1'), b'data1') + self.assertEqual(zipfp.read('file2'), b'data2') + + def tearDown(self): unlink(TESTFN) unlink(TESTFN2) @@ -2355,5 +2394,113 @@ def test_extract_command(self): with open(path, 'rb') as f: self.assertEqual(f.read(), zf.read(zi)) + +# Poor man's technique to consume a (smallish) iterable. +consume = tuple + + +def add_dirs(zipfile): + """ + Given a writable zipfile, inject directory entries for + any directories implied by the presence of children. + """ + names = zipfile.namelist() + consume( + zipfile.writestr(name + "/", b"") + for name in map(posixpath.dirname, names) + if name and name + "/" not in names + ) + return zipfile + + +def build_abcde_files(): + """ + Create a zip file with this structure: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + """ + data = io.BytesIO() + zf = zipfile.ZipFile(data, "w") + zf.writestr("a.txt", b"content of a") + zf.writestr("b/c.txt", b"content of c") + zf.writestr("b/d/e.txt", b"content of e") + zf.filename = "abcde.zip" + return zf + + +class TestPath(unittest.TestCase): + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + + def zipfile_abcde(self): + with self.subTest(): + yield build_abcde_files() + with self.subTest(): + yield add_dirs(build_abcde_files()) + + def zipfile_ondisk(self): + tmpdir = pathlib.Path(self.fixtures.enter_context(temp_dir())) + for zipfile_abcde in self.zipfile_abcde(): + buffer = zipfile_abcde.fp + zipfile_abcde.close() + path = tmpdir / zipfile_abcde.filename + with path.open("wb") as strm: + strm.write(buffer.getvalue()) + yield path + + def test_iterdir_istype(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + assert root.is_dir() + a, b = root.iterdir() + assert a.is_file() + assert b.is_dir() + c, d = b.iterdir() + assert c.is_file() + e, = d.iterdir() + assert e.is_file() + + def test_open(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + a, b = root.iterdir() + with a.open() as strm: + data = strm.read() + assert data == b"content of a" + + def test_read(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + a, b = root.iterdir() + assert a.read_text() == "content of a" + assert a.read_bytes() == b"content of a" + + def test_traverse_truediv(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + a = root / "a" + assert a.is_file() + e = root / "b" / "d" / "e.txt" + assert e.read_text() == "content of e" + + def test_pathlike_construction(self): + """ + zipfile.Path should be constructable from a path-like object + """ + for zipfile_ondisk in self.zipfile_ondisk(): + pathlike = pathlib.Path(str(zipfile_ondisk)) + zipfile.Path(pathlike) + + def test_traverse_pathlike(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + root / pathlib.Path("a") + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/xmltestdata/c14n-20/README b/Lib/test/xmltestdata/c14n-20/README new file mode 100644 index 00000000000..45e75b9bd98 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/README @@ -0,0 +1,40 @@ +C14N 2.0 test files +=================== + +This directory contains files from the draft note document listing +test cases for the W3C C14N 2.0 specification: +https://www.w3.org/TR/xml-c14n2-testcases/ + +Direct source: +https://www.w3.org/TR/xml-c14n2-testcases/files/ + +Copied and distributed under these terms: +https://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html + +Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of works must retain the original copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the original copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the W3C nor the names of its contributors may be + used to endorse or promote products derived from this work without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Lib/test/xmltestdata/c14n-20/c14nComment.xml b/Lib/test/xmltestdata/c14n-20/c14nComment.xml new file mode 100644 index 00000000000..e95aa302d04 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nComment.xml @@ -0,0 +1,4 @@ + + true + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/c14nDefault.xml new file mode 100644 index 00000000000..c1364142cc5 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nDefault.xml @@ -0,0 +1,3 @@ + + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/c14nPrefix.xml new file mode 100644 index 00000000000..fb233b42b13 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nPrefix.xml @@ -0,0 +1,4 @@ + + sequential + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nPrefixQname.xml b/Lib/test/xmltestdata/c14n-20/c14nPrefixQname.xml new file mode 100644 index 00000000000..23188eedbc2 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nPrefixQname.xml @@ -0,0 +1,7 @@ + + sequential + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nPrefixQnameXpathElem.xml b/Lib/test/xmltestdata/c14n-20/c14nPrefixQnameXpathElem.xml new file mode 100644 index 00000000000..626fc48f410 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nPrefixQnameXpathElem.xml @@ -0,0 +1,8 @@ + + sequential + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nQname.xml b/Lib/test/xmltestdata/c14n-20/c14nQname.xml new file mode 100644 index 00000000000..919e5903f5c --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nQname.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nQnameElem.xml b/Lib/test/xmltestdata/c14n-20/c14nQnameElem.xml new file mode 100644 index 00000000000..0321f806195 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nQnameElem.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nQnameXpathElem.xml b/Lib/test/xmltestdata/c14n-20/c14nQnameXpathElem.xml new file mode 100644 index 00000000000..c4890bc8b01 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nQnameXpathElem.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/c14nTrim.xml b/Lib/test/xmltestdata/c14n-20/c14nTrim.xml new file mode 100644 index 00000000000..ccb9cf65db7 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/c14nTrim.xml @@ -0,0 +1,4 @@ + + true + + diff --git a/Lib/test/xmltestdata/c14n-20/doc.dtd b/Lib/test/xmltestdata/c14n-20/doc.dtd new file mode 100644 index 00000000000..5c5d544a0df --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/doc.dtd @@ -0,0 +1,6 @@ + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/doc.xsl b/Lib/test/xmltestdata/c14n-20/doc.xsl new file mode 100644 index 00000000000..a3f2348cc2f --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/doc.xsl @@ -0,0 +1,5 @@ + + + diff --git a/Lib/test/xmltestdata/c14n-20/inC14N1.xml b/Lib/test/xmltestdata/c14n-20/inC14N1.xml new file mode 100644 index 00000000000..ed450c7341d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inC14N1.xml @@ -0,0 +1,14 @@ + + + + + + +Hello, world! + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/inC14N2.xml b/Lib/test/xmltestdata/c14n-20/inC14N2.xml new file mode 100644 index 00000000000..74eeea147c3 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inC14N2.xml @@ -0,0 +1,11 @@ + + + A B + + A + + B + A B + C + + diff --git a/Lib/test/xmltestdata/c14n-20/inC14N3.xml b/Lib/test/xmltestdata/c14n-20/inC14N3.xml new file mode 100644 index 00000000000..fea78213f1a --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inC14N3.xml @@ -0,0 +1,18 @@ +]> + + + + + + + + + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/inC14N4.xml b/Lib/test/xmltestdata/c14n-20/inC14N4.xml new file mode 100644 index 00000000000..909a847435b --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inC14N4.xml @@ -0,0 +1,13 @@ + + +]> + + First line Second line + 2 + "0" && value<"10" ?"valid":"error"]]> + valid + + + + diff --git a/Lib/test/xmltestdata/c14n-20/inC14N5.xml b/Lib/test/xmltestdata/c14n-20/inC14N5.xml new file mode 100644 index 00000000000..501161bad51 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inC14N5.xml @@ -0,0 +1,12 @@ + + + + + +]> + + &ent1;, &ent2;! + + + diff --git a/Lib/test/xmltestdata/c14n-20/inC14N6.xml b/Lib/test/xmltestdata/c14n-20/inC14N6.xml new file mode 100644 index 00000000000..31e20718672 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inC14N6.xml @@ -0,0 +1,2 @@ + +© diff --git a/Lib/test/xmltestdata/c14n-20/inNsContent.xml b/Lib/test/xmltestdata/c14n-20/inNsContent.xml new file mode 100644 index 00000000000..b9924660ba6 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsContent.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + diff --git a/Lib/test/xmltestdata/c14n-20/inNsDefault.xml b/Lib/test/xmltestdata/c14n-20/inNsDefault.xml new file mode 100644 index 00000000000..3e0d323bad2 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsDefault.xml @@ -0,0 +1,3 @@ + + + diff --git a/Lib/test/xmltestdata/c14n-20/inNsPushdown.xml b/Lib/test/xmltestdata/c14n-20/inNsPushdown.xml new file mode 100644 index 00000000000..daa67d83f15 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsPushdown.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Lib/test/xmltestdata/c14n-20/inNsRedecl.xml b/Lib/test/xmltestdata/c14n-20/inNsRedecl.xml new file mode 100644 index 00000000000..10bd97beda3 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsRedecl.xml @@ -0,0 +1,3 @@ + + + diff --git a/Lib/test/xmltestdata/c14n-20/inNsSort.xml b/Lib/test/xmltestdata/c14n-20/inNsSort.xml new file mode 100644 index 00000000000..8e9fc01c647 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsSort.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Lib/test/xmltestdata/c14n-20/inNsSuperfluous.xml b/Lib/test/xmltestdata/c14n-20/inNsSuperfluous.xml new file mode 100644 index 00000000000..f77720f7b0b --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsSuperfluous.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Lib/test/xmltestdata/c14n-20/inNsXml.xml b/Lib/test/xmltestdata/c14n-20/inNsXml.xml new file mode 100644 index 00000000000..7520cf3fb9e --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/inNsXml.xml @@ -0,0 +1,3 @@ + + data + diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N1_c14nComment.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N1_c14nComment.xml new file mode 100644 index 00000000000..d98d16840c6 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N1_c14nComment.xml @@ -0,0 +1,6 @@ + +Hello, world! + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N1_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N1_c14nDefault.xml new file mode 100644 index 00000000000..af9a9770578 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N1_c14nDefault.xml @@ -0,0 +1,4 @@ + +Hello, world! + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N2_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N2_c14nDefault.xml new file mode 100644 index 00000000000..2afa15ccb36 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N2_c14nDefault.xml @@ -0,0 +1,11 @@ + + + A B + + A + + B + A B + C + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N2_c14nTrim.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N2_c14nTrim.xml new file mode 100644 index 00000000000..7a1dc32946b --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N2_c14nTrim.xml @@ -0,0 +1 @@ +A BABA BC \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nDefault.xml new file mode 100644 index 00000000000..662e108aa8a --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nDefault.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nPrefix.xml new file mode 100644 index 00000000000..041e1ec8ebe --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nPrefix.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nTrim.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nTrim.xml new file mode 100644 index 00000000000..4f35ad9662d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N3_c14nTrim.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N4_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N4_c14nDefault.xml new file mode 100644 index 00000000000..243d0e61f2e --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N4_c14nDefault.xml @@ -0,0 +1,10 @@ + + First line +Second line + 2 + value>"0" && value<"10" ?"valid":"error" + valid + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N4_c14nTrim.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N4_c14nTrim.xml new file mode 100644 index 00000000000..24d83ba8ab0 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N4_c14nTrim.xml @@ -0,0 +1,2 @@ +First line +Second line2value>"0" && value<"10" ?"valid":"error"valid \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N5_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N5_c14nDefault.xml new file mode 100644 index 00000000000..c232e740aee --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N5_c14nDefault.xml @@ -0,0 +1,3 @@ + + Hello, world! + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N5_c14nTrim.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N5_c14nTrim.xml new file mode 100644 index 00000000000..3fa84b1e986 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N5_c14nTrim.xml @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inC14N6_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inC14N6_c14nDefault.xml new file mode 100644 index 00000000000..0be38f98cb1 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inC14N6_c14nDefault.xml @@ -0,0 +1 @@ +© \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nDefault.xml new file mode 100644 index 00000000000..62d7e004a44 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nDefault.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nPrefixQnameXpathElem.xml b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nPrefixQnameXpathElem.xml new file mode 100644 index 00000000000..20e1c2e9d6d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nPrefixQnameXpathElem.xml @@ -0,0 +1,4 @@ + + n1:string + /n3:body/child::n2:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nQnameElem.xml b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nQnameElem.xml new file mode 100644 index 00000000000..db8680daa03 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nQnameElem.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nQnameXpathElem.xml b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nQnameXpathElem.xml new file mode 100644 index 00000000000..df3b21579fa --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsContent_c14nQnameXpathElem.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsDefault_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsDefault_c14nDefault.xml new file mode 100644 index 00000000000..674b076dd6d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsDefault_c14nDefault.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsDefault_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inNsDefault_c14nPrefix.xml new file mode 100644 index 00000000000..83edaae91e7 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsDefault_c14nPrefix.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsPushdown_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsPushdown_c14nDefault.xml new file mode 100644 index 00000000000..fa4f21b5d0a --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsPushdown_c14nDefault.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsPushdown_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inNsPushdown_c14nPrefix.xml new file mode 100644 index 00000000000..6d579200c9d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsPushdown_c14nPrefix.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsRedecl_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsRedecl_c14nDefault.xml new file mode 100644 index 00000000000..ba37f925103 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsRedecl_c14nDefault.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsRedecl_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inNsRedecl_c14nPrefix.xml new file mode 100644 index 00000000000..af3bb2d6f06 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsRedecl_c14nPrefix.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsSort_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsSort_c14nDefault.xml new file mode 100644 index 00000000000..8a92c5c61c2 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsSort_c14nDefault.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsSort_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inNsSort_c14nPrefix.xml new file mode 100644 index 00000000000..8d44c84fe5d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsSort_c14nPrefix.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsSuperfluous_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsSuperfluous_c14nDefault.xml new file mode 100644 index 00000000000..6bb862d763d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsSuperfluous_c14nDefault.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsSuperfluous_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inNsSuperfluous_c14nPrefix.xml new file mode 100644 index 00000000000..700a16d42a7 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsSuperfluous_c14nPrefix.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nDefault.xml b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nDefault.xml new file mode 100644 index 00000000000..1689f3bf423 --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nDefault.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nPrefix.xml b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nPrefix.xml new file mode 100644 index 00000000000..38508a47f6b --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nPrefix.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nPrefixQname.xml b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nPrefixQname.xml new file mode 100644 index 00000000000..867980f82bf --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nPrefixQname.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nQname.xml b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nQname.xml new file mode 100644 index 00000000000..0300f9d562d --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/out_inNsXml_c14nQname.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Lib/test/xmltestdata/c14n-20/world.txt b/Lib/test/xmltestdata/c14n-20/world.txt new file mode 100644 index 00000000000..04fea06420c --- /dev/null +++ b/Lib/test/xmltestdata/c14n-20/world.txt @@ -0,0 +1 @@ +world \ No newline at end of file diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index ae493ed3aaa..57d5b257282 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -4124,6 +4124,15 @@ def write(self, filename, format=None, from_coords=None): args = args + ('-from',) + tuple(from_coords) self.tk.call(args) + def transparency_get(self, x, y): + """Return True if the pixel at x,y is transparent.""" + return self.tk.getboolean(self.tk.call( + self.name, 'transparency', 'get', x, y)) + + def transparency_set(self, x, y, boolean): + """Set the transparency of the pixel at x,y.""" + self.tk.call(self.name, 'transparency', 'set', x, y, boolean) + class BitmapImage(Image): """Widget which can display images in XBM format.""" diff --git a/Lib/tkinter/test/test_tkinter/test_images.py b/Lib/tkinter/test/test_tkinter/test_images.py index 85a8cd0495b..2805d35a1f5 100644 --- a/Lib/tkinter/test/test_tkinter/test_images.py +++ b/Lib/tkinter/test/test_tkinter/test_images.py @@ -320,6 +320,15 @@ def test_write(self): self.assertEqual(image3.get(0, 0), image.get(4, 6)) self.assertEqual(image3.get(1, 2), image.get(5, 8)) + def test_transparency(self): + image = self.create() + self.assertEqual(image.transparency_get(0, 0), True) + self.assertEqual(image.transparency_get(4, 6), False) + image.transparency_set(4, 6, True) + self.assertEqual(image.transparency_get(4, 6), True) + image.transparency_set(4, 6, False) + self.assertEqual(image.transparency_get(4, 6), False) + tests_gui = (MiscTest, BitmapImageTest, PhotoImageTest,) diff --git a/Lib/tokenize.py b/Lib/tokenize.py index cf1ecc99a94..0f9d5dd554d 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -82,7 +82,7 @@ def maybe(*choices): return group(*choices) + '?' # Return the empty string, plus all of the valid string prefixes. def _all_string_prefixes(): # The valid string prefixes. Only contain the lower case versions, - # and don't contain any permuations (include 'fr', but not + # and don't contain any permutations (include 'fr', but not # 'rf'). The various permutations will be generated. _valid_string_prefixes = ['b', 'r', 'u', 'f', 'br', 'fr'] # if we add binary f-strings, add: ['fb', 'fbr'] diff --git a/Lib/trace.py b/Lib/trace.py index 3049e4ec683..63008a134a8 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -451,7 +451,22 @@ def runctx(self, cmd, globals=None, locals=None): sys.settrace(None) threading.settrace(None) - def runfunc(self, func, *args, **kw): + def runfunc(*args, **kw): + if len(args) >= 2: + self, func, *args = args + elif not args: + raise TypeError("descriptor 'runfunc' of 'Trace' object " + "needs an argument") + elif 'func' in kw: + func = kw.pop('func') + self, *args = args + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('runfunc expected at least 1 positional argument, ' + 'got %d' % (len(args)-1)) + result = None if not self.donothing: sys.settrace(self.globaltrace) @@ -461,6 +476,7 @@ def runfunc(self, func, *args, **kw): if not self.donothing: sys.settrace(None) return result + runfunc.__text_signature__ = '($self, func, /, *args, **kw)' def file_module_function_of(self, frame): code = frame.f_code diff --git a/Lib/turtle.py b/Lib/turtle.py index 47a94f2a470..044d91cf6d8 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -1568,7 +1568,7 @@ def degrees(self, fullcircle=360.0): fullcircle - a number Set angle measurement units, i. e. set number - of 'degrees' for a full circle. Dafault value is + of 'degrees' for a full circle. Default value is 360 degrees. Example (for a Turtle instance named turtle): diff --git a/Lib/types.py b/Lib/types.py index cf643088ea9..37ba4bb1f42 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -263,7 +263,7 @@ def coroutine(func): # TODO: Implement this in C. co = func.__code__ func.__code__ = CodeType( - co.co_argcount, co.co_kwonlyargcount, co.co_nlocals, + co.co_argcount, co.co_posonlyargcount, co.co_kwonlyargcount, co.co_nlocals, co.co_stacksize, co.co_flags | 0x100, # 0x100 == CO_ITERABLE_COROUTINE co.co_code, diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index a157ae8a14b..8e01c3dc7bb 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -86,10 +86,23 @@ def _id(obj): _module_cleanups = [] -def addModuleCleanup(function, *args, **kwargs): +def addModuleCleanup(*args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpModule fails (unlike tearDownModule).""" + if args: + function, *args = args + elif 'function' in kwargs: + function = kwargs.pop('function') + import warnings + warnings.warn("Passing 'function' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('addModuleCleanup expected at least 1 positional ' + 'argument, got %d' % (len(args)-1)) + args = tuple(args) + _module_cleanups.append((function, args, kwargs)) +addModuleCleanup.__text_signature__ = '(function, /, *args, **kwargs)' def doModuleCleanups(): @@ -463,19 +476,47 @@ def addTypeEqualityFunc(self, typeobj, function): """ self._type_equality_funcs[typeobj] = function - def addCleanup(self, function, *args, **kwargs): + def addCleanup(*args, **kwargs): """Add a function, with arguments, to be called when the test is completed. Functions added are called on a LIFO basis and are called after tearDown on test failure or success. Cleanup items are called even if setUp fails (unlike tearDown).""" - self._cleanups.append((function, args, kwargs)) + if len(args) >= 2: + self, function, *args = args + elif not args: + raise TypeError("descriptor 'addCleanup' of 'TestCase' object " + "needs an argument") + elif 'function' in kwargs: + function = kwargs.pop('function') + self, *args = args + import warnings + warnings.warn("Passing 'function' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + raise TypeError('addCleanup expected at least 1 positional ' + 'argument, got %d' % (len(args)-1)) + args = tuple(args) - @classmethod - def addClassCleanup(cls, function, *args, **kwargs): + self._cleanups.append((function, args, kwargs)) + addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)' + + def addClassCleanup(*args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpClass fails (unlike tearDownClass).""" + if len(args) >= 2: + cls, function, *args = args + elif not args: + raise TypeError("descriptor 'addClassCleanup' of 'TestCase' object " + "needs an argument") + else: + raise TypeError('addClassCleanup expected at least 1 positional ' + 'argument, got %d' % (len(args)-1)) + args = tuple(args) + cls._class_cleanups.append((function, args, kwargs)) + addClassCleanup.__text_signature__ = '($cls, function, /, *args, **kwargs)' + addClassCleanup = classmethod(addClassCleanup) def setUp(self): "Hook method for setting up the test fixture before exercising it." @@ -1206,9 +1247,8 @@ def assertDictContainsSubset(self, subset, dictionary, msg=None): def assertCountEqual(self, first, second, msg=None): - """An unordered sequence comparison asserting that the same elements, - regardless of order. If the same element occurs more than once, - it verifies that the elements occur the same number of times. + """Asserts that two iterables have the same elements, the same number of + times, without regard to order. self.assertEqual(Counter(list(first)), Counter(list(second))) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index fdde16be03a..1e8057d5f5b 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -25,24 +25,18 @@ __version__ = '1.0' +import io import inspect import pprint import sys import builtins -from types import ModuleType +from types import ModuleType, MethodType from unittest.util import safe_repr from functools import wraps, partial _builtins = {name for name in dir(builtins) if not name.startswith('_')} -BaseExceptions = (BaseException,) -if 'java' in sys.platform: - # jython - import java - BaseExceptions = (BaseException, java.lang.Throwable) - - FILTER_DIR = True # Workaround for issue #12370 @@ -57,8 +51,8 @@ def _is_instance_mock(obj): def _is_exception(obj): return ( - isinstance(obj, BaseExceptions) or - isinstance(obj, type) and issubclass(obj, BaseExceptions) + isinstance(obj, BaseException) or + isinstance(obj, type) and issubclass(obj, BaseException) ) @@ -70,10 +64,7 @@ def _get_signature_object(func, as_instance, eat_self): """ if isinstance(func, type) and not as_instance: # If it's a type and should be modelled as a type, use __init__. - try: - func = func.__init__ - except AttributeError: - return None + func = func.__init__ # Skip the `self` argument in __init__ eat_self = True elif not isinstance(func, FunctionTypes): @@ -122,6 +113,8 @@ def _copy_func_details(func, funcopy): def _callable(obj): if isinstance(obj, type): return True + if isinstance(obj, (staticmethod, classmethod, MethodType)): + return _callable(obj.__func__) if getattr(obj, '__call__', None) is not None: return True return False @@ -152,8 +145,6 @@ def _set_signature(mock, original, instance=False): # creates a function with signature (*args, **kwargs) that delegates to a # mock. It still does signature checking by calling a lambda with the same # signature as the original. - if not _callable(original): - return skipfirst = isinstance(original, type) result = _get_signature_object(original, instance, skipfirst) @@ -180,10 +171,6 @@ def checksig(*args, **kwargs): def _setup_func(funcopy, mock, sig): funcopy.mock = mock - # can't use isinstance with mocks - if not _is_instance_mock(mock): - return - def assert_called_with(*args, **kwargs): return mock.assert_called_with(*args, **kwargs) def assert_called(*args, **kwargs): @@ -268,12 +255,6 @@ def __reduce__(self): _deleted = sentinel.DELETED -def _copy(value): - if type(value) in (dict, list, tuple, set): - return type(value)(value) - return value - - _allowed_names = { 'return_value', '_mock_return_value', 'side_effect', '_mock_side_effect', '_mock_parent', '_mock_new_parent', @@ -356,8 +337,6 @@ def _check_and_set_parent(parent, value, name, new_name): class _MockIter(object): def __init__(self, obj): self.obj = iter(obj) - def __iter__(self): - return self def __next__(self): return next(self.obj) @@ -457,7 +436,7 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, if isinstance(spec, type): _spec_class = spec else: - _spec_class = _get_class(spec) + _spec_class = type(spec) res = _get_signature_object(spec, _spec_as_instance, _eat_self) _spec_signature = res and res[1] @@ -629,7 +608,7 @@ def _extract_mock_name(self): dot = '.' if _name_list == ['()']: dot = '' - seen = set() + while _parent is not None: last = _parent @@ -640,11 +619,6 @@ def _extract_mock_name(self): _parent = _parent._mock_new_parent - # use ids here so as not to call __hash__ on the mocks - if id(_parent) in seen: - break - seen.add(id(_parent)) - _name_list = list(reversed(_name_list)) _first = last._mock_name or 'mock' if len(_name_list) > 1: @@ -682,12 +656,14 @@ def __dir__(self): extras = self._mock_methods or [] from_type = dir(type(self)) from_dict = list(self.__dict__) + from_child_mocks = [ + m_name for m_name, m_value in self._mock_children.items() + if m_value is not _deleted] from_type = [e for e in from_type if not e.startswith('_')] from_dict = [e for e in from_dict if not e.startswith('_') or _is_magic(e)] - return sorted(set(extras + from_type + from_dict + - list(self._mock_children))) + return sorted(set(extras + from_type + from_dict + from_child_mocks)) def __setattr__(self, name, value): @@ -739,7 +715,7 @@ def __delattr__(self, name): obj = self._mock_children.get(name, _missing) if name in self.__dict__: - super().__delattr__(name) + _safe_super(NonCallableMock, self).__delattr__(name) elif obj is _deleted: raise AttributeError(name) if obj is not _missing: @@ -756,8 +732,6 @@ def _format_mock_failure_message(self, args, kwargs): message = 'expected call not found.\nExpected: %s\nActual: %s' expected_string = self._format_mock_call_signature(args, kwargs) call_args = self.call_args - if len(call_args) == 3: - call_args = call_args[1:] actual_string = self._format_mock_call_signature(*call_args) return message % (expected_string, actual_string) @@ -995,8 +969,6 @@ def _mock_call(_mock_self, *args, **kwargs): self.call_args = _call self.call_args_list.append(_call) - seen = set() - # initial stuff for method_calls: do_method_calls = self._mock_parent is not None method_call_name = self._mock_name @@ -1032,13 +1004,6 @@ def _mock_call(_mock_self, *args, **kwargs): # follow the parental chain: _new_parent = _new_parent._mock_new_parent - # check we're not in an infinite loop: - # ( use ids here so as not to call __hash__ on the mocks) - _new_parent_id = id(_new_parent) - if _new_parent_id in seen: - break - seen.add(_new_parent_id) - effect = self.side_effect if effect is not None: if _is_exception(effect): @@ -1398,7 +1363,7 @@ def __enter__(self): def __exit__(self, *exc_info): """Undo the patch.""" if not _is_started(self): - raise RuntimeError('stop called on unstarted patcher') + return if self.is_local and self.temp_original is not DEFAULT: setattr(self.target, self.attribute, self.temp_original) @@ -1861,12 +1826,7 @@ def _set_return_value(mock, method, name): return_calulator = _calculate_return_value.get(name) if return_calulator is not None: - try: - return_value = return_calulator(mock) - except AttributeError: - # XXXX why do we return AttributeError here? - # set it as a side_effect instead? - return_value = AttributeError(name) + return_value = return_calulator(mock) method.return_value = return_value return @@ -1946,10 +1906,6 @@ def __init__(self, name, parent): self.name = name self.parent = parent - def __call__(self, *args, **kwargs): - m = self.create_mock() - return m(*args, **kwargs) - def create_mock(self): entry = self.name parent = self.parent @@ -2333,19 +2289,10 @@ def _must_skip(spec, entry, is_type): else: return False - # shouldn't get here unless function is a dynamically provided attribute - # XXXX untested behaviour + # function is a dynamically provided attribute return is_type -def _get_class(obj): - try: - return obj.__class__ - except AttributeError: - # it is possible for objects to have no __class__ - return type(obj) - - class _SpecState(object): def __init__(self, spec, spec_set=False, parent=None, @@ -2372,25 +2319,12 @@ def __init__(self, spec, spec_set=False, parent=None, file_spec = None -def _iterate_read_data(read_data): - # Helper for mock_open: - # Retrieve lines from read_data via a generator so that separate calls to - # readline, read, and readlines are properly interleaved - sep = b'\n' if isinstance(read_data, bytes) else '\n' - data_as_list = [l + sep for l in read_data.split(sep)] - if data_as_list[-1] == sep: - # If the last line ended in a newline, the list comprehension will have an - # extra entry that's just a newline. Remove this. - data_as_list = data_as_list[:-1] +def _to_stream(read_data): + if isinstance(read_data, bytes): + return io.BytesIO(read_data) else: - # If there wasn't an extra newline by itself, then the file being - # emulated doesn't have a newline to end the last line remove the - # newline that our naive format() added - data_as_list[-1] = data_as_list[-1][:-1] - - for line in data_as_list: - yield line + return io.StringIO(read_data) def mock_open(mock=None, read_data=''): @@ -2405,20 +2339,23 @@ def mock_open(mock=None, read_data=''): `read_data` is a string for the `read`, `readline` and `readlines` of the file handle to return. This is an empty string by default. """ + _read_data = _to_stream(read_data) + _state = [_read_data, None] + def _readlines_side_effect(*args, **kwargs): if handle.readlines.return_value is not None: return handle.readlines.return_value - return list(_state[0]) + return _state[0].readlines(*args, **kwargs) def _read_side_effect(*args, **kwargs): if handle.read.return_value is not None: return handle.read.return_value - return type(read_data)().join(_state[0]) + return _state[0].read(*args, **kwargs) - def _readline_side_effect(): + def _readline_side_effect(*args, **kwargs): yield from _iter_side_effect() while True: - yield type(read_data)() + yield _state[0].readline(*args, **kwargs) def _iter_side_effect(): if handle.readline.return_value is not None: @@ -2438,8 +2375,6 @@ def _iter_side_effect(): handle = MagicMock(spec=file_spec) handle.__enter__.return_value = handle - _state = [_iterate_read_data(read_data), None] - handle.write.return_value = None handle.read.return_value = None handle.readline.return_value = None @@ -2452,7 +2387,7 @@ def _iter_side_effect(): handle.__iter__.side_effect = _iter_side_effect def reset_data(*args, **kwargs): - _state[0] = _iterate_read_data(read_data) + _state[0] = _to_stream(read_data) if handle.readline.side_effect == _state[1]: # Only reset the side effect if the user hasn't overridden it. _state[1] = _readline_side_effect() diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index 2b475c2d856..443b689dbea 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -403,6 +403,22 @@ class Module(object): self.assertEqual(str(e.exception), 'CleanUpExc') self.assertEqual(unittest.case._module_cleanups, []) + def test_addModuleCleanup_arg_errors(self): + cleanups = [] + def cleanup(*args, **kwargs): + cleanups.append((args, kwargs)) + + class Module(object): + unittest.addModuleCleanup(cleanup, 1, 2, function='hello') + with self.assertWarns(DeprecationWarning): + unittest.addModuleCleanup(function=cleanup, arg='hello') + with self.assertRaises(TypeError): + unittest.addModuleCleanup() + unittest.case.doModuleCleanups() + self.assertEqual(cleanups, + [((), {'arg': 'hello'}), + ((1, 2), {'function': 'hello'})]) + def test_run_module_cleanUp(self): blowUp = True ordering = [] @@ -547,6 +563,50 @@ def tearDownClass(cls): 'tearDownModule', 'cleanup_good']) self.assertEqual(unittest.case._module_cleanups, []) + def test_addClassCleanup_arg_errors(self): + cleanups = [] + def cleanup(*args, **kwargs): + cleanups.append((args, kwargs)) + + class TestableTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.addClassCleanup(cleanup, 1, 2, function=3, cls=4) + with self.assertRaises(TypeError): + cls.addClassCleanup(function=cleanup, arg='hello') + def testNothing(self): + pass + + with self.assertRaises(TypeError): + TestableTest.addClassCleanup() + with self.assertRaises(TypeError): + unittest.TestCase.addCleanup(cls=TestableTest(), function=cleanup) + runTests(TestableTest) + self.assertEqual(cleanups, + [((1, 2), {'function': 3, 'cls': 4})]) + + def test_addCleanup_arg_errors(self): + cleanups = [] + def cleanup(*args, **kwargs): + cleanups.append((args, kwargs)) + + class TestableTest(unittest.TestCase): + def setUp(self2): + self2.addCleanup(cleanup, 1, 2, function=3, self=4) + with self.assertWarns(DeprecationWarning): + self2.addCleanup(function=cleanup, arg='hello') + def testNothing(self): + pass + + with self.assertRaises(TypeError): + TestableTest().addCleanup() + with self.assertRaises(TypeError): + unittest.TestCase.addCleanup(self=TestableTest(), function=cleanup) + runTests(TestableTest) + self.assertEqual(cleanups, + [((), {'arg': 'hello'}), + ((1, 2), {'function': 3, 'self': 4})]) + def test_with_errors_in_addClassCleanup(self): ordering = [] diff --git a/Lib/unittest/test/testmock/support.py b/Lib/unittest/test/testmock/support.py index f146be244e9..49986d65dc4 100644 --- a/Lib/unittest/test/testmock/support.py +++ b/Lib/unittest/test/testmock/support.py @@ -9,8 +9,7 @@ def is_instance(obj, klass): class SomeClass(object): class_attribute = None - def wibble(self): - pass + def wibble(self): pass class X(object): diff --git a/Lib/unittest/test/testmock/testcallable.py b/Lib/unittest/test/testmock/testcallable.py index 34474c4c816..5eadc007049 100644 --- a/Lib/unittest/test/testmock/testcallable.py +++ b/Lib/unittest/test/testmock/testcallable.py @@ -98,8 +98,7 @@ def test_patch_spec_set_instance(self): def test_patch_spec_callable_class(self): class CallableX(X): - def __call__(self): - pass + def __call__(self): pass class Sub(CallableX): pass diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 9f1bf2676bf..301bca430c1 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -5,19 +5,16 @@ from unittest.mock import ( call, _Call, create_autospec, MagicMock, - Mock, ANY, _CallList, patch, PropertyMock + Mock, ANY, _CallList, patch, PropertyMock, _callable ) from datetime import datetime from functools import partial class SomeClass(object): - def one(self, a, b): - pass - def two(self): - pass - def three(self, a=None): - pass + def one(self, a, b): pass + def two(self): pass + def three(self, a=None): pass @@ -48,12 +45,9 @@ def test_any_and_datetime(self): def test_any_mock_calls_comparison_order(self): mock = Mock() - d = datetime.now() class Foo(object): - def __eq__(self, other): - return False - def __ne__(self, other): - return True + def __eq__(self, other): pass + def __ne__(self, other): pass for d in datetime.now(), Foo(): mock.reset_mock() @@ -378,8 +372,7 @@ def test_basic(self): def test_create_autospec_return_value(self): - def f(): - pass + def f(): pass mock = create_autospec(f, return_value='foo') self.assertEqual(mock(), 'foo') @@ -399,8 +392,7 @@ def test_autospec_reset_mock(self): def test_mocking_unbound_methods(self): class Foo(object): - def foo(self, foo): - pass + def foo(self, foo): pass p = patch.object(Foo, 'foo') mock_foo = p.start() Foo().foo(1) @@ -408,24 +400,6 @@ def foo(self, foo): mock_foo.assert_called_with(1) - def test_create_autospec_unbound_methods(self): - # see mock issue 128 - # this is expected to fail until the issue is fixed - return - class Foo(object): - def foo(self): - pass - - klass = create_autospec(Foo) - instance = klass() - self.assertRaises(TypeError, instance.foo, 1) - - # Note: no type checking on the "self" parameter - klass.foo(1) - klass.foo.assert_called_with(1) - self.assertRaises(TypeError, klass.foo) - - def test_create_autospec_keyword_arguments(self): class Foo(object): a = 3 @@ -434,8 +408,7 @@ class Foo(object): def test_create_autospec_keyword_only_arguments(self): - def foo(a, *, b=None): - pass + def foo(a, *, b=None): pass m = create_autospec(foo) m(1) @@ -448,8 +421,7 @@ def foo(a, *, b=None): def test_function_as_instance_attribute(self): obj = SomeClass() - def f(a): - pass + def f(a): pass obj.f = f mock = create_autospec(obj) @@ -485,13 +457,57 @@ class Sub(SomeClass): self._check_someclass_mock(mock) + def test_spec_has_descriptor_returning_function(self): + + class CrazyDescriptor(object): + + def __get__(self, obj, type_): + if obj is None: + return lambda x: None + + class MyClass(object): + + some_attr = CrazyDescriptor() + + mock = create_autospec(MyClass) + mock.some_attr(1) + with self.assertRaises(TypeError): + mock.some_attr() + with self.assertRaises(TypeError): + mock.some_attr(1, 2) + + + def test_spec_has_function_not_in_bases(self): + + class CrazyClass(object): + + def __dir__(self): + return super(CrazyClass, self).__dir__()+['crazy'] + + def __getattr__(self, item): + if item == 'crazy': + return lambda x: x + raise AttributeError(item) + + inst = CrazyClass() + with self.assertRaises(AttributeError): + inst.other + self.assertEqual(inst.crazy(42), 42) + + mock = create_autospec(inst) + mock.crazy(42) + with self.assertRaises(TypeError): + mock.crazy() + with self.assertRaises(TypeError): + mock.crazy(1, 2) + + def test_builtin_functions_types(self): # we could replace builtin functions / methods with a function # with *args / **kwargs signature. Using the builtin method type # as a spec seems to work fairly well though. class BuiltinSubclass(list): - def bar(self, arg): - pass + def bar(self, arg): pass sorted = sorted attr = {} @@ -565,17 +581,13 @@ class Sub(SomeClass): def test_descriptors(self): class Foo(object): @classmethod - def f(cls, a, b): - pass + def f(cls, a, b): pass @staticmethod - def g(a, b): - pass + def g(a, b): pass - class Bar(Foo): - pass + class Bar(Foo): pass - class Baz(SomeClass, Bar): - pass + class Baz(SomeClass, Bar): pass for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()): mock = create_autospec(spec) @@ -588,8 +600,7 @@ class Baz(SomeClass, Bar): def test_recursive(self): class A(object): - def a(self): - pass + def a(self): pass foo = 'foo bar baz' bar = foo @@ -611,11 +622,9 @@ def a(self): def test_spec_inheritance_for_classes(self): class Foo(object): - def a(self, x): - pass + def a(self, x): pass class Bar(object): - def f(self, y): - pass + def f(self, y): pass class_mock = create_autospec(Foo) @@ -695,8 +704,7 @@ def test_builtins(self): def test_function(self): - def f(a, b): - pass + def f(a, b): pass mock = create_autospec(f) self.assertRaises(TypeError, mock) @@ -726,9 +734,10 @@ class RaiserClass(object): def existing(a, b): return a + b + self.assertEqual(RaiserClass.existing(1, 2), 3) s = create_autospec(RaiserClass) self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3)) - s.existing(1, 2) + self.assertEqual(s.existing(1, 2), s.existing.return_value) self.assertRaises(AttributeError, lambda: s.nonexisting) # check we can fetch the raiser attribute and it has no spec @@ -738,8 +747,7 @@ def existing(a, b): def test_signature_class(self): class Foo(object): - def __init__(self, a, b=3): - pass + def __init__(self, a, b=3): pass mock = create_autospec(Foo) @@ -765,10 +773,8 @@ class Foo(object): def test_signature_callable(self): class Callable(object): - def __init__(self, x, y): - pass - def __call__(self, a): - pass + def __init__(self, x, y): pass + def __call__(self, a): pass mock = create_autospec(Callable) mock(1, 2) @@ -824,8 +830,7 @@ class Foo(object): def test_autospec_functions_with_self_in_odd_place(self): class Foo(object): - def f(a, self): - pass + def f(a, self): pass a = create_autospec(Foo) a.f(10) @@ -842,12 +847,9 @@ def __init__(self, value): self.value = value def __get__(self, obj, cls=None): - if obj is None: - return self - return self.value + return self - def __set__(self, obj, value): - pass + def __set__(self, obj, value): pass class MyProperty(property): pass @@ -856,12 +858,10 @@ class Foo(object): __slots__ = ['slot'] @property - def prop(self): - return 3 + def prop(self): pass @MyProperty - def subprop(self): - return 4 + def subprop(self): pass desc = Descriptor(42) @@ -913,14 +913,13 @@ def __getattr__(self, attribute): def test_spec_inspect_signature(self): - def myfunc(x, y): - pass + def myfunc(x, y): pass mock = create_autospec(myfunc) mock(1, 2) mock(x=1, y=2) - self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc)) + self.assertEqual(inspect.signature(mock), inspect.signature(myfunc)) self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)]) self.assertRaises(TypeError, mock, 1) @@ -930,16 +929,53 @@ def test_spec_inspect_signature_annotations(self): def foo(a: int, b: int=10, *, c:int) -> int: return a + b + c + self.assertEqual(foo(1, 2 , c=3), 6) mock = create_autospec(foo) mock(1, 2, c=3) mock(1, c=3) - self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(foo)) + self.assertEqual(inspect.signature(mock), inspect.signature(foo)) self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)]) self.assertRaises(TypeError, mock, 1) self.assertRaises(TypeError, mock, 1, 2, 3, c=4) + def test_spec_function_no_name(self): + func = lambda: 'nope' + mock = create_autospec(func) + self.assertEqual(mock.__name__, 'funcopy') + + + def test_spec_function_assert_has_calls(self): + def f(a): pass + mock = create_autospec(f) + mock(1) + mock.assert_has_calls([call(1)]) + with self.assertRaises(AssertionError): + mock.assert_has_calls([call(2)]) + + + def test_spec_function_assert_any_call(self): + def f(a): pass + mock = create_autospec(f) + mock(1) + mock.assert_any_call(1) + with self.assertRaises(AssertionError): + mock.assert_any_call(2) + + + def test_spec_function_reset_mock(self): + def f(a): pass + rv = Mock() + mock = create_autospec(f, return_value=rv) + mock(1)(2) + self.assertEqual(mock.mock_calls, [call(1)]) + self.assertEqual(rv.mock_calls, [call(2)]) + mock.reset_mock() + self.assertEqual(mock.mock_calls, []) + self.assertEqual(rv.mock_calls, []) + + class TestCallList(unittest.TestCase): def test_args_list_contains_call_list(self): @@ -1011,5 +1047,40 @@ def test_propertymock_returnvalue(self): self.assertNotIsInstance(returned, PropertyMock) +class TestCallablePredicate(unittest.TestCase): + + def test_type(self): + for obj in [str, bytes, int, list, tuple, SomeClass]: + self.assertTrue(_callable(obj)) + + def test_call_magic_method(self): + class Callable: + def __call__(self): pass + instance = Callable() + self.assertTrue(_callable(instance)) + + def test_staticmethod(self): + class WithStaticMethod: + @staticmethod + def staticfunc(): pass + self.assertTrue(_callable(WithStaticMethod.staticfunc)) + + def test_non_callable_staticmethod(self): + class BadStaticMethod: + not_callable = staticmethod(None) + self.assertFalse(_callable(BadStaticMethod.not_callable)) + + def test_classmethod(self): + class WithClassMethod: + @classmethod + def classfunc(cls): pass + self.assertTrue(_callable(WithClassMethod.classfunc)) + + def test_non_callable_classmethod(self): + class BadClassMethod: + not_callable = classmethod(None) + self.assertFalse(_callable(BadClassMethod.not_callable)) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/unittest/test/testmock/testmagicmethods.py index 69dfe60f7ea..130a3397ba0 100644 --- a/Lib/unittest/test/testmock/testmagicmethods.py +++ b/Lib/unittest/test/testmock/testmagicmethods.py @@ -305,8 +305,7 @@ def test_magic_methods_fspath(self): def test_magic_methods_and_spec(self): class Iterable(object): - def __iter__(self): - pass + def __iter__(self): pass mock = Mock(spec=Iterable) self.assertRaises(AttributeError, lambda: mock.__iter__) @@ -330,8 +329,7 @@ def set_int(): def test_magic_methods_and_spec_set(self): class Iterable(object): - def __iter__(self): - pass + def __iter__(self): pass mock = Mock(spec_set=Iterable) self.assertRaises(AttributeError, lambda: mock.__iter__) diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index 66a5720d143..5f917dd20f1 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -28,16 +28,13 @@ def next(self): class Something(object): - def meth(self, a, b, c, d=None): - pass + def meth(self, a, b, c, d=None): pass @classmethod - def cmeth(cls, a, b, c, d=None): - pass + def cmeth(cls, a, b, c, d=None): pass @staticmethod - def smeth(a, b, c, d=None): - pass + def smeth(a, b, c, d=None): pass class MockTest(unittest.TestCase): @@ -83,6 +80,21 @@ def test_return_value_in_constructor(self): "return value in constructor not honoured") + def test_change_return_value_via_delegate(self): + def f(): pass + mock = create_autospec(f) + mock.mock.return_value = 1 + self.assertEqual(mock(), 1) + + + def test_change_side_effect_via_delegate(self): + def f(): pass + mock = create_autospec(f) + mock.mock.side_effect = TypeError() + with self.assertRaises(TypeError): + mock() + + def test_repr(self): mock = Mock(name='foo') self.assertIn('foo', repr(mock)) @@ -161,8 +173,7 @@ def test_autospec_side_effect(self): results = [1, 2, 3] def effect(): return results.pop() - def f(): - pass + def f(): pass mock = create_autospec(f) mock.side_effect = [1, 2, 3] @@ -177,28 +188,12 @@ def f(): def test_autospec_side_effect_exception(self): # Test for issue 23661 - def f(): - pass + def f(): pass mock = create_autospec(f) mock.side_effect = ValueError('Bazinga!') self.assertRaisesRegex(ValueError, 'Bazinga!', mock) - @unittest.skipUnless('java' in sys.platform, - 'This test only applies to Jython') - def test_java_exception_side_effect(self): - import java - mock = Mock(side_effect=java.lang.RuntimeException("Boom!")) - - # can't use assertRaises with java exceptions - try: - mock(1, 2, fish=3) - except java.lang.RuntimeException: - pass - else: - self.fail('java exception not raised') - mock.assert_called_with(1,2, fish=3) - def test_reset_mock(self): parent = Mock() @@ -355,8 +350,7 @@ def test_assert_called_with_any(self): def test_assert_called_with_function_spec(self): - def f(a, b, c, d=None): - pass + def f(a, b, c, d=None): pass mock = Mock(spec=f) @@ -424,8 +418,7 @@ def test_assert_called_once_with_call_list(self): def test_assert_called_once_with_function_spec(self): - def f(a, b, c, d=None): - pass + def f(a, b, c, d=None): pass mock = Mock(spec=f) @@ -529,8 +522,7 @@ def test_from_spec(self): class Something(object): x = 3 __something__ = None - def y(self): - pass + def y(self): pass def test_attributes(mock): # should work @@ -616,8 +608,7 @@ def method(self): def test_customize_wrapped_object_with_side_effect_iterable(self): class Real(object): - def method(self): - raise NotImplementedError() + def method(self): pass real = Real() mock = Mock(wraps=real) @@ -630,8 +621,7 @@ def method(self): def test_customize_wrapped_object_with_side_effect_exception(self): class Real(object): - def method(self): - raise NotImplementedError() + def method(self): pass real = Real() mock = Mock(wraps=real) @@ -642,9 +632,7 @@ def method(self): def test_customize_wrapped_object_with_side_effect_function(self): class Real(object): - def method(self): - raise NotImplementedError() - + def method(self): pass def side_effect(): return sentinel.VALUE @@ -657,8 +645,7 @@ def side_effect(): def test_customize_wrapped_object_with_return_value(self): class Real(object): - def method(self): - raise NotImplementedError() + def method(self): pass real = Real() mock = Mock(wraps=real) @@ -670,8 +657,7 @@ def method(self): def test_customize_wrapped_object_with_return_value_and_side_effect(self): # side_effect should always take precedence over return_value. class Real(object): - def method(self): - raise NotImplementedError() + def method(self): pass real = Real() mock = Mock(wraps=real) @@ -686,8 +672,7 @@ def method(self): def test_customize_wrapped_object_with_return_value_and_side_effect2(self): # side_effect can return DEFAULT to default to return_value class Real(object): - def method(self): - raise NotImplementedError() + def method(self): pass real = Real() mock = Mock(wraps=real) @@ -699,8 +684,7 @@ def method(self): def test_customize_wrapped_object_with_return_value_and_side_effect_default(self): class Real(object): - def method(self): - raise NotImplementedError() + def method(self): pass real = Real() mock = Mock(wraps=real) @@ -779,6 +763,26 @@ class X(object): self.assertIsInstance(mock, X) + def test_spec_class_no_object_base(self): + class X: + pass + + mock = Mock(spec=X) + self.assertIsInstance(mock, X) + + mock = Mock(spec=X()) + self.assertIsInstance(mock, X) + + self.assertIs(mock.__class__, X) + self.assertEqual(Mock().__class__.__name__, 'Mock') + + mock = Mock(spec_set=X) + self.assertIsInstance(mock, X) + + mock = Mock(spec_set=X()) + self.assertIsInstance(mock, X) + + def test_setting_attribute_with_spec_set(self): class X(object): y = 3 @@ -885,6 +889,15 @@ def test_filter_dir(self): patcher.stop() + def test_dir_does_not_include_deleted_attributes(self): + mock = Mock() + mock.child.return_value = 1 + + self.assertIn('child', dir(mock)) + del mock.child + self.assertNotIn('child', dir(mock)) + + def test_configure_mock(self): mock = Mock(foo='bar') self.assertEqual(mock.foo, 'bar') @@ -908,15 +921,9 @@ def test_configure_mock(self): def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs): # needed because assertRaisesRegex doesn't work easily with newlines - try: + with self.assertRaises(exception) as context: func(*args, **kwargs) - except: - instance = sys.exc_info()[1] - self.assertIsInstance(instance, exception) - else: - self.fail('Exception %r not raised' % (exception,)) - - msg = str(instance) + msg = str(context.exception) self.assertEqual(msg, message) @@ -1105,6 +1112,18 @@ def test_mock_call_repr(self): self.assertEqual(repr(m.mock_calls[2]), 'call.foo().bar().baz.bob()') + def test_mock_call_repr_loop(self): + m = Mock() + m.foo = m + repr(m.foo()) + self.assertRegex(repr(m.foo()), r"") + + + def test_mock_calls_contains(self): + m = Mock() + self.assertFalse([call()] in m.mock_calls) + + def test_subclassing(self): class Subclass(Mock): pass @@ -1318,8 +1337,7 @@ def test_assert_has_calls(self): def test_assert_has_calls_with_function_spec(self): - def f(a, b, c, d=None): - pass + def f(a, b, c, d=None): pass mock = Mock(spec=f) @@ -1377,8 +1395,7 @@ def test_assert_any_call(self): def test_assert_any_call_with_function_spec(self): - def f(a, b, c, d=None): - pass + def f(a, b, c, d=None): pass mock = Mock(spec=f) @@ -1397,8 +1414,7 @@ def f(a, b, c, d=None): def test_mock_calls_create_autospec(self): - def f(a, b): - pass + def f(a, b): pass obj = Iter() obj.f = f @@ -1419,6 +1435,21 @@ def test_create_autospec_with_name(self): m = mock.create_autospec(object(), name='sweet_func') self.assertIn('sweet_func', repr(m)) + #Issue23078 + def test_create_autospec_classmethod_and_staticmethod(self): + class TestClass: + @classmethod + def class_method(cls): pass + + @staticmethod + def static_method(): pass + for method in ('class_method', 'static_method'): + with self.subTest(method=method): + mock_method = mock.create_autospec(getattr(TestClass, method)) + mock_method() + mock_method.assert_called_once_with() + self.assertRaises(TypeError, mock_method, 'extra_arg') + #Issue21238 def test_mock_unsafe(self): m = Mock() @@ -1837,8 +1868,7 @@ def test_parent_attribute_of_call(self): def test_parent_propagation_with_create_autospec(self): - def foo(a, b): - pass + def foo(a, b): pass mock = Mock() mock.child = create_autospec(foo) @@ -1847,6 +1877,45 @@ def foo(a, b): self.assertRaises(TypeError, mock.child, 1) self.assertEqual(mock.mock_calls, [call.child(1, 2)]) + def test_isinstance_under_settrace(self): + # bpo-36593 : __class__ is not set for a class that has __class__ + # property defined when it's used with sys.settrace(trace) set. + # Delete the module to force reimport with tracing function set + # restore the old reference later since there are other tests that are + # dependent on unittest.mock.patch. In testpatch.PatchTest + # test_patch_dict_test_prefix and test_patch_test_prefix not restoring + # causes the objects patched to go out of sync + + old_patch = unittest.mock.patch + + # Directly using __setattr__ on unittest.mock causes current imported + # reference to be updated. Use a lambda so that during cleanup the + # re-imported new reference is updated. + self.addCleanup(lambda patch: setattr(unittest.mock, 'patch', patch), + old_patch) + + with patch.dict('sys.modules'): + del sys.modules['unittest.mock'] + + # This trace will stop coverage being measured ;-) + def trace(frame, event, arg): # pragma: no cover + return trace + + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(trace) + + from unittest.mock import ( + Mock, MagicMock, NonCallableMock, NonCallableMagicMock + ) + + mocks = [ + Mock, MagicMock, NonCallableMock, NonCallableMagicMock + ] + + for mock in mocks: + obj = mock(spec=Something) + self.assertIsInstance(obj, Something) + if __name__ == '__main__': unittest.main() diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index c484adb6050..3295c5b2420 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -43,23 +43,24 @@ def __delattr__(self, name): class Foo(object): - def __init__(self, a): - pass - def f(self, a): - pass - def g(self): - pass + def __init__(self, a): pass + def f(self, a): pass + def g(self): pass foo = 'bar' + @staticmethod + def static_method(): pass + + @classmethod + def class_method(cls): pass + class Bar(object): - def a(self): - pass + def a(self): pass foo_name = '%s.Foo' % __name__ -def function(a, b=Foo): - pass +def function(a, b=Foo): pass class Container(object): @@ -362,31 +363,19 @@ def test(): def test_patch_wont_create_by_default(self): - try: + with self.assertRaises(AttributeError): @patch('%s.frooble' % builtin_string, sentinel.Frooble) - def test(): - self.assertEqual(frooble, sentinel.Frooble) + def test(): pass test() - except AttributeError: - pass - else: - self.fail('Patching non existent attributes should fail') - self.assertRaises(NameError, lambda: frooble) def test_patchobject_wont_create_by_default(self): - try: + with self.assertRaises(AttributeError): @patch.object(SomeClass, 'ord', sentinel.Frooble) - def test(): - self.fail('Patching non existent attributes should fail') - + def test(): pass test() - except AttributeError: - pass - else: - self.fail('Patching non existent attributes should fail') self.assertFalse(hasattr(SomeClass, 'ord')) @@ -476,6 +465,9 @@ class Something(object): attribute = sentinel.Original class Foo(object): + + test_class_attr = 'whatever' + def test_method(other_self, mock_something): self.assertEqual(PTModule.something, mock_something, "unpatched") @@ -634,8 +626,7 @@ def test_name_preserved(self): @patch('%s.SomeClass' % __name__, object(), autospec=True) @patch.object(SomeClass, object()) @patch.dict(foo) - def some_name(): - pass + def some_name(): pass self.assertEqual(some_name.__name__, 'some_name') @@ -646,12 +637,9 @@ def test_patch_with_exception(self): @patch.dict(foo, {'a': 'b'}) def test(): raise NameError('Konrad') - try: + + with self.assertRaises(NameError): test() - except NameError: - pass - else: - self.fail('NameError not raised by test') self.assertEqual(foo, {}) @@ -681,49 +669,6 @@ def test(): support.target = original - def test_patch_descriptor(self): - # would be some effort to fix this - we could special case the - # builtin descriptors: classmethod, property, staticmethod - return - class Nothing(object): - foo = None - - class Something(object): - foo = {} - - @patch.object(Nothing, 'foo', 2) - @classmethod - def klass(cls): - self.assertIs(cls, Something) - - @patch.object(Nothing, 'foo', 2) - @staticmethod - def static(arg): - return arg - - @patch.dict(foo) - @classmethod - def klass_dict(cls): - self.assertIs(cls, Something) - - @patch.dict(foo) - @staticmethod - def static_dict(arg): - return arg - - # these will raise exceptions if patching descriptors is broken - self.assertEqual(Something.static('f00'), 'f00') - Something.klass() - self.assertEqual(Something.static_dict('f00'), 'f00') - Something.klass_dict() - - something = Something() - self.assertEqual(something.static('f00'), 'f00') - something.klass() - self.assertEqual(something.static_dict('f00'), 'f00') - something.klass_dict() - - def test_patch_spec_set(self): @patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True) def test(MockClass): @@ -772,10 +717,18 @@ def test_patch_start_stop(self): def test_stop_without_start(self): + # bpo-36366: calling stop without start will return None. + patcher = patch(foo_name, 'bar', 3) + self.assertIsNone(patcher.stop()) + + + def test_stop_idempotent(self): + # bpo-36366: calling stop on an already stopped patch will return None. patcher = patch(foo_name, 'bar', 3) - # calling stop without start used to produce a very obscure error - self.assertRaises(RuntimeError, patcher.stop) + patcher.start() + patcher.stop() + self.assertIsNone(patcher.stop()) def test_patchobject_start_stop(self): @@ -915,17 +868,13 @@ def test_patch_dict_keyword_args(self): def test_autospec(self): class Boo(object): - def __init__(self, a): - pass - def f(self, a): - pass - def g(self): - pass + def __init__(self, a): pass + def f(self, a): pass + def g(self): pass foo = 'bar' class Bar(object): - def a(self): - pass + def a(self): pass def _test(mock): mock(1) @@ -1015,6 +964,18 @@ def test(mock_function): self.assertEqual(result, 3) + def test_autospec_staticmethod(self): + with patch('%s.Foo.static_method' % __name__, autospec=True) as method: + Foo.static_method() + method.assert_called_once_with() + + + def test_autospec_classmethod(self): + with patch('%s.Foo.class_method' % __name__, autospec=True) as method: + Foo.class_method() + method.assert_called_once_with() + + def test_autospec_with_new(self): patcher = patch('%s.function' % __name__, new=3, autospec=True) self.assertRaises(TypeError, patcher.start) @@ -1284,7 +1245,6 @@ def test(f, foo): def test_patch_multiple_create_mocks_different_order(self): - # bug revealed by Jython! original_f = Foo.f original_g = Foo.g @@ -1461,20 +1421,17 @@ def test_nested_patch_failure(self): @patch.object(Foo, 'g', 1) @patch.object(Foo, 'missing', 1) @patch.object(Foo, 'f', 1) - def thing1(): - pass + def thing1(): pass @patch.object(Foo, 'missing', 1) @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) - def thing2(): - pass + def thing2(): pass @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) @patch.object(Foo, 'missing', 1) - def thing3(): - pass + def thing3(): pass for func in thing1, thing2, thing3: self.assertRaises(AttributeError, func) @@ -1493,20 +1450,17 @@ def crasher(): @patch.object(Foo, 'g', 1) @patch.object(Foo, 'foo', new_callable=crasher) @patch.object(Foo, 'f', 1) - def thing1(): - pass + def thing1(): pass @patch.object(Foo, 'foo', new_callable=crasher) @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) - def thing2(): - pass + def thing2(): pass @patch.object(Foo, 'g', 1) @patch.object(Foo, 'f', 1) @patch.object(Foo, 'foo', new_callable=crasher) - def thing3(): - pass + def thing3(): pass for func in thing1, thing2, thing3: self.assertRaises(NameError, func) @@ -1532,8 +1486,7 @@ def test_patch_multiple_failure(self): patcher.additional_patchers = additionals @patcher - def func(): - pass + def func(): pass self.assertRaises(AttributeError, func) self.assertEqual(Foo.f, original_f) @@ -1561,8 +1514,7 @@ def crasher(): patcher.additional_patchers = additionals @patcher - def func(): - pass + def func(): pass self.assertRaises(NameError, func) self.assertEqual(Foo.f, original_f) @@ -1871,5 +1823,36 @@ def foo(*a, x=0): self.assertEqual(foo(), 1) self.assertEqual(foo(), 0) + def test_dotted_but_module_not_loaded(self): + # This exercises the AttributeError branch of _dot_lookup. + + # make sure it's there + import unittest.test.testmock.support + # now make sure it's not: + with patch.dict('sys.modules'): + del sys.modules['unittest.test.testmock.support'] + del sys.modules['unittest.test.testmock'] + del sys.modules['unittest.test'] + del sys.modules['unittest'] + + # now make sure we can patch based on a dotted path: + @patch('unittest.test.testmock.support.X') + def test(mock): + pass + test() + + + def test_invalid_target(self): + with self.assertRaises(TypeError): + patch('') + + + def test_cant_set_kwargs_when_passing_a_mock(self): + @patch('unittest.test.testmock.support.X', new=object(), x=1) + def test(): pass + with self.assertRaises(TypeError): + test() + + if __name__ == '__main__': unittest.main() diff --git a/Lib/unittest/test/testmock/testsealable.py b/Lib/unittest/test/testmock/testsealable.py index 0e72b32411c..59f52338d41 100644 --- a/Lib/unittest/test/testmock/testsealable.py +++ b/Lib/unittest/test/testmock/testsealable.py @@ -3,15 +3,10 @@ class SampleObject: - def __init__(self): - self.attr_sample1 = 1 - self.attr_sample2 = 1 - def method_sample1(self): - pass + def method_sample1(self): pass - def method_sample2(self): - pass + def method_sample2(self): pass class TestSealable(unittest.TestCase): diff --git a/Lib/unittest/test/testmock/testwith.py b/Lib/unittest/test/testmock/testwith.py index ec4e540dcfd..5172c222d97 100644 --- a/Lib/unittest/test/testmock/testwith.py +++ b/Lib/unittest/test/testmock/testwith.py @@ -10,6 +10,8 @@ something_else = sentinel.SomethingElse +class SampleException(Exception): pass + class WithTest(unittest.TestCase): @@ -20,14 +22,10 @@ def test_with_statement(self): def test_with_statement_exception(self): - try: + with self.assertRaises(SampleException): with patch('%s.something' % __name__, sentinel.Something2): self.assertEqual(something, sentinel.Something2, "unpatched") - raise Exception('pow') - except Exception: - pass - else: - self.fail("patch swallowed exception") + raise SampleException() self.assertEqual(something, sentinel.Something) @@ -128,8 +126,7 @@ def test_dict_context_manager(self): def test_double_patch_instance_method(self): class C: - def f(self): - pass + def f(self): pass c = C() @@ -286,7 +283,12 @@ def test_mock_open_read_with_argument(self): # for mocks returned by mock_open some_data = 'foo\nbar\nbaz' mock = mock_open(read_data=some_data) - self.assertEqual(mock().read(10), some_data) + self.assertEqual(mock().read(10), some_data[:10]) + self.assertEqual(mock().read(10), some_data[:10]) + + f = mock() + self.assertEqual(f.read(10), some_data[:10]) + self.assertEqual(f.read(10), some_data[10:]) def test_interleaved_reads(self): diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 8b6c9b10609..dfba704144e 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -402,13 +402,16 @@ def _checknetloc(netloc): # looking for characters like \u2100 that expand to 'a/c' # IDNA uses NFKC equivalence, so normalize for this check import unicodedata - netloc2 = unicodedata.normalize('NFKC', netloc) - if netloc == netloc2: + n = netloc.rpartition('@')[2] # ignore anything to the left of '@' + n = n.replace(':', '') # ignore characters already included + n = n.replace('#', '') # but not the surrounding text + n = n.replace('?', '') + netloc2 = unicodedata.normalize('NFKC', n) + if n == netloc2: return - _, _, netloc = netloc.rpartition('@') # anything to the left of '@' is okay for c in '/?#@:': if c in netloc2: - raise ValueError("netloc '" + netloc2 + "' contains invalid " + + raise ValueError("netloc '" + netloc + "' contains invalid " + "characters under NFKC normalization") def urlsplit(url, scheme='', allow_fragments=True): @@ -785,25 +788,32 @@ def quote(string, safe='/', encoding=None, errors=None): """quote('abc def') -> 'abc%20def' Each part of a URL, e.g. the path info, the query, etc., has a - different set of reserved characters that must be quoted. + different set of reserved characters that must be quoted. The + quote function offers a cautious (not minimal) way to quote a + string for most of these parts. - RFC 3986 Uniform Resource Identifiers (URI): Generic Syntax lists - the following reserved characters. + RFC 3986 Uniform Resource Identifier (URI): Generic Syntax lists + the following (un)reserved characters. - reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | - "$" | "," | "~" + unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + reserved = gen-delims / sub-delims + gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" - Each of these characters is reserved in some component of a URL, + Each of the reserved characters is reserved in some component of a URL, but not necessarily in all of them. - Python 3.7 updates from using RFC 2396 to RFC 3986 to quote URL strings. - Now, "~" is included in the set of reserved characters. + The quote function %-escapes all characters that are neither in the + unreserved chars ("always safe") nor the additional chars set via the + safe arg. - By default, the quote function is intended for quoting the path - section of a URL. Thus, it will not encode '/'. This character - is reserved, but in typical usage the quote function is being - called on a path where the existing slash characters are used as - reserved characters. + The default for the safe arg is '/'. The character is reserved, but in + typical usage the quote function is being called on a path where the + existing slash characters are to be preserved. + + Python 3.7 updates from using RFC 2396 to RFC 3986 to quote URL strings. + Now, "~" is included in the set of unreserved characters. string and safe may be either str or bytes objects. encoding and errors must not be specified if string is a bytes object. diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 9a3d399f018..df2ff06f0fc 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -426,8 +426,7 @@ def remove_header(self, header_name): self.unredirected_hdrs.pop(header_name, None) def header_items(self): - hdrs = self.unredirected_hdrs.copy() - hdrs.update(self.headers) + hdrs = {**self.unredirected_hdrs, **self.headers} return list(hdrs.items()) class OpenerDirector: diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 5e6d375e95a..4a49b240b8e 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -195,6 +195,9 @@ def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): src = os.path.join(os.path.dirname(src), basename + ext) else: src = srcfn + if not os.path.exists(src): + logger.warning('Unable to copy %r', src) + return shutil.copyfile(src, dst) diff --git a/Lib/venv/scripts/nt/activate.bat b/Lib/venv/scripts/nt/activate.bat index 126049f495f..da831bb42c7 100644 --- a/Lib/venv/scripts/nt/activate.bat +++ b/Lib/venv/scripts/nt/activate.bat @@ -1,7 +1,7 @@ @echo off rem This file is UTF-8 encoded, so we need to update the current code page while executing it -for /f "tokens=2 delims=:" %%a in ('"%SystemRoot%\System32\chcp.com"') do ( +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( set "_OLD_CODEPAGE=%%a" ) if defined _OLD_CODEPAGE ( diff --git a/Lib/weakref.py b/Lib/weakref.py index 753f07291e2..1eeb7b0a0b4 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -527,7 +527,33 @@ class finalize: class _Info: __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index") - def __init__(self, obj, func, *args, **kwargs): + def __init__(*args, **kwargs): + if len(args) >= 3: + self, obj, func, *args = args + elif not args: + raise TypeError("descriptor '__init__' of 'finalize' object " + "needs an argument") + else: + if 'func' not in kwargs: + raise TypeError('finalize expected at least 2 positional ' + 'arguments, got %d' % (len(args)-1)) + func = kwargs.pop('func') + if len(args) >= 2: + self, obj, *args = args + import warnings + warnings.warn("Passing 'func' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + if 'obj' not in kwargs: + raise TypeError('finalize expected at least 2 positional ' + 'arguments, got %d' % (len(args)-1)) + obj = kwargs.pop('obj') + self, *args = args + import warnings + warnings.warn("Passing 'obj' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + args = tuple(args) + if not self._registered_with_atexit: # We may register the exit function more than once because # of a thread race, but that is harmless @@ -543,6 +569,7 @@ def __init__(self, obj, func, *args, **kwargs): info.index = next(self._index_iter) self._registry[self] = info finalize._dirty = True + __init__.__text_signature__ = '($self, obj, func, /, *args, **kwargs)' def __call__(self, _=None): """If alive then mark as dead and return func(*args, **kwargs); diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index 28ed9b7a6d0..834073d5009 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -136,6 +136,10 @@ def run(self, application): self.setup_environ() self.result = application(self.environ, self.start_response) self.finish_response() + except (ConnectionAbortedError, BrokenPipeError, ConnectionResetError): + # We expect the client to close the connection abruptly from time + # to time. + return except: try: self.handle_error() diff --git a/Lib/wsgiref/validate.py b/Lib/wsgiref/validate.py index 1c00bde220e..48ac0070549 100644 --- a/Lib/wsgiref/validate.py +++ b/Lib/wsgiref/validate.py @@ -77,7 +77,7 @@ * That wsgi.input is used properly: - - .read() is called with zero or one argument + - .read() is called with exactly one argument - That it returns a string diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index 43569ddcbea..464420b7659 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -862,7 +862,8 @@ def writexml(self, writer, indent="", addindent="", newl=""): if self.childNodes: writer.write(">") if (len(self.childNodes) == 1 and - self.childNodes[0].nodeType == Node.TEXT_NODE): + self.childNodes[0].nodeType in ( + Node.TEXT_NODE, Node.CDATA_SECTION_NODE)): self.childNodes[0].writexml(writer, '', '', '') else: writer.write(newl) diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py index ef32917b14d..cfe72f2f9d4 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -71,16 +71,22 @@ ) def xpath_tokenizer(pattern, namespaces=None): + default_namespace = namespaces.get('') if namespaces else None for token in xpath_tokenizer_re.findall(pattern): tag = token[1] - if tag and tag[0] != "{" and ":" in tag: - try: + if tag and tag[0] != "{": + if ":" in tag: prefix, uri = tag.split(":", 1) - if not namespaces: - raise KeyError - yield token[0], "{%s}%s" % (namespaces[prefix], uri) - except KeyError: - raise SyntaxError("prefix %r not found in prefix map" % prefix) from None + try: + if not namespaces: + raise KeyError + yield token[0], "{%s}%s" % (namespaces[prefix], uri) + except KeyError: + raise SyntaxError("prefix %r not found in prefix map" % prefix) from None + elif default_namespace: + yield token[0], "{%s}%s" % (default_namespace, tag) + else: + yield token else: yield token @@ -93,13 +99,70 @@ def get_parent_map(context): parent_map[e] = p return parent_map + + +def _is_wildcard_tag(tag): + return tag[:3] == '{*}' or tag[-2:] == '}*' + + +def _prepare_tag(tag): + _isinstance, _str = isinstance, str + if tag == '{*}*': + # Same as '*', but no comments or processing instructions. + # It can be a surprise that '*' includes those, but there is no + # justification for '{*}*' doing the same. + def select(context, result): + for elem in result: + if _isinstance(elem.tag, _str): + yield elem + elif tag == '{}*': + # Any tag that is not in a namespace. + def select(context, result): + for elem in result: + el_tag = elem.tag + if _isinstance(el_tag, _str) and el_tag[0] != '{': + yield elem + elif tag[:3] == '{*}': + # The tag in any (or no) namespace. + suffix = tag[2:] # '}name' + no_ns = slice(-len(suffix), None) + tag = tag[3:] + def select(context, result): + for elem in result: + el_tag = elem.tag + if el_tag == tag or _isinstance(el_tag, _str) and el_tag[no_ns] == suffix: + yield elem + elif tag[-2:] == '}*': + # Any tag in the given namespace. + ns = tag[:-1] + ns_only = slice(None, len(ns)) + def select(context, result): + for elem in result: + el_tag = elem.tag + if _isinstance(el_tag, _str) and el_tag[ns_only] == ns: + yield elem + else: + raise RuntimeError(f"internal parser error, got {tag}") + return select + + def prepare_child(next, token): tag = token[1] - def select(context, result): - for elem in result: - for e in elem: - if e.tag == tag: - yield e + if _is_wildcard_tag(tag): + select_tag = _prepare_tag(tag) + def select(context, result): + def select_child(result): + for elem in result: + yield from elem + return select_tag(context, select_child(result)) + else: + if tag[:2] == '{}': + tag = tag[2:] # '{}tag' == 'tag' + def select(context, result): + for elem in result: + for e in elem: + if e.tag == tag: + yield e return select def prepare_star(next, token): @@ -124,11 +187,24 @@ def prepare_descendant(next, token): tag = token[1] else: raise SyntaxError("invalid descendant") - def select(context, result): - for elem in result: - for e in elem.iter(tag): - if e is not elem: - yield e + + if _is_wildcard_tag(tag): + select_tag = _prepare_tag(tag) + def select(context, result): + def select_child(result): + for elem in result: + for e in elem.iter(): + if e is not elem: + yield e + return select_tag(context, select_child(result)) + else: + if tag[:2] == '{}': + tag = tag[2:] # '{}tag' == 'tag' + def select(context, result): + for elem in result: + for e in elem.iter(tag): + if e is not elem: + yield e return select def prepare_parent(next, token): @@ -264,10 +340,13 @@ def __init__(self, root): def iterfind(elem, path, namespaces=None): # compile selector pattern - cache_key = (path, None if namespaces is None - else tuple(sorted(namespaces.items()))) if path[-1:] == "/": path = path + "*" # implicit all (FIXME: keep this?) + + cache_key = (path,) + if namespaces: + cache_key += tuple(sorted(namespaces.items())) + try: selector = _cache[cache_key] except KeyError: diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index c1cf483cf56..645e999a0be 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -87,6 +87,7 @@ "XML", "XMLID", "XMLParser", "XMLPullParser", "register_namespace", + "canonicalize", "C14NWriterTarget", ] VERSION = "1.3.0" @@ -169,10 +170,8 @@ def __init__(self, tag, attrib={}, **extra): if not isinstance(attrib, dict): raise TypeError("attrib must be dict, not %s" % ( attrib.__class__.__name__,)) - attrib = attrib.copy() - attrib.update(extra) self.tag = tag - self.attrib = attrib + self.attrib = {**attrib, **extra} self._children = [] def __repr__(self): @@ -451,8 +450,7 @@ def SubElement(parent, tag, attrib={}, **extra): additional attributes given as keyword arguments. """ - attrib = attrib.copy() - attrib.update(extra) + attrib = {**attrib, **extra} element = parent.makeelement(tag, attrib) parent.append(element) return element @@ -1116,6 +1114,7 @@ def _escape_attrib_html(text): # -------------------------------------------------------------------- def tostring(element, encoding=None, method=None, *, + xml_declaration=None, default_namespace=None, short_empty_elements=True): """Generate string representation of XML element. @@ -1124,13 +1123,17 @@ def tostring(element, encoding=None, method=None, *, *element* is an Element instance, *encoding* is an optional output encoding defaulting to US-ASCII, *method* is an optional output which can - be one of "xml" (default), "html", "text" or "c14n". + be one of "xml" (default), "html", "text" or "c14n", *default_namespace* + sets the default XML namespace (for "xmlns"). Returns an (optionally) encoded string containing the XML data. """ stream = io.StringIO() if encoding == 'unicode' else io.BytesIO() - ElementTree(element).write(stream, encoding, method=method, + ElementTree(element).write(stream, encoding, + xml_declaration=xml_declaration, + default_namespace=default_namespace, + method=method, short_empty_elements=short_empty_elements) return stream.getvalue() @@ -1152,10 +1155,14 @@ def tell(self): return len(self.lst) def tostringlist(element, encoding=None, method=None, *, + xml_declaration=None, default_namespace=None, short_empty_elements=True): lst = [] stream = _ListDataStream(lst) - ElementTree(element).write(stream, encoding, method=method, + ElementTree(element).write(stream, encoding, + xml_declaration=xml_declaration, + default_namespace=default_namespace, + method=method, short_empty_elements=short_empty_elements) return lst @@ -1368,12 +1375,30 @@ class TreeBuilder: *element_factory* is an optional element factory which is called to create new Element instances, as necessary. + *comment_factory* is a factory to create comments to be used instead of + the standard factory. If *insert_comments* is false (the default), + comments will not be inserted into the tree. + + *pi_factory* is a factory to create processing instructions to be used + instead of the standard factory. If *insert_pis* is false (the default), + processing instructions will not be inserted into the tree. """ - def __init__(self, element_factory=None): + def __init__(self, element_factory=None, *, + comment_factory=None, pi_factory=None, + insert_comments=False, insert_pis=False): self._data = [] # data collector self._elem = [] # element stack self._last = None # last element + self._root = None # root element self._tail = None # true if we're after an end tag + if comment_factory is None: + comment_factory = Comment + self._comment_factory = comment_factory + self.insert_comments = insert_comments + if pi_factory is None: + pi_factory = ProcessingInstruction + self._pi_factory = pi_factory + self.insert_pis = insert_pis if element_factory is None: element_factory = Element self._factory = element_factory @@ -1381,8 +1406,8 @@ def __init__(self, element_factory=None): def close(self): """Flush builder buffers and return toplevel document Element.""" assert len(self._elem) == 0, "missing end tags" - assert self._last is not None, "missing toplevel element" - return self._last + assert self._root is not None, "missing toplevel element" + return self._root def _flush(self): if self._data: @@ -1411,6 +1436,8 @@ def start(self, tag, attrs): self._last = elem = self._factory(tag, attrs) if self._elem: self._elem[-1].append(elem) + elif self._root is None: + self._root = elem self._elem.append(elem) self._tail = 0 return elem @@ -1429,6 +1456,33 @@ def end(self, tag): self._tail = 1 return self._last + def comment(self, text): + """Create a comment using the comment_factory. + + *text* is the text of the comment. + """ + return self._handle_single( + self._comment_factory, self.insert_comments, text) + + def pi(self, target, text=None): + """Create a processing instruction using the pi_factory. + + *target* is the target name of the processing instruction. + *text* is the data of the processing instruction, or ''. + """ + return self._handle_single( + self._pi_factory, self.insert_pis, target, text) + + def _handle_single(self, factory, insert, *args): + elem = factory(*args) + if insert: + self._flush() + self._last = elem + if self._elem: + self._elem[-1].append(elem) + self._tail = 1 + return elem + # also see ElementTree and TreeBuilder class XMLParser: @@ -1465,6 +1519,10 @@ def __init__(self, *, target=None, encoding=None): parser.StartElementHandler = self._start if hasattr(target, 'end'): parser.EndElementHandler = self._end + if hasattr(target, 'start_ns'): + parser.StartNamespaceDeclHandler = self._start_ns + if hasattr(target, 'end_ns'): + parser.EndNamespaceDeclHandler = self._end_ns if hasattr(target, 'data'): parser.CharacterDataHandler = target.data # miscellaneous callbacks @@ -1506,13 +1564,34 @@ def handler(tag, event=event_name, append=append, append((event, end(tag))) parser.EndElementHandler = handler elif event_name == "start-ns": - def handler(prefix, uri, event=event_name, append=append): - append((event, (prefix or "", uri or ""))) + # TreeBuilder does not implement .start_ns() + if hasattr(self.target, "start_ns"): + def handler(prefix, uri, event=event_name, append=append, + start_ns=self._start_ns): + append((event, start_ns(prefix, uri))) + else: + def handler(prefix, uri, event=event_name, append=append): + append((event, (prefix or '', uri or ''))) parser.StartNamespaceDeclHandler = handler elif event_name == "end-ns": - def handler(prefix, event=event_name, append=append): - append((event, None)) + # TreeBuilder does not implement .end_ns() + if hasattr(self.target, "end_ns"): + def handler(prefix, event=event_name, append=append, + end_ns=self._end_ns): + append((event, end_ns(prefix))) + else: + def handler(prefix, event=event_name, append=append): + append((event, None)) parser.EndNamespaceDeclHandler = handler + elif event_name == 'comment': + def handler(text, event=event_name, append=append, self=self): + append((event, self.target.comment(text))) + parser.CommentHandler = handler + elif event_name == 'pi': + def handler(pi_target, data, event=event_name, append=append, + self=self): + append((event, self.target.pi(pi_target, data))) + parser.ProcessingInstructionHandler = handler else: raise ValueError("unknown event %r" % event_name) @@ -1533,6 +1612,12 @@ def _fixname(self, key): self._names[key] = name return name + def _start_ns(self, prefix, uri): + return self.target.start_ns(prefix or '', uri or '') + + def _end_ns(self, prefix): + return self.target.end_ns(prefix or '') + def _start(self, tag, attr_list): # Handler for expat's StartElementHandler. Since ordered_attributes # is set, the attributes are reported as a list of alternating @@ -1627,6 +1712,336 @@ def close(self): del self.target, self._target +# -------------------------------------------------------------------- +# C14N 2.0 + +def canonicalize(xml_data=None, *, out=None, from_file=None, **options): + """Convert XML to its C14N 2.0 serialised form. + + If *out* is provided, it must be a file or file-like object that receives + the serialised canonical XML output (text, not bytes) through its ``.write()`` + method. To write to a file, open it in text mode with encoding "utf-8". + If *out* is not provided, this function returns the output as text string. + + Either *xml_data* (an XML string) or *from_file* (a file path or + file-like object) must be provided as input. + + The configuration options are the same as for the ``C14NWriterTarget``. + """ + if xml_data is None and from_file is None: + raise ValueError("Either 'xml_data' or 'from_file' must be provided as input") + sio = None + if out is None: + sio = out = io.StringIO() + + parser = XMLParser(target=C14NWriterTarget(out.write, **options)) + + if xml_data is not None: + parser.feed(xml_data) + parser.close() + elif from_file is not None: + parse(from_file, parser=parser) + + return sio.getvalue() if sio is not None else None + + +_looks_like_prefix_name = re.compile(r'^\w+:\w+$', re.UNICODE).match + + +class C14NWriterTarget: + """ + Canonicalization writer target for the XMLParser. + + Serialises parse events to XML C14N 2.0. + + The *write* function is used for writing out the resulting data stream + as text (not bytes). To write to a file, open it in text mode with encoding + "utf-8" and pass its ``.write`` method. + + Configuration options: + + - *with_comments*: set to true to include comments + - *strip_text*: set to true to strip whitespace before and after text content + - *rewrite_prefixes*: set to true to replace namespace prefixes by "n{number}" + - *qname_aware_tags*: a set of qname aware tag names in which prefixes + should be replaced in text content + - *qname_aware_attrs*: a set of qname aware attribute names in which prefixes + should be replaced in text content + - *exclude_attrs*: a set of attribute names that should not be serialised + - *exclude_tags*: a set of tag names that should not be serialised + """ + def __init__(self, write, *, + with_comments=False, strip_text=False, rewrite_prefixes=False, + qname_aware_tags=None, qname_aware_attrs=None, + exclude_attrs=None, exclude_tags=None): + self._write = write + self._data = [] + self._with_comments = with_comments + self._strip_text = strip_text + self._exclude_attrs = set(exclude_attrs) if exclude_attrs else None + self._exclude_tags = set(exclude_tags) if exclude_tags else None + + self._rewrite_prefixes = rewrite_prefixes + if qname_aware_tags: + self._qname_aware_tags = set(qname_aware_tags) + else: + self._qname_aware_tags = None + if qname_aware_attrs: + self._find_qname_aware_attrs = set(qname_aware_attrs).intersection + else: + self._find_qname_aware_attrs = None + + # Stack with globally and newly declared namespaces as (uri, prefix) pairs. + self._declared_ns_stack = [[ + ("http://www.w3.org/XML/1998/namespace", "xml"), + ]] + # Stack with user declared namespace prefixes as (uri, prefix) pairs. + self._ns_stack = [] + if not rewrite_prefixes: + self._ns_stack.append(list(_namespace_map.items())) + self._ns_stack.append([]) + self._prefix_map = {} + self._preserve_space = [False] + self._pending_start = None + self._root_seen = False + self._root_done = False + self._ignored_depth = 0 + + def _iter_namespaces(self, ns_stack, _reversed=reversed): + for namespaces in _reversed(ns_stack): + if namespaces: # almost no element declares new namespaces + yield from namespaces + + def _resolve_prefix_name(self, prefixed_name): + prefix, name = prefixed_name.split(':', 1) + for uri, p in self._iter_namespaces(self._ns_stack): + if p == prefix: + return f'{{{uri}}}{name}' + raise ValueError(f'Prefix {prefix} of QName "{prefixed_name}" is not declared in scope') + + def _qname(self, qname, uri=None): + if uri is None: + uri, tag = qname[1:].rsplit('}', 1) if qname[:1] == '{' else ('', qname) + else: + tag = qname + + prefixes_seen = set() + for u, prefix in self._iter_namespaces(self._declared_ns_stack): + if u == uri and prefix not in prefixes_seen: + return f'{prefix}:{tag}' if prefix else tag, tag, uri + prefixes_seen.add(prefix) + + # Not declared yet => add new declaration. + if self._rewrite_prefixes: + if uri in self._prefix_map: + prefix = self._prefix_map[uri] + else: + prefix = self._prefix_map[uri] = f'n{len(self._prefix_map)}' + self._declared_ns_stack[-1].append((uri, prefix)) + return f'{prefix}:{tag}', tag, uri + + if not uri and '' not in prefixes_seen: + # No default namespace declared => no prefix needed. + return tag, tag, uri + + for u, prefix in self._iter_namespaces(self._ns_stack): + if u == uri: + self._declared_ns_stack[-1].append((uri, prefix)) + return f'{prefix}:{tag}' if prefix else tag, tag, uri + + raise ValueError(f'Namespace "{uri}" is not declared in scope') + + def data(self, data): + if not self._ignored_depth: + self._data.append(data) + + def _flush(self, _join_text=''.join): + data = _join_text(self._data) + del self._data[:] + if self._strip_text and not self._preserve_space[-1]: + data = data.strip() + if self._pending_start is not None: + args, self._pending_start = self._pending_start, None + qname_text = data if data and _looks_like_prefix_name(data) else None + self._start(*args, qname_text) + if qname_text is not None: + return + if data and self._root_seen: + self._write(_escape_cdata_c14n(data)) + + def start_ns(self, prefix, uri): + if self._ignored_depth: + return + # we may have to resolve qnames in text content + if self._data: + self._flush() + self._ns_stack[-1].append((uri, prefix)) + + def start(self, tag, attrs): + if self._exclude_tags is not None and ( + self._ignored_depth or tag in self._exclude_tags): + self._ignored_depth += 1 + return + if self._data: + self._flush() + + new_namespaces = [] + self._declared_ns_stack.append(new_namespaces) + + if self._qname_aware_tags is not None and tag in self._qname_aware_tags: + # Need to parse text first to see if it requires a prefix declaration. + self._pending_start = (tag, attrs, new_namespaces) + return + self._start(tag, attrs, new_namespaces) + + def _start(self, tag, attrs, new_namespaces, qname_text=None): + if self._exclude_attrs is not None and attrs: + attrs = {k: v for k, v in attrs.items() if k not in self._exclude_attrs} + + qnames = {tag, *attrs} + resolved_names = {} + + # Resolve prefixes in attribute and tag text. + if qname_text is not None: + qname = resolved_names[qname_text] = self._resolve_prefix_name(qname_text) + qnames.add(qname) + if self._find_qname_aware_attrs is not None and attrs: + qattrs = self._find_qname_aware_attrs(attrs) + if qattrs: + for attr_name in qattrs: + value = attrs[attr_name] + if _looks_like_prefix_name(value): + qname = resolved_names[value] = self._resolve_prefix_name(value) + qnames.add(qname) + else: + qattrs = None + else: + qattrs = None + + # Assign prefixes in lexicographical order of used URIs. + parse_qname = self._qname + parsed_qnames = {n: parse_qname(n) for n in sorted( + qnames, key=lambda n: n.split('}', 1))} + + # Write namespace declarations in prefix order ... + if new_namespaces: + attr_list = [ + ('xmlns:' + prefix if prefix else 'xmlns', uri) + for uri, prefix in new_namespaces + ] + attr_list.sort() + else: + # almost always empty + attr_list = [] + + # ... followed by attributes in URI+name order + if attrs: + for k, v in sorted(attrs.items()): + if qattrs is not None and k in qattrs and v in resolved_names: + v = parsed_qnames[resolved_names[v]][0] + attr_qname, attr_name, uri = parsed_qnames[k] + # No prefix for attributes in default ('') namespace. + attr_list.append((attr_qname if uri else attr_name, v)) + + # Honour xml:space attributes. + space_behaviour = attrs.get('{http://www.w3.org/XML/1998/namespace}space') + self._preserve_space.append( + space_behaviour == 'preserve' if space_behaviour + else self._preserve_space[-1]) + + # Write the tag. + write = self._write + write('<' + parsed_qnames[tag][0]) + if attr_list: + write(''.join([f' {k}="{_escape_attrib_c14n(v)}"' for k, v in attr_list])) + write('>') + + # Write the resolved qname text content. + if qname_text is not None: + write(_escape_cdata_c14n(parsed_qnames[resolved_names[qname_text]][0])) + + self._root_seen = True + self._ns_stack.append([]) + + def end(self, tag): + if self._ignored_depth: + self._ignored_depth -= 1 + return + if self._data: + self._flush() + self._write(f'') + self._preserve_space.pop() + self._root_done = len(self._preserve_space) == 1 + self._declared_ns_stack.pop() + self._ns_stack.pop() + + def comment(self, text): + if not self._with_comments: + return + if self._ignored_depth: + return + if self._root_done: + self._write('\n') + elif self._root_seen and self._data: + self._flush() + self._write(f'') + if not self._root_seen: + self._write('\n') + + def pi(self, target, data): + if self._ignored_depth: + return + if self._root_done: + self._write('\n') + elif self._root_seen and self._data: + self._flush() + self._write( + f'' if data else f'') + if not self._root_seen: + self._write('\n') + + +def _escape_cdata_c14n(text): + # escape character data + try: + # it's worth avoiding do-nothing calls for strings that are + # shorter than 500 character, or so. assume that's, by far, + # the most common case in most applications. + if '&' in text: + text = text.replace('&', '&') + if '<' in text: + text = text.replace('<', '<') + if '>' in text: + text = text.replace('>', '>') + if '\r' in text: + text = text.replace('\r', ' ') + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + + +def _escape_attrib_c14n(text): + # escape attribute value + try: + if '&' in text: + text = text.replace('&', '&') + if '<' in text: + text = text.replace('<', '<') + if '"' in text: + text = text.replace('"', '"') + if '\t' in text: + text = text.replace('\t', ' ') + if '\n' in text: + text = text.replace('\n', ' ') + if '\r' in text: + text = text.replace('\r', ' ') + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + + +# -------------------------------------------------------------------- + # Import the C accelerators try: # Element is going to be shadowed by the C implementation. We need to keep @@ -1634,7 +2049,10 @@ def close(self): # (see tests) _Element_Py = Element - # Element, SubElement, ParseError, TreeBuilder, XMLParser + # Element, SubElement, ParseError, TreeBuilder, XMLParser, _set_factories from _elementtree import * + from _elementtree import _set_factories except ImportError: pass +else: + _set_factories(Comment, ProcessingInstruction) diff --git a/Lib/xml/sax/saxutils.py b/Lib/xml/sax/saxutils.py index a69c7f76217..c1612ea1ceb 100644 --- a/Lib/xml/sax/saxutils.py +++ b/Lib/xml/sax/saxutils.py @@ -56,8 +56,7 @@ def quoteattr(data, entities={}): the optional entities parameter. The keys and values must all be strings; each key will be replaced with its corresponding value. """ - entities = entities.copy() - entities.update({'\n': ' ', '\r': ' ', '\t':' '}) + entities = {**entities, '\n': ' ', '\r': ' ', '\t':' '} data = escape(data, entities) if '"' in data: if "'" in data: @@ -340,6 +339,8 @@ def prepare_input_source(source, base=""): """This function takes an InputSource and an optional base URL and returns a fully resolved InputSource object ready for reading.""" + if isinstance(source, os.PathLike): + source = os.fspath(source) if isinstance(source, str): source = xmlreader.InputSource(source) elif hasattr(source, "read"): diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index a0e923a2032..b9875745000 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -186,8 +186,7 @@ def escape(s): class Error(Exception): """Base class for client errors.""" - def __str__(self): - return repr(self) + __str__ = object.__str__ ## # Indicates an HTTP-level protocol error. This is raised by the HTTP @@ -869,8 +868,6 @@ def __init__(self, server): def __repr__(self): return "<%s at %#x>" % (self.__class__.__name__, id(self)) - __str__ = __repr__ - def __getattr__(self, name): return _MultiCallMethod(self.__call_list, name) @@ -1468,8 +1465,6 @@ def __repr__(self): (self.__class__.__name__, self.__host, self.__handler) ) - __str__ = __repr__ - def __getattr__(self, name): # magic method dispatcher return _Method(self.__request, name) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 61cd929f614..62475c701f5 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -3,16 +3,18 @@ XXX references to utf-8 need further investigation. """ +import binascii +import functools +import importlib.util import io import os -import importlib.util -import sys -import time -import stat +import posixpath import shutil +import stat import struct -import binascii +import sys import threading +import time try: import zlib # We may need its compression method @@ -1105,47 +1107,50 @@ def write(self, data): def close(self): if self.closed: return - super().close() - # Flush any data from the compressor, and update header info - if self._compressor: - buf = self._compressor.flush() - self._compress_size += len(buf) - self._fileobj.write(buf) - self._zinfo.compress_size = self._compress_size - else: - self._zinfo.compress_size = self._file_size - self._zinfo.CRC = self._crc - self._zinfo.file_size = self._file_size + try: + super().close() + # Flush any data from the compressor, and update header info + if self._compressor: + buf = self._compressor.flush() + self._compress_size += len(buf) + self._fileobj.write(buf) + self._zinfo.compress_size = self._compress_size + else: + self._zinfo.compress_size = self._file_size + self._zinfo.CRC = self._crc + self._zinfo.file_size = self._file_size - # Write updated header info - if self._zinfo.flag_bits & 0x08: - # Write CRC and file sizes after the file data - fmt = ' ZIP64_LIMIT: - raise RuntimeError('File size unexpectedly exceeded ZIP64 ' - 'limit') - if self._compress_size > ZIP64_LIMIT: - raise RuntimeError('Compressed size unexpectedly exceeded ' - 'ZIP64 limit') - # Seek backwards and write file header (which will now include - # correct CRC and file sizes) + # Write updated header info + if self._zinfo.flag_bits & 0x08: + # Write CRC and file sizes after the file data + fmt = ' ZIP64_LIMIT: + raise RuntimeError( + 'File size unexpectedly exceeded ZIP64 limit') + if self._compress_size > ZIP64_LIMIT: + raise RuntimeError( + 'Compressed size unexpectedly exceeded ZIP64 limit') + # Seek backwards and write file header (which will now include + # correct CRC and file sizes) - # Preserve current position in file - self._zipfile.start_dir = self._fileobj.tell() - self._fileobj.seek(self._zinfo.header_offset) - self._fileobj.write(self._zinfo.FileHeader(self._zip64)) - self._fileobj.seek(self._zipfile.start_dir) + # Preserve current position in file + self._zipfile.start_dir = self._fileobj.tell() + self._fileobj.seek(self._zinfo.header_offset) + self._fileobj.write(self._zinfo.FileHeader(self._zip64)) + self._fileobj.seek(self._zipfile.start_dir) + + # Successfully written: Add file to our caches + self._zipfile.filelist.append(self._zinfo) + self._zipfile.NameToInfo[self._zinfo.filename] = self._zinfo + finally: + self._zipfile._writing = False - self._zipfile._writing = False - # Successfully written: Add file to our caches - self._zipfile.filelist.append(self._zinfo) - self._zipfile.NameToInfo[self._zinfo.filename] = self._zinfo class ZipFile: """ Class with methods to open, read, write, close, list zip files. @@ -2099,6 +2104,138 @@ def _compile(file, optimize=-1): return (fname, archivename) +class Path: + """ + A pathlib-compatible interface for zip files. + + Consider a zip file with this structure:: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + + >>> data = io.BytesIO() + >>> zf = ZipFile(data, 'w') + >>> zf.writestr('a.txt', 'content of a') + >>> zf.writestr('b/c.txt', 'content of c') + >>> zf.writestr('b/d/e.txt', 'content of e') + >>> zf.filename = 'abcde.zip' + + Path accepts the zipfile object itself or a filename + + >>> root = Path(zf) + + From there, several path operations are available. + + Directory iteration (including the zip file itself): + + >>> a, b = root.iterdir() + >>> a + Path('abcde.zip', 'a.txt') + >>> b + Path('abcde.zip', 'b/') + + name property: + + >>> b.name + 'b' + + join with divide operator: + + >>> c = b / 'c.txt' + >>> c + Path('abcde.zip', 'b/c.txt') + >>> c.name + 'c.txt' + + Read text: + + >>> c.read_text() + 'content of c' + + existence: + + >>> c.exists() + True + >>> (b / 'missing.txt').exists() + False + + Coersion to string: + + >>> str(c) + 'abcde.zip/b/c.txt' + """ + + __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" + + def __init__(self, root, at=""): + self.root = root if isinstance(root, ZipFile) else ZipFile(root) + self.at = at + + @property + def open(self): + return functools.partial(self.root.open, self.at) + + @property + def name(self): + return posixpath.basename(self.at.rstrip("/")) + + def read_text(self, *args, **kwargs): + with self.open() as strm: + return io.TextIOWrapper(strm, *args, **kwargs).read() + + def read_bytes(self): + with self.open() as strm: + return strm.read() + + def _is_child(self, path): + return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") + + def _next(self, at): + return Path(self.root, at) + + def is_dir(self): + return not self.at or self.at.endswith("/") + + def is_file(self): + return not self.is_dir() + + def exists(self): + return self.at in self._names() + + def iterdir(self): + if not self.is_dir(): + raise ValueError("Can't listdir a file") + subs = map(self._next, self._names()) + return filter(self._is_child, subs) + + def __str__(self): + return posixpath.join(self.root.filename, self.at) + + def __repr__(self): + return self.__repr.format(self=self) + + def __truediv__(self, add): + next = posixpath.join(self.at, add) + next_dir = posixpath.join(self.at, add, "") + names = self._names() + return self._next(next_dir if next not in names and next_dir in names else next) + + @staticmethod + def _add_implied_dirs(names): + return names + [ + name + "/" + for name in map(posixpath.dirname, names) + if name and name + "/" not in names + ] + + def _names(self): + return self._add_implied_dirs(self.root.namelist()) + + def main(args=None): import argparse diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 2e3a61ec71d..fb43da5478f 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1207,7 +1207,8 @@ def buildPython(): if ln.startswith('VERSION='): VERSION=ln.split()[1] if ln.startswith('ABIFLAGS='): - ABIFLAGS=ln.split()[1] + ABIFLAGS=ln.split() + ABIFLAGS=ABIFLAGS[1] if len(ABIFLAGS) > 1 else '' if ln.startswith('LDVERSION='): LDVERSION=ln.split()[1] fp.close() @@ -1258,7 +1259,8 @@ def buildPython(): import pprint if getVersionMajorMinor() >= (3, 6): # XXX this is extra-fragile - path = os.path.join(path_to_lib, '_sysconfigdata_m_darwin_darwin.py') + path = os.path.join(path_to_lib, + '_sysconfigdata_%s_darwin_darwin.py' % (ABIFLAGS,)) else: path = os.path.join(path_to_lib, '_sysconfigdata.py') fp = open(path, 'r') diff --git a/Makefile.pre.in b/Makefile.pre.in index 8042e8e81a0..75eb66be3c0 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -41,6 +41,7 @@ AR= @AR@ READELF= @READELF@ SOABI= @SOABI@ LDVERSION= @LDVERSION@ +LIBPYTHON= @LIBPYTHON@ GITVERSION= @GITVERSION@ GITTAG= @GITTAG@ GITBRANCH= @GITBRANCH@ @@ -104,6 +105,8 @@ PY_LDFLAGS_NODIST=$(CONFIGURE_LDFLAGS_NODIST) $(LDFLAGS_NODIST) NO_AS_NEEDED= @NO_AS_NEEDED@ SGI_ABI= @SGI_ABI@ CCSHARED= @CCSHARED@ +# LINKFORSHARED are the flags passed to the $(CC) command that links +# the python executable -- this is only needed for a few systems LINKFORSHARED= @LINKFORSHARED@ ARFLAGS= @ARFLAGS@ # Extra C flags added for building the interpreter object files. @@ -724,7 +727,7 @@ regen-importlib: Programs/_freeze_importlib # Regenerate all generated files regen-all: regen-opcode regen-opcode-targets regen-typeslots regen-grammar \ - regen-token regen-symbol regen-ast regen-importlib clinic + regen-token regen-keyword regen-symbol regen-ast regen-importlib clinic ############################################################################ # Special rules for object files @@ -789,7 +792,7 @@ regen-grammar: regen-token # Regenerate Include/graminit.h and Python/graminit.c # from Grammar/Grammar using pgen @$(MKDIR_P) Include - $(PYTHON_FOR_REGEN) -m Parser.pgen $(srcdir)/Grammar/Grammar \ + PYTHONPATH=$(srcdir) $(PYTHON_FOR_REGEN) -m Parser.pgen $(srcdir)/Grammar/Grammar \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Include/graminit.h.new \ $(srcdir)/Python/graminit.c.new @@ -843,6 +846,15 @@ regen-token: $(srcdir)/Grammar/Tokens \ $(srcdir)/Lib/token.py +.PHONY: regen-keyword +regen-keyword: + # Regenerate Lib/keyword.py from Grammar/Grammar and Grammar/Tokens + # using Parser/pgen + PYTHONPATH=$(srcdir) $(PYTHON_FOR_REGEN) -m Parser.pgen.keywordgen $(srcdir)/Grammar/Grammar \ + $(srcdir)/Grammar/Tokens \ + $(srcdir)/Lib/keyword.py.new + $(UPDATE_FILE) $(srcdir)/Lib/keyword.py $(srcdir)/Lib/keyword.py.new + .PHONY: regen-symbol regen-symbol: $(srcdir)/Include/graminit.h # Regenerate Lib/symbol.py from Include/graminit.h @@ -997,7 +1009,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/osdefs.h \ $(srcdir)/Include/osmodule.h \ $(srcdir)/Include/patchlevel.h \ - $(srcdir)/Include/pgenheaders.h \ $(srcdir)/Include/pyarena.h \ $(srcdir)/Include/pycapsule.h \ $(srcdir)/Include/pyctype.h \ @@ -1046,6 +1057,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/objimpl.h \ $(srcdir)/Include/cpython/pyerrors.h \ $(srcdir)/Include/cpython/pylifecycle.h \ + $(srcdir)/Include/cpython/pymem.h \ $(srcdir)/Include/cpython/pystate.h \ $(srcdir)/Include/cpython/tupleobject.h \ $(srcdir)/Include/cpython/unicodeobject.h \ @@ -1284,7 +1296,8 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ tkinter/test/test_ttk site-packages test \ test/audiodata \ test/capath test/data \ - test/cjkencodings test/decimaltestdata test/xmltestdata \ + test/cjkencodings test/decimaltestdata \ + test/xmltestdata test/xmltestdata/c14n-20 \ test/dtracedata \ test/eintrdata \ test/imghdrdata \ @@ -1449,6 +1462,8 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/PatternGrammar.txt +# bpo-21536: Misc/python-config.sh is generated in the build directory +# from $(srcdir)Misc/python-config.sh.in. python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh @ # Substitution happens here, as the completely-expanded BINDIR @ # is not available in configure @@ -1639,14 +1654,6 @@ frameworkaltinstallunixtools: frameworkinstallextras: cd Mac && $(MAKE) installextras DESTDIR="$(DESTDIR)" -# This installs a few of the useful scripts in Tools/scripts -scriptsinstall: - SRCDIR=$(srcdir) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) $(srcdir)/Tools/scripts/setup.py install \ - --prefix=$(prefix) \ - --install-scripts=$(BINDIR) \ - --root=$(DESTDIR)/ - # Build the toplevel Makefile Makefile.pre: $(srcdir)/Makefile.pre.in config.status CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status diff --git a/Misc/ACKS b/Misc/ACKS index 9cddcb3a871..300e7889407 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -222,6 +222,7 @@ Ian Bruntlett Floris Bruynooghe Matt Bryant Stan Bubrouski +Brandt Bucher Colm Buckley Erik de Bueger Jan-Hein Bührman @@ -475,6 +476,7 @@ Jim Fasarakis-Hilliard Mark Favas Sergey Fedoseev Boris Feld +M. Felt Thomas Fenzl Niels Ferguson Francisco Fernández Castaño @@ -645,6 +647,7 @@ Christian Heimes Thomas Heller Malte Helmert Lance Finn Helsten +Gordon P. Hemsley Jonathan Hendry Nathan Henrie Michael Henry @@ -721,6 +724,7 @@ Ludwig Hähne Gerhard Häring Fredrik Håård Florian Höch +Robert Hölzl Catalin Iacob Mihai Ibanescu Ali Ikinci @@ -1096,6 +1100,7 @@ Tim Mitchell Zubin Mithra Florian Mladitsch Doug Moen +Jakub Molinski Juliette Monsel The Dragon De Monsyne Bastien Montagne diff --git a/Misc/NEWS.d/3.8.0a3.rst b/Misc/NEWS.d/3.8.0a3.rst new file mode 100644 index 00000000000..a7397b520cb --- /dev/null +++ b/Misc/NEWS.d/3.8.0a3.rst @@ -0,0 +1,871 @@ +.. bpo: 36216 +.. date: 2019-03-06-09-38-40 +.. nonce: 6q1m4a +.. release date: 2019-03-25 +.. section: Security + +Changes urlsplit() to raise ValueError when the URL contains characters that +decompose under IDNA encoding (NFKC-normalization) into characters that +affect how the URL is parsed. + +.. + +.. bpo: 35121 +.. date: 2018-10-31-15-39-17 +.. nonce: EgHv9k +.. section: Security + +Don't send cookies of domain A without Domain attribute to domain B when +domain A is a suffix match of domain B while using a cookiejar with +:class:`http.cookiejar.DefaultCookiePolicy` policy. Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 36421 +.. date: 2019-03-24-21-33-22 +.. nonce: gJ2Pv9 +.. section: Core and Builtins + +Fix a possible double decref in _ctypes.c's ``PyCArrayType_new()``. + +.. + +.. bpo: 36412 +.. date: 2019-03-23-19-51-09 +.. nonce: C7acGn +.. section: Core and Builtins + +Fix a possible crash when creating a new dictionary. + +.. + +.. bpo: 36398 +.. date: 2019-03-21-22-19-38 +.. nonce: B_jXGe +.. section: Core and Builtins + +Fix a possible crash in ``structseq_repr()``. + +.. + +.. bpo: 36256 +.. date: 2019-03-21-00-24-18 +.. nonce: OZHa0t +.. section: Core and Builtins + +Fix bug in parsermodule when parsing a state in a DFA that has two or more +arcs with labels of the same type. Patch by Pablo Galindo. + +.. + +.. bpo: 36365 +.. date: 2019-03-19-15-58-23 +.. nonce: jHaErz +.. section: Core and Builtins + +repr(structseq) is no longer limited to 512 bytes. + +.. + +.. bpo: 36374 +.. date: 2019-03-19-15-46-42 +.. nonce: EWKMZE +.. section: Core and Builtins + +Fix a possible null pointer dereference in ``merge_consts_recursive()``. +Patch by Zackery Spytz. + +.. + +.. bpo: 36236 +.. date: 2019-03-19-03-08-26 +.. nonce: 5qN9qK +.. section: Core and Builtins + +At Python initialization, the current directory is no longer prepended to +:data:`sys.path` if it has been removed. + +.. + +.. bpo: 36352 +.. date: 2019-03-19-02-36-40 +.. nonce: qj2trz +.. section: Core and Builtins + +Python initialization now fails with an error, rather than silently +truncating paths, if a path is too long. + +.. + +.. bpo: 36301 +.. date: 2019-03-19-00-54-31 +.. nonce: xvOCJb +.. section: Core and Builtins + +Python initialization now fails if decoding ``pybuilddir.txt`` configuration +file fails at startup. + +.. + +.. bpo: 36333 +.. date: 2019-03-18-10-56-53 +.. nonce: 4dqemZ +.. section: Core and Builtins + +Fix leak in _PyRuntimeState_Fini. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36332 +.. date: 2019-03-18-09-27-54 +.. nonce: yEC-Vz +.. section: Core and Builtins + +The builtin :func:`compile` can now handle AST objects that contain +assignment expressions. Patch by Pablo Galindo. + +.. + +.. bpo: 36282 +.. date: 2019-03-13-22-47-28 +.. nonce: zs7RKP +.. section: Core and Builtins + +Improved error message for too much positional arguments in some builtin +functions. + +.. + +.. bpo: 30040 +.. date: 2019-03-11-22-30-56 +.. nonce: W9z8X7 +.. section: Core and Builtins + +New empty dict uses fewer memory for now. It used more memory than empty +dict created by ``dict.clear()``. And empty dict creation and deletion is +about 2x faster. Patch by Inada Naoki. + +.. + +.. bpo: 36262 +.. date: 2019-03-11-15-37-33 +.. nonce: v3N6Fz +.. section: Core and Builtins + +Fix an unlikely memory leak on conversion from string to float in the +function ``_Py_dg_strtod()`` used by ``float(str)``, ``complex(str)``, +:func:`pickle.load`, :func:`marshal.load`, etc. + +.. + +.. bpo: 36252 +.. date: 2019-03-09-15-47-05 +.. nonce: sCQFKq +.. section: Core and Builtins + +Update Unicode databases to version 12.0.0. + +.. + +.. bpo: 36218 +.. date: 2019-03-07-13-05-43 +.. nonce: dZemNt +.. section: Core and Builtins + +Fix a segfault occuring when sorting a list of heterogeneous values. Patch +contributed by Rémi Lapeyre and Elliot Gorokhovsky. + +.. + +.. bpo: 36188 +.. date: 2019-03-04-18-05-31 +.. nonce: EuUZNz +.. section: Core and Builtins + +Cleaned up left-over vestiges of Python 2 unbound method handling in method +objects and documentation. Patch by Martijn Pieters + +.. + +.. bpo: 36124 +.. date: 2019-03-01-13-48-01 +.. nonce: Blzxq1 +.. section: Core and Builtins + +Add a new interpreter-specific dict and expose it in the C-API via +PyInterpreterState_GetDict(). This parallels PyThreadState_GetDict(). +However, extension modules should continue using PyModule_GetState() for +their own internal per-interpreter state. + +.. + +.. bpo: 35975 +.. date: 2019-02-27-16-49-08 +.. nonce: IescLY +.. section: Core and Builtins + +Add a ``feature_version`` flag to ``ast.parse()`` (documented) and +``compile()`` (hidden) that allows tweaking the parser to support older +versions of the grammar. In particular, if ``feature_version`` is 5 or 6, +the hacks for the ``async`` and ``await`` keyword from PEP 492 are +reinstated. (For 7 or higher, these are unconditionally treated as keywords, +but they are still special tokens rather than ``NAME`` tokens that the +parser driver recognizes.) + +.. + +.. bpo: 31904 +.. date: 2019-02-26-17-34-49 +.. nonce: R4KSj6 +.. section: Core and Builtins + +Use UTF-8 as the system encoding on VxWorks. + +.. + +.. bpo: 36048 +.. date: 2019-02-20-08-51-04 +.. nonce: I3LJt9 +.. section: Core and Builtins + +The :meth:`~object.__index__` special method will be used instead of +:meth:`~object.__int__` for implicit conversion of Python numbers to C +integers. Using the ``__int__()`` method in implicit conversions has been +deprecated. + +.. + +.. bpo: 35808 +.. date: 2019-02-11-00-50-03 +.. nonce: M12CMH +.. section: Core and Builtins + +Retire pgen and use a modified version of pgen2 to generate the parser. +Patch by Pablo Galindo. + +.. + +.. bpo: 36401 +.. date: 2019-03-23-10-25-07 +.. nonce: hYpVBS +.. section: Library + +The class documentation created by pydoc now has a separate section for +readonly properties. + +.. + +.. bpo: 36320 +.. date: 2019-03-18-01-08-14 +.. nonce: -06b9_ +.. section: Library + +The typing.NamedTuple() class has deprecated the _field_types attribute in +favor of the __annotations__ attribute which carried the same information. +Also, both attributes were converted from OrderedDict to a regular dict. + +.. + +.. bpo: 34745 +.. date: 2019-03-17-16-43-29 +.. nonce: nOfm7_ +.. section: Library + +Fix :mod:`asyncio` ssl memory issues caused by circular references + +.. + +.. bpo: 36324 +.. date: 2019-03-17-01-17-45 +.. nonce: dvNrRe +.. section: Library + +Add method to statistics.NormalDist for computing the inverse cumulative +normal distribution. + +.. + +.. bpo: 36321 +.. date: 2019-03-16-13-40-59 +.. nonce: s6crQx +.. section: Library + +collections.namedtuple() misspelled the name of an attribute. To be +consistent with typing.NamedTuple, the attribute name should have been +"_field_defaults" instead of "_fields_defaults". For backwards +compatibility, both spellings are now created. The misspelled version may +be removed in the future. + +.. + +.. bpo: 36297 +.. date: 2019-03-15-21-41-22 +.. nonce: Gz9ZfU +.. section: Library + +"unicode_internal" codec is removed. It was deprecated since Python 3.3. +Patch by Inada Naoki. + +.. + +.. bpo: 36298 +.. date: 2019-03-15-13-54-07 +.. nonce: amEVK2 +.. section: Library + +Raise ModuleNotFoundError in pyclbr when a module can't be found. Thanks to +'mental' for the bug report. + +.. + +.. bpo: 36268 +.. date: 2019-03-14-16-25-17 +.. nonce: MDXLw6 +.. section: Library + +Switch the default format used for writing tars with mod:`tarfile` to the +modern POSIX.1-2001 pax standard, from the vendor-specific GNU. Contributed +by C.A.M. Gerlach. + +.. + +.. bpo: 36285 +.. date: 2019-03-14-01-09-59 +.. nonce: G-usj8 +.. section: Library + +Fix integer overflows in the array module. Patch by Stephan Hohe. + +.. + +.. bpo: 31904 +.. date: 2019-03-13-14-55-02 +.. nonce: 834kfY +.. section: Library + +Add _signal module support for VxWorks. + +.. + +.. bpo: 36272 +.. date: 2019-03-13-14-14-36 +.. nonce: f3l2IG +.. section: Library + +:mod:`logging` does not silently ignore RecursionError anymore. Patch +contributed by Rémi Lapeyre. + +.. + +.. bpo: 36280 +.. date: 2019-03-12-21-02-55 +.. nonce: mOd3iH +.. section: Library + +Add a kind field to ast.Constant. It is 'u' if the literal has a 'u' prefix +(i.e. a Python 2 style unicode literal), else None. + +.. + +.. bpo: 35931 +.. date: 2019-03-11-22-06-36 +.. nonce: Qp_Tbe +.. section: Library + +The :mod:`pdb` ``debug`` command now gracefully handles all exceptions. + +.. + +.. bpo: 36251 +.. date: 2019-03-09-18-01-24 +.. nonce: zOp9l0 +.. section: Library + +Fix format strings used for stderrprinter and re.Match reprs. Patch by +Stephan Hohe. + +.. + +.. bpo: 36235 +.. date: 2019-03-08-13-32-21 +.. nonce: _M72wU +.. section: Library + +Fix ``CFLAGS`` in ``customize_compiler()`` of ``distutils.sysconfig``: when +the ``CFLAGS`` environment variable is defined, don't override ``CFLAGS`` +variable with the ``OPT`` variable anymore. Initial patch written by David +Malcolm. + +.. + +.. bpo: 35807 +.. date: 2019-03-06-13-21-33 +.. nonce: W7mmu3 +.. section: Library + +Update ensurepip to install pip 19.0.3 and setuptools 40.8.0. + +.. + +.. bpo: 36139 +.. date: 2019-03-06-13-07-29 +.. nonce: 6kedum +.. section: Library + +Release GIL when closing :class:`~mmap.mmap` objects. + +.. + +.. bpo: 36179 +.. date: 2019-03-04-10-42-46 +.. nonce: jEyuI- +.. section: Library + +Fix two unlikely reference leaks in _hashopenssl. The leaks only occur in +out-of-memory cases. + +.. + +.. bpo: 36169 +.. date: 2019-03-03-11-37-09 +.. nonce: 8nWJy7 +.. section: Library + +Add overlap() method to statistics.NormalDist. Computes the overlapping +coefficient for two normal distributions. + +.. + +.. bpo: 36103 +.. date: 2019-03-01-16-10-01 +.. nonce: n6VgXL +.. section: Library + +Default buffer size used by ``shutil.copyfileobj()`` is changed from 16 KiB +to 64 KiB on non-Windows platform to reduce system call overhead. +Contributed by Inada Naoki. + +.. + +.. bpo: 36130 +.. date: 2019-02-26-22-41-38 +.. nonce: _BnZOo +.. section: Library + +Fix ``pdb`` with ``skip=...`` when stepping into a frame without a +``__name__`` global. Patch by Anthony Sottile. + +.. + +.. bpo: 35652 +.. date: 2019-02-26-11-34-44 +.. nonce: 6KRJu_ +.. section: Library + +shutil.copytree(copy_function=...) erroneously pass DirEntry instead of a +path string. + +.. + +.. bpo: 35178 +.. date: 2019-02-25-23-04-00 +.. nonce: NA_rXa +.. section: Library + +Ensure custom :func:`warnings.formatwarning` function can receive `line` as +positional argument. Based on patch by Tashrif Billah. + +.. + +.. bpo: 36106 +.. date: 2019-02-25-13-21-43 +.. nonce: VuhEiQ +.. section: Library + +Resolve potential name clash with libm's sinpi(). Patch by Dmitrii +Pasechnik. + +.. + +.. bpo: 36091 +.. date: 2019-02-23-06-49-06 +.. nonce: 26o4Lc +.. section: Library + +Clean up reference to async generator in Lib/types. Patch by Henry Chen. + +.. + +.. bpo: 36043 +.. date: 2019-02-19-19-53-46 +.. nonce: l867v0 +.. section: Library + +:class:`FileCookieJar` supports :term:`path-like object`. Contributed by +Stéphane Wirtel + +.. + +.. bpo: 35899 +.. date: 2019-02-16-07-11-02 +.. nonce: cjfn5a +.. section: Library + +Enum has been fixed to correctly handle empty strings and strings with +non-Latin characters (ie. 'α', 'א') without crashing. Original patch +contributed by Maxwell. Assisted by Stéphane Wirtel. + +.. + +.. bpo: 21269 +.. date: 2019-02-10-16-49-16 +.. nonce: Fqi7VH +.. section: Library + +Add ``args`` and ``kwargs`` properties to mock call objects. Contributed by +Kumar Akshay. + +.. + +.. bpo: 30670 +.. date: 2019-02-06-12-07-46 +.. nonce: yffB3F +.. section: Library + +`pprint.pp` has been added to pretty-print objects with dictionary keys +being sorted with their insertion order by default. Parameter *sort_dicts* +has been added to `pprint.pprint`, `pprint.pformat` and +`pprint.PrettyPrinter`. Contributed by Rémi Lapeyre. + +.. + +.. bpo: 35843 +.. date: 2019-01-28-10-19-40 +.. nonce: 7rXGQE +.. section: Library + +Implement ``__getitem__`` for ``_NamespacePath``. Patch by Anthony Sottile. + +.. + +.. bpo: 35802 +.. date: 2019-01-21-13-56-55 +.. nonce: 6633PE +.. section: Library + +Clean up code which checked presence of ``os.stat`` / ``os.lstat`` / +``os.chmod`` which are always present. Patch by Anthony Sottile. + +.. + +.. bpo: 35715 +.. date: 2019-01-11-08-47-58 +.. nonce: Wi3gl0 +.. section: Library + +Librates the return value of a ProcessPoolExecutor _process_worker after +it's no longer needed to free memory + +.. + +.. bpo: 35493 +.. date: 2019-01-09-23-43-08 +.. nonce: kEcRGE +.. section: Library + +Use :func:`multiprocessing.connection.wait` instead of polling each 0.2 +seconds for worker updates in :class:`multiprocessing.Pool`. Patch by Pablo +Galindo. + +.. + +.. bpo: 35661 +.. date: 2019-01-05-16-16-20 +.. nonce: H_UOXc +.. section: Library + +Store the venv prompt in pyvenv.cfg. + +.. + +.. bpo: 35121 +.. date: 2018-12-30-14-35-19 +.. nonce: oWmiGU +.. section: Library + +Don't set cookie for a request when the request path is a prefix match of +the cookie's path attribute but doesn't end with "/". Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 21478 +.. date: 2018-12-21-09-54-30 +.. nonce: 5gsXtc +.. section: Library + +Calls to a child function created with :func:`unittest.mock.create_autospec` +should propagate to the parent. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 35198 +.. date: 2018-11-09-12-45-28 +.. nonce: EJ8keW +.. section: Library + +Fix C++ extension compilation on AIX + +.. + +.. bpo: 36329 +.. date: 2019-03-17-20-01-41 +.. nonce: L5dJPD +.. section: Documentation + +Declare the path of the Python binary for the usage of +``Tools/scripts/serve.py`` when executing ``make -C Doc/ serve``. +Contributed by Stéphane Wirtel + +.. + +.. bpo: 36138 +.. date: 2019-03-02-00-40-57 +.. nonce: yfjNzG +.. section: Documentation + +Improve documentation about converting datetime.timedelta to scalars. + +.. + +.. bpo: 21314 +.. date: 2018-11-21-23-01-37 +.. nonce: PG33VT +.. section: Documentation + +A new entry was added to the Core Language Section of the Programming FAQ, +which explaines the usage of slash(/) in the signature of a function. Patch +by Lysandros Nikolaou + +.. + +.. bpo: 36234 +.. date: 2019-03-08-12-53-37 +.. nonce: NRVK6W +.. section: Tests + +test_posix.PosixUidGidTests: add tests for invalid uid/gid type (str). +Initial patch written by David Malcolm. + +.. + +.. bpo: 29571 +.. date: 2019-02-28-18-33-29 +.. nonce: r6b9fr +.. section: Tests + +Fix ``test_re.test_locale_flag()``: use ``locale.getpreferredencoding()`` +rather than ``locale.getlocale()`` to get the locale encoding. With some +locales, ``locale.getlocale()`` returns the wrong encoding. + +.. + +.. bpo: 36123 +.. date: 2019-02-26-12-51-35 +.. nonce: QRhhRS +.. section: Tests + +Fix race condition in test_socket. + +.. + +.. bpo: 36356 +.. date: 2019-03-18-23-49-15 +.. nonce: WNrwYI +.. section: Build + +Fix leaks that led to build failure when configured with address sanitizer. + +.. + +.. bpo: 36146 +.. date: 2019-03-01-17-49-22 +.. nonce: VeoyG7 +.. section: Build + +Add ``TEST_EXTENSIONS`` constant to ``setup.py`` to allow to not build test +extensions like ``_testcapi``. + +.. + +.. bpo: 36146 +.. date: 2019-02-28-18-09-01 +.. nonce: IwPJVT +.. section: Build + +Fix setup.py on macOS: only add ``/usr/include/ffi`` to include directories +of _ctypes, not for all extensions. + +.. + +.. bpo: 31904 +.. date: 2019-02-21-14-48-31 +.. nonce: J82jY2 +.. section: Build + +Enable build system to cross-build for VxWorks RTOS. + +.. + +.. bpo: 36312 +.. date: 2019-03-16-16-51-17 +.. nonce: Niwm-T +.. section: Windows + +Fixed decoders for the following code pages: 50220, 50221, 50222, 50225, +50227, 50229, 57002 through 57011, 65000 and 42. + +.. + +.. bpo: 36264 +.. date: 2019-03-11-09-33-47 +.. nonce: rTzWce +.. section: Windows + +Don't honor POSIX ``HOME`` in ``os.path.expanduser`` on windows. Patch by +Anthony Sottile. + +.. + +.. bpo: 24643 +.. date: 2019-02-24-07-52-39 +.. nonce: PofyiS +.. section: Windows + +Fix name collisions due to ``#define timezone _timezone`` in PC/pyconfig.h. + +.. + +.. bpo: 36405 +.. date: 2019-03-23-01-45-56 +.. nonce: m7Wv1F +.. section: IDLE + +Use dict unpacking in idlelib. + +.. + +.. bpo: 36396 +.. date: 2019-03-21-22-43-21 +.. nonce: xSTX-I +.. section: IDLE + +Remove fgBg param of idlelib.config.GetHighlight(). This param was only used +twice and changed the return type. + +.. + +.. bpo: 36176 +.. date: 2019-03-10-00-07-46 +.. nonce: jk_vv6 +.. section: IDLE + +Fix IDLE autocomplete & calltip popup colors. Prevent conflicts with Linux +dark themes (and slightly darken calltip background). + +.. + +.. bpo: 23205 +.. date: 2019-03-06-14-47-57 +.. nonce: Vv0gfH +.. section: IDLE + +For the grep module, add tests for findfiles, refactor findfiles to be a +module-level function, and refactor findfiles to use os.walk. + +.. + +.. bpo: 23216 +.. date: 2019-03-02-19-39-53 +.. nonce: ZA7H8H +.. section: IDLE + +Add docstrings to IDLE search modules. + +.. + +.. bpo: 36152 +.. date: 2019-02-28-18-52-40 +.. nonce: 9pkHIU +.. section: IDLE + +Remove colorizer.ColorDelegator.close_when_done and the corresponding +argument of .close(). In IDLE, both have always been None or False since +2007. + +.. + +.. bpo: 32129 +.. date: 2019-02-25-11-40-14 +.. nonce: 4qVCzD +.. section: IDLE + +Avoid blurry IDLE application icon on macOS with Tk 8.6. Patch by Kevin +Walzer. + +.. + +.. bpo: 36096 +.. date: 2019-02-23-17-53-53 +.. nonce: mN5Ly3 +.. section: IDLE + +Refactor class variables to instance variables in colorizer. + +.. + +.. bpo: 30348 +.. date: 2018-06-27-21-18-41 +.. nonce: WbaRJW +.. section: IDLE + +Increase test coverage of idlelib.autocomplete by 30%. + +.. + +.. bpo: 35132 +.. date: 2019-03-04-02-09-09 +.. nonce: 1R_pnL +.. section: Tools/Demos + +Fix py-list and py-bt commands of python-gdb.py on gdb7. + +.. + +.. bpo: 32217 +.. date: 2017-12-19-20-42-36 +.. nonce: axXcjA +.. section: Tools/Demos + +Fix freeze script on Windows. + +.. + +.. bpo: 36381 +.. date: 2019-03-20-22-02-40 +.. nonce: xlzDJ2 +.. section: C API + +Raise ``DeprecationWarning`` when '#' formats are used for building or +parsing values without ``PY_SSIZE_T_CLEAN``. + +.. + +.. bpo: 36142 +.. date: 2019-03-01-03-23-48 +.. nonce: 7F6wJd +.. section: C API + +The whole coreconfig.h header is now excluded from Py_LIMITED_API. Move +functions definitions into a new internal pycore_coreconfig.h header. diff --git a/Misc/NEWS.d/3.8.0a4.rst b/Misc/NEWS.d/3.8.0a4.rst new file mode 100644 index 00000000000..76bb4970ff8 --- /dev/null +++ b/Misc/NEWS.d/3.8.0a4.rst @@ -0,0 +1,1421 @@ +.. bpo: 36742 +.. date: 2019-04-29-15-34-59 +.. nonce: QCUY0i +.. release date: 2019-05-06 +.. section: Security + +Fixes mishandling of pre-normalization characters in urlsplit(). + +.. + +.. bpo: 30458 +.. date: 2019-04-10-08-53-30 +.. nonce: 51E-DA +.. section: Security + +Address CVE-2019-9740 by disallowing URL paths with embedded whitespace or +control characters through into the underlying http client request. Such +potentially malicious header injection URLs now cause an +http.client.InvalidURL exception to be raised. + +.. + +.. bpo: 35755 +.. date: 2019-01-17-10-03-48 +.. nonce: GmllIs +.. section: Security + +:func:`shutil.which` now uses ``os.confstr("CS_PATH")`` if available and if +the :envvar:`PATH` environment variable is not set. Remove also the current +directory from :data:`posixpath.defpath`. On Unix, :func:`shutil.which` and +the :mod:`subprocess` module no longer search the executable in the current +directory if the :envvar:`PATH` environment variable is not set. + +.. + +.. bpo: 36751 +.. date: 2019-04-29-23-30-21 +.. nonce: 3NCRbm +.. section: Core and Builtins + +The :func:`~inspect.getfullargspec` function in the :mod:`inspect` module is +deprecated in favor of the :func:`inspect.signature` API. Contributed by +Pablo Galindo. + +.. + +.. bpo: 36722 +.. date: 2019-04-25-21-02-40 +.. nonce: 8NApVM +.. section: Core and Builtins + +In debug build, import now also looks for C extensions compiled in release +mode and for C extensions compiled in the stable ABI. + +.. + +.. bpo: 32849 +.. date: 2019-04-16-11-56-12 +.. nonce: aeSg-D +.. section: Core and Builtins + +Fix Python Initialization code on FreeBSD to detect properly when stdin file +descriptor (fd 0) is invalid. + +.. + +.. bpo: 36623 +.. date: 2019-04-13-02-08-44 +.. nonce: HR_xhB +.. section: Core and Builtins + +Remove parser headers and related function declarations that lack +implementations after the removal of pgen. + +.. + +.. bpo: 20180 +.. date: 2019-04-12-15-49-15 +.. nonce: KUqVk7 +.. section: Core and Builtins + +``dict.pop()`` is now up to 33% faster thanks to Argument Clinic. Patch by +Inada Naoki. + +.. + +.. bpo: 36611 +.. date: 2019-04-12-12-32-39 +.. nonce: zbo9WQ +.. section: Core and Builtins + +Debug memory allocators: disable serialno field by default from debug hooks +on Python memory allocators to reduce the memory footprint by 5%. Enable +:mod:`tracemalloc` to get the traceback where a memory block has been +allocated when a fatal memory error is logged to decide where to put a +breakpoint. Compile Python with ``PYMEM_DEBUG_SERIALNO`` defined to get back +the field. + +.. + +.. bpo: 36588 +.. date: 2019-04-11-14-36-55 +.. nonce: wejLoC +.. section: Core and Builtins + +On AIX, :attr:`sys.platform` doesn't contain the major version anymore. +Always return ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. Since older +Python versions include the version number, it is recommended to always use +``sys.platform.startswith('aix')``. Contributed by M. Felt. + +.. + +.. bpo: 36549 +.. date: 2019-04-11-12-41-31 +.. nonce: QSp8of +.. section: Core and Builtins + +Change str.capitalize to use titlecase for the first character instead of +uppercase. + +.. + +.. bpo: 36540 +.. date: 2019-04-06-20-59-19 +.. nonce: SzVUfC +.. section: Core and Builtins + +Implement :pep:`570` (Python positional-only parameters). Patch by Pablo +Galindo. + +.. + +.. bpo: 36475 +.. date: 2019-04-02-20-02-22 +.. nonce: CjRps3 +.. section: Core and Builtins + +:c:func:`PyEval_AcquireLock` and :c:func:`PyEval_AcquireThread` now +terminate the current thread if called while the interpreter is finalizing, +making them consistent with :c:func:`PyEval_RestoreThread`, +:c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. + +.. + +.. bpo: 36504 +.. date: 2019-04-02-04-10-32 +.. nonce: k_V8Bm +.. section: Core and Builtins + +Fix signed integer overflow in _ctypes.c's ``PyCArrayType_new()``. + +.. + +.. bpo: 20844 +.. date: 2019-03-29-18-47-50 +.. nonce: ge-7SM +.. section: Core and Builtins + +Fix running script with encoding cookie and LF line ending may fail on +Windows. + +.. + +.. bpo: 24214 +.. date: 2019-03-28-15-22-45 +.. nonce: tZ6lYU +.. section: Core and Builtins + +Fixed support of the surrogatepass error handler in the UTF-8 incremental +decoder. + +.. + +.. bpo: 36452 +.. date: 2019-03-27-23-53-00 +.. nonce: xhK2lT +.. section: Core and Builtins + +Changing ``dict`` keys during iteration of the dict itself, ``keys()``, +``values()``, or ``items()`` will now be detected in certain corner cases +where keys are deleted/added so that the number of keys isn't changed. A +`RuntimeError` will be raised after ``len(dict)`` iterations. Contributed by +Thomas Perl. + +.. + +.. bpo: 36459 +.. date: 2019-03-27-22-35-16 +.. nonce: UAvkKp +.. section: Core and Builtins + +Fix a possible double ``PyMem_FREE()`` due to tokenizer.c's ``tok_nextc()``. + +.. + +.. bpo: 36433 +.. date: 2019-03-26-17-23-02 +.. nonce: -8XzZf +.. section: Core and Builtins + +Fixed TypeError message in classmethoddescr_call. + +.. + +.. bpo: 36430 +.. date: 2019-03-25-23-37-26 +.. nonce: sd9xxQ +.. section: Core and Builtins + +Fix a possible reference leak in :func:`itertools.count`. + +.. + +.. bpo: 36440 +.. date: 2019-03-25-13-45-19 +.. nonce: gkvzhi +.. section: Core and Builtins + +Include node names in ``ParserError`` messages, instead of numeric IDs. +Patch by A. Skrobov. + +.. + +.. bpo: 36143 +.. date: 2019-03-20-00-37-24 +.. nonce: fnKoKo +.. section: Core and Builtins + +Regenerate :mod:`keyword` from the Grammar and Tokens file using pgen. Patch +by Pablo Galindo. + +.. + +.. bpo: 18372 +.. date: 2018-12-08-03-40-43 +.. nonce: DT1nR0 +.. section: Core and Builtins + +Add missing :c:func:`PyObject_GC_Track` calls in the :mod:`pickle` module. +Patch by Zackery Spytz. + +.. + +.. bpo: 35952 +.. date: 2019-04-29-11-47-06 +.. nonce: 3uNuyo +.. section: Library + +Fix pythoninfo when the compiler is missing. + +.. + +.. bpo: 28238 +.. date: 2019-04-28-15-01-29 +.. nonce: gdk38f +.. section: Library + +The ``.find*()`` methods of xml.etree.ElementTree can now search for +wildcards like ``{*}tag`` and ``{ns}*`` that match a tag in any namespace or +all tags in a namespace. Patch by Stefan Behnel. + +.. + +.. bpo: 26978 +.. date: 2019-04-28-01-52-39 +.. nonce: Lpm-SI +.. section: Library + +`pathlib.path.link_to()` is now implemented. It creates a hard link pointing +to a path. + +.. + +.. bpo: 1613500 +.. date: 2019-04-27-21-09-33 +.. nonce: Ogp4P0 +.. section: Library + +:class:`fileinput.FileInput` now uses the input file mode to correctly set +the output file mode (previously it was hardcoded to ``'w'``) when +``inplace=True`` is passed to its constructor. + +.. + +.. bpo: 36734 +.. date: 2019-04-26-17-14-20 +.. nonce: p2MaiN +.. section: Library + +Fix compilation of ``faulthandler.c`` on HP-UX. Initialize ``stack_t +current_stack`` to zero using ``memset()``. + +.. + +.. bpo: 13611 +.. date: 2019-04-26-10-10-34 +.. nonce: XEF4bg +.. section: Library + +The xml.etree.ElementTree packages gained support for C14N 2.0 +serialisation. Patch by Stefan Behnel. + +.. + +.. bpo: 36669 +.. date: 2019-04-24-17-08-45 +.. nonce: X4g0fu +.. section: Library + +Add missing matrix multiplication operator support to weakref.proxy. + +.. + +.. bpo: 36676 +.. date: 2019-04-20-13-10-34 +.. nonce: XF4Egb +.. section: Library + +The XMLParser() in xml.etree.ElementTree provides namespace prefix context +to the parser target if it defines the callback methods "start_ns()" and/or +"end_ns()". Patch by Stefan Behnel. + +.. + +.. bpo: 36673 +.. date: 2019-04-20-09-50-32 +.. nonce: XF4Egb +.. section: Library + +The TreeBuilder and XMLPullParser in xml.etree.ElementTree gained support +for parsing comments and processing instructions. Patch by Stefan Behnel. + +.. + +.. bpo: 36650 +.. date: 2019-04-19-15-29-55 +.. nonce: _EVdrz +.. section: Library + +The C version of functools.lru_cache() was treating calls with an empty +``**kwargs`` dictionary as being distinct from calls with no keywords at +all. This did not result in an incorrect answer, but it did trigger an +unexpected cache miss. + +.. + +.. bpo: 28552 +.. date: 2019-04-18-16-10-29 +.. nonce: MW1TLt +.. section: Library + +Fix :mod:`distutils.sysconfig` if :data:`sys.executable` is ``None`` or an +empty string: use :func:`os.getcwd` to initialize ``project_base``. Fix +also the distutils build command: don't use :data:`sys.executable` if it is +``None`` or an empty string. + +.. + +.. bpo: 35755 +.. date: 2019-04-16-17-50-39 +.. nonce: Fg4EXb +.. section: Library + +:func:`shutil.which` and :func:`distutils.spawn.find_executable` now use +``os.confstr("CS_PATH")`` if available instead of :data:`os.defpath`, if the +``PATH`` environment variable is not set. Moreover, don't use +``os.confstr("CS_PATH")`` nor :data:`os.defpath` if the ``PATH`` environment +variable is set to an empty string. + +.. + +.. bpo: 25430 +.. date: 2019-04-15-12-22-09 +.. nonce: 7_8kqc +.. section: Library + +improve performance of ``IPNetwork.__contains__()`` + +.. + +.. bpo: 30485 +.. date: 2019-04-13-23-42-33 +.. nonce: JHhjJS +.. section: Library + +Path expressions in xml.etree.ElementTree can now avoid explicit namespace +prefixes for tags (or the "{namespace}tag" notation) by passing a default +namespace with an empty string prefix. + +.. + +.. bpo: 36613 +.. date: 2019-04-12-13-52-15 +.. nonce: hqT1qn +.. section: Library + +Fix :mod:`asyncio` wait() not removing callback if exception + +.. + +.. bpo: 36598 +.. date: 2019-04-11-22-11-24 +.. nonce: hfzDUl +.. section: Library + +Fix ``isinstance`` check for Mock objects with spec when the code is +executed under tracing. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 18748 +.. date: 2019-04-11-16-09-42 +.. nonce: QW7upB +.. section: Library + +In development mode (:option:`-X` ``dev``) and in debug build, the +:class:`io.IOBase` destructor now logs ``close()`` exceptions. These +exceptions are silent by default in release mode. + +.. + +.. bpo: 36575 +.. date: 2019-04-09-22-40-52 +.. nonce: Vg_p92 +.. section: Library + +The ``_lsprof`` module now uses internal timer same to +``time.perf_counter()`` by default. ``gettimeofday(2)`` was used on Unix. +New timer has better resolution on most Unix platforms and timings are no +longer impacted by system clock updates since ``perf_counter()`` is +monotonic. Patch by Inada Naoki. + +.. + +.. bpo: 33461 +.. date: 2019-04-09-14-46-28 +.. nonce: SYJM-E +.. section: Library + +``json.loads`` now emits ``DeprecationWarning`` when ``encoding`` option is +specified. Patch by Matthias Bussonnier. + +.. + +.. bpo: 36559 +.. date: 2019-04-09-12-02-35 +.. nonce: LbDRrw +.. section: Library + +The random module now prefers the lean internal _sha512 module over hashlib +for seed(version=2) to optimize import time. + +.. + +.. bpo: 17561 +.. date: 2019-04-09-04-08-46 +.. nonce: hOhVnh +.. section: Library + +Set backlog=None as the default for socket.create_server. + +.. + +.. bpo: 34373 +.. date: 2019-04-08-14-41-22 +.. nonce: lEAl_- +.. section: Library + +Fix :func:`time.mktime` error handling on AIX for year before 1970. + +.. + +.. bpo: 36232 +.. date: 2019-04-06-20-25-25 +.. nonce: SClmhb +.. section: Library + +Improve error message when trying to open existing DBM database that +actually doesn't exist. Patch by Marco Rougeth. + +.. + +.. bpo: 36546 +.. date: 2019-04-06-14-23-00 +.. nonce: YXjbyY +.. section: Library + +Add statistics.quantiles() + +.. + +.. bpo: 36050 +.. date: 2019-04-05-21-29-53 +.. nonce: x9DRKE +.. section: Library + +Optimized ``http.client.HTTPResponse.read()`` for large response. Patch by +Inada Naoki. + +.. + +.. bpo: 36522 +.. date: 2019-04-03-20-46-47 +.. nonce: g5x3By +.. section: Library + +If *debuglevel* is set to >0 in :mod:`http.client`, print all values for +headers with multiple values for the same header name. Patch by Matt +Houglum. + +.. + +.. bpo: 36492 +.. date: 2019-03-31-10-21-54 +.. nonce: f7vyUs +.. section: Library + +Deprecated passing required arguments like *func* as keyword arguments in +functions which should accept arbitrary keyword arguments and pass them to +other function. Arbitrary keyword arguments (even with names "self" and +"func") can now be passed to these functions if the required arguments are +passed as positional arguments. + +.. + +.. bpo: 27181 +.. date: 2019-03-31-01-18-52 +.. nonce: LVUWcc +.. section: Library + +Add statistics.geometric_mean(). + +.. + +.. bpo: 30427 +.. date: 2019-03-28-21-17-08 +.. nonce: lxzvbw +.. section: Library + +``os.path.normcase()`` relies on ``os.fspath()`` to check the type of its +argument. Redundant checks have been removed from its +``posixpath.normcase()`` and ``ntpath.normcase()`` implementations. Patch by +Wolfgang Maier. + +.. + +.. bpo: 36385 +.. date: 2019-03-27-02-09-22 +.. nonce: we2F45 +.. section: Library + +Stop rejecting IPv4 octets for being ambiguously octal. Leading zeros are +ignored, and no longer are assumed to specify octal octets. Octets are +always decimal numbers. Octets must still be no more than three digits, +including leading zeroes. + +.. + +.. bpo: 36434 +.. date: 2019-03-26-14-20-59 +.. nonce: PTdidw +.. section: Library + +Errors during writing to a ZIP file no longer prevent to properly close it. + +.. + +.. bpo: 36407 +.. date: 2019-03-23-17-16-15 +.. nonce: LG3aC4 +.. section: Library + +Fixed wrong indentation writing for CDATA section in xml.dom.minidom. Patch +by Vladimir Surjaninov. + +.. + +.. bpo: 36326 +.. date: 2019-03-22-13-47-52 +.. nonce: WCnEI5 +.. section: Library + +inspect.getdoc() can now find docstrings for member objects when __slots__ +is a dictionary. + +.. + +.. bpo: 36366 +.. date: 2019-03-20-15-13-18 +.. nonce: n0eav_ +.. section: Library + +Calling ``stop()`` on an unstarted or stopped :func:`unittest.mock.patch` +object will now return `None` instead of raising :exc:`RuntimeError`, making +the method idempotent. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 36348 +.. date: 2019-03-18-16-16-55 +.. nonce: E0w_US +.. section: Library + +The :meth:`imap.IMAP4.logout` method no longer ignores silently arbitrary +exceptions. + +.. + +.. bpo: 31904 +.. date: 2019-03-13-16-48-42 +.. nonce: 9sjd38 +.. section: Library + +Add time module support and fix test_time faiures for VxWorks. + +.. + +.. bpo: 36227 +.. date: 2019-03-07-20-02-18 +.. nonce: i2Z1XR +.. section: Library + +Added support for keyword arguments `default_namespace` and +`xml_declaration` in functions ElementTree.tostring() and +ElementTree.tostringlist(). + +.. + +.. bpo: 36004 +.. date: 2019-02-17-12-55-51 +.. nonce: hCt_KK +.. section: Library + +Added new alternate constructors :meth:`datetime.date.fromisocalendar` and +:meth:`datetime.datetime.fromisocalendar`, which construct date objects from +ISO year, week number and weekday; these are the inverse of each class's +``isocalendar`` method. Patch by Paul Ganssle. + +.. + +.. bpo: 35936 +.. date: 2019-02-16-22-19-32 +.. nonce: Ay5WtD +.. section: Library + +:mod:`modulefinder` no longer depends on the deprecated :mod:`imp` module, +and the initializer for :class:`modulefinder.ModuleFinder` now has immutable +default arguments. Patch by Brandt Bucher. + +.. + +.. bpo: 35376 +.. date: 2019-02-13-18-56-27 +.. nonce: UFhYLj +.. section: Library + +:mod:`modulefinder` correctly handles modules that have the same name as a +bad package. Patch by Brandt Bucher. + +.. + +.. bpo: 17396 +.. date: 2019-02-13-18-56-22 +.. nonce: oKRkrD +.. section: Library + +:mod:`modulefinder` no longer crashes when encountering syntax errors in +followed imports. Patch by Brandt Bucher. + +.. + +.. bpo: 35934 +.. date: 2019-02-07-20-25-39 +.. nonce: QmfNmY +.. section: Library + +Added :meth:`~socket.create_server()` and +:meth:`~socket.has_dualstack_ipv6()` convenience functions to automate the +necessary tasks usually involved when creating a server socket, including +accepting both IPv4 and IPv6 connections on the same socket. (Contributed +by Giampaolo Rodola in :issue:`17561`.) + +.. + +.. bpo: 23078 +.. date: 2019-01-18-23-10-10 +.. nonce: l4dFoj +.. section: Library + +Add support for :func:`classmethod` and :func:`staticmethod` to +:func:`unittest.mock.create_autospec`. Initial patch by Felipe Ochoa. + +.. + +.. bpo: 35416 +.. date: 2018-12-05-09-55-05 +.. nonce: XALKZG +.. section: Library + +Fix potential resource warnings in distutils. Patch by Mickaël Schoentgen. + +.. + +.. bpo: 25451 +.. date: 2018-11-07-23-44-25 +.. nonce: re_8db +.. section: Library + +Add transparency methods to :class:`tkinter.PhotoImage`. Patch by Zackery +Spytz. + +.. + +.. bpo: 35082 +.. date: 2018-10-27-11-54-12 +.. nonce: HDj1nr +.. section: Library + +Don't return deleted attributes when calling dir on a +:class:`unittest.mock.Mock`. + +.. + +.. bpo: 34547 +.. date: 2018-10-05-16-01-00 +.. nonce: abbaa +.. section: Library + +:class:`wsgiref.handlers.BaseHandler` now handles abrupt client connection +terminations gracefully. Patch by Petter Strandmark. + +.. + +.. bpo: 31658 +.. date: 2018-07-30-12-00-15 +.. nonce: _bx7a_ +.. section: Library + +:func:`xml.sax.parse` now supports :term:`path-like `. +Patch by Mickaël Schoentgen. + +.. + +.. bpo: 34139 +.. date: 2018-07-18-11-25-34 +.. nonce: tKbmW7 +.. section: Library + +Remove stale unix datagram socket before binding + +.. + +.. bpo: 33530 +.. date: 2018-05-29-18-34-53 +.. nonce: _4Q_bi +.. section: Library + +Implemented Happy Eyeballs in `asyncio.create_connection()`. Added two new +arguments, *happy_eyeballs_delay* and *interleave*, to specify Happy +Eyeballs behavior. + +.. + +.. bpo: 33291 +.. date: 2018-04-11-11-41-52 +.. nonce: -xLGf8 +.. section: Library + +Do not raise AttributeError when calling the inspect functions +isgeneratorfunction, iscoroutinefunction, isasyncgenfunction on a method +created from an arbitrary callable. Instead, return False. + +.. + +.. bpo: 31310 +.. date: 2018-04-06-11-06-23 +.. nonce: eq9ky0 +.. section: Library + +Fix the multiprocessing.semaphore_tracker so it is reused by child processes + +.. + +.. bpo: 31292 +.. date: 2017-08-30-20-27-00 +.. nonce: dKIaZb +.. section: Library + +Fix ``setup.py check --restructuredtext`` for files containing ``include`` +directives. + +.. + +.. bpo: 36625 +.. date: 2019-04-15-12-02-45 +.. nonce: x3LMCF +.. section: Documentation + +Remove obsolete comments from docstrings in fractions.Fraction + +.. + +.. bpo: 30840 +.. date: 2019-04-14-19-46-21 +.. nonce: R-JFzw +.. section: Documentation + +Document relative imports + +.. + +.. bpo: 36523 +.. date: 2019-04-04-19-11-47 +.. nonce: sG1Tr4 +.. section: Documentation + +Add docstring for io.IOBase.writelines(). + +.. + +.. bpo: 36425 +.. date: 2019-03-27-22-46-00 +.. nonce: kG9gx1 +.. section: Documentation + +New documentation translation: `Simplified Chinese +`_. + +.. + +.. bpo: 36345 +.. date: 2019-03-26-14-58-34 +.. nonce: r2stx3 +.. section: Documentation + +Avoid the duplication of code from ``Tools/scripts/serve.py`` in using the +:rst:dir:`literalinclude` directive for the basic wsgiref-based web server +in the documentation of :mod:`wsgiref`. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36345 +.. date: 2019-03-23-09-25-12 +.. nonce: L704Zv +.. section: Documentation + +Using the code of the ``Tools/scripts/serve.py`` script as an example in the +:mod:`wsgiref` documentation. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36157 +.. date: 2019-03-08-15-39-47 +.. nonce: nF1pP1 +.. section: Documentation + +Added Documention for PyInterpreterState_Main(). + +.. + +.. bpo: 33043 +.. date: 2019-02-24-03-15-10 +.. nonce: 8knWTS +.. section: Documentation + +Updates the docs.python.org page with the addition of a 'Contributing to +Docs' link at the end of the page (between 'Reporting Bugs' and 'About +Documentation'). Updates the 'Found a Bug' page with additional links and +information in the Documentation Bugs section. + +.. + +.. bpo: 35581 +.. date: 2018-12-25-12-56-57 +.. nonce: aA7r6T +.. section: Documentation + +@typing.type_check_only now allows type stubs to mark functions and classes +not available during runtime. + +.. + +.. bpo: 33832 +.. date: 2018-06-15-15-57-37 +.. nonce: xBFhKw +.. section: Documentation + +Add glossary entry for 'magic method'. + +.. + +.. bpo: 32913 +.. date: 2018-02-22-15-48-16 +.. nonce: f3utho +.. section: Documentation + +Added re.Match.groupdict example to regex HOWTO. + +.. + +.. bpo: 36719 +.. date: 2019-04-26-09-02-49 +.. nonce: ys2uqH +.. section: Tests + +regrtest now always detects uncollectable objects. Previously, the check was +only enabled by ``--findleaks``. The check now also works with +``-jN/--multiprocess N``. ``--findleaks`` becomes a deprecated alias to +``--fail-env-changed``. + +.. + +.. bpo: 36725 +.. date: 2019-04-26-04-12-29 +.. nonce: B8-ghi +.. section: Tests + +When using mulitprocessing mode (-jN), regrtest now better reports errors if +a worker process fails, and it exits immediately on a worker thread failure +or when interrupted. + +.. + +.. bpo: 36454 +.. date: 2019-04-23-17-48-11 +.. nonce: 0q4lQz +.. section: Tests + +Change test_time.test_monotonic() to test only the lower bound of elapsed +time after a sleep command rather than the upper bound. This prevents +unnecessary test failures on slow buildbots. Patch by Victor Stinner. + +.. + +.. bpo: 32424 +.. date: 2019-04-21-17-55-18 +.. nonce: yDy49h +.. section: Tests + +Improve test coverage for xml.etree.ElementTree. Patch by Gordon P. Hemsley. + +.. + +.. bpo: 32424 +.. date: 2019-04-21-17-53-50 +.. nonce: Q4rBmn +.. section: Tests + +Fix typo in test_cyclic_gc() test for xml.etree.ElementTree. Patch by Gordon +P. Hemsley. + +.. + +.. bpo: 36635 +.. date: 2019-04-15-16-55-49 +.. nonce: __FTq9 +.. section: Tests + +Add a new :mod:`_testinternalcapi` module to test the internal C API. + +.. + +.. bpo: 36629 +.. date: 2019-04-15-11-57-39 +.. nonce: ySnaL3 +.. section: Tests + +Fix ``test_imap4_host_default_value()`` of ``test_imaplib``: catch also +:data:`errno.ENETUNREACH` error. + +.. + +.. bpo: 36611 +.. date: 2019-04-12-12-44-42 +.. nonce: UtorXL +.. section: Tests + +Fix ``test_sys.test_getallocatedblocks()`` when :mod:`tracemalloc` is +enabled. + +.. + +.. bpo: 36560 +.. date: 2019-04-09-14-08-02 +.. nonce: _ejeOr +.. section: Tests + +Fix reference leak hunting in regrtest: compute also deltas (of reference +count, allocated memory blocks, file descriptor count) during warmup, to +ensure that everything is initialized before starting to hunt reference +leaks. + +.. + +.. bpo: 36565 +.. date: 2019-04-08-19-01-21 +.. nonce: 2bxgtU +.. section: Tests + +Fix reference hunting (``python3 -m test -R 3:3``) when Python has no +built-in abc module. + +.. + +.. bpo: 31904 +.. date: 2019-04-08-09-24-36 +.. nonce: ab03ea +.. section: Tests + +Port test_resource to VxWorks: skip tests cases setting RLIMIT_FSIZE and +RLIMIT_CPU. + +.. + +.. bpo: 31904 +.. date: 2019-04-01-16-06-36 +.. nonce: peaceF +.. section: Tests + +Fix test_tabnanny on VxWorks: adjust ENOENT error message. + +.. + +.. bpo: 36436 +.. date: 2019-03-26-13-49-21 +.. nonce: yAtN0V +.. section: Tests + +Fix ``_testcapi.pymem_buffer_overflow()``: handle memory allocation failure. + +.. + +.. bpo: 31904 +.. date: 2019-03-19-17-39-25 +.. nonce: QxhhRx +.. section: Tests + +Fix test_utf8_mode on VxWorks: Python always use UTF-8 on VxWorks. + +.. + +.. bpo: 36341 +.. date: 2019-03-18-10-47-45 +.. nonce: UXlY0P +.. section: Tests + +Fix tests that may fail with PermissionError upon calling bind() on AF_UNIX +sockets. + +.. + +.. bpo: 36747 +.. date: 2019-04-29-09-57-20 +.. nonce: 1YEyu- +.. section: Build + +Remove the stale scriptsinstall Makefile target. + +.. + +.. bpo: 21536 +.. date: 2019-04-25-01-51-52 +.. nonce: ACQkiC +.. section: Build + +On Unix, C extensions are no longer linked to libpython except on Android. + +It is now possible for a statically linked Python to load a C extension +built using a shared library Python. + +When Python is embedded, ``libpython`` must not be loaded with +``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using +``RTLD_LOCAL``, it was already not possible to load C extensions which were +not linked to ``libpython``, such as C extensions of the standard library +built by the ``*shared*`` section of ``Modules/Setup``. + +distutils, python-config and python-config.py have been modified. + +.. + +.. bpo: 36707 +.. date: 2019-04-24-02-29-15 +.. nonce: 8ZNB67 +.. section: Build + +``./configure --with-pymalloc`` no longer adds the ``m`` flag to SOABI +(sys.implementation.cache_tag). Enabling or disabling pymalloc has no impact +on the ABI. + +.. + +.. bpo: 36635 +.. date: 2019-04-16-13-58-52 +.. nonce: JKlzkf +.. section: Build + +Change ``PyAPI_FUNC(type)``, ``PyAPI_DATA(type)`` and ``PyMODINIT_FUNC`` +macros of ``pyport.h`` when ``Py_BUILD_CORE_MODULE`` is defined. The +``Py_BUILD_CORE_MODULE`` define must be now be used to build a C extension +as a dynamic library accessing Python internals: export the PyInit_xxx() +function in DLL exports on Windows. + +.. + +.. bpo: 31904 +.. date: 2019-04-15-15-01-29 +.. nonce: 38fdkg +.. section: Build + +Don't build the ``_crypt`` extension on VxWorks. + +.. + +.. bpo: 36618 +.. date: 2019-04-12-19-49-10 +.. nonce: gcI9iq +.. section: Build + +Add ``-fmax-type-align=8`` to CFLAGS when clang compiler is detected. The +pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects +alignment on 16 bytes by default and so uses MOVAPS instruction which can +lead to segmentation fault. Instruct clang that Python is limited to +alignemnt on 8 bytes to use MOVUPS instruction instead: slower but don't +trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag +must be added to ``CFLAGS`` and not just ``CFLAGS_NODIST``, since third +party C extensions can have the same issue. + +.. + +.. bpo: 36605 +.. date: 2019-04-11-18-50-58 +.. nonce: gk5czf +.. section: Build + +``make tags`` and ``make TAGS`` now also parse ``Modules/_io/*.c`` and +``Modules/_io/*.h``. + +.. + +.. bpo: 36465 +.. date: 2019-04-09-18-19-43 +.. nonce: -w6vx6 +.. section: Build + +Release builds and debug builds are now ABI compatible: defining the +``Py_DEBUG`` macro no longer implies the ``Py_TRACE_REFS`` macro, which +introduces the only ABI incompatibility. The ``Py_TRACE_REFS`` macro, which +adds the :func:`sys.getobjects` function and the :envvar:`PYTHONDUMPREFS` +environment variable, can be set using the new ``./configure +--with-trace-refs`` build option. + +.. + +.. bpo: 36577 +.. date: 2019-04-09-17-31-47 +.. nonce: 34kuUW +.. section: Build + +setup.py now correctly reports missing OpenSSL headers and libraries again. + +.. + +.. bpo: 36544 +.. date: 2019-04-06-18-53-03 +.. nonce: hJr2_a +.. section: Build + +Fix regression introduced in bpo-36146 refactoring setup.py + +.. + +.. bpo: 36508 +.. date: 2019-04-02-17-01-23 +.. nonce: SN5Y6N +.. section: Build + +``python-config --ldflags`` no longer includes flags of the +``LINKFORSHARED`` variable. The ``LINKFORSHARED`` variable must only be used +to build executables. + +.. + +.. bpo: 36503 +.. date: 2019-04-02-09-25-23 +.. nonce: 0xzfkQ +.. section: Build + +Remove references to "aix3" and "aix4". Patch by M. Felt. + +.. + +.. bpo: 35920 +.. date: 2019-04-22-16-59-20 +.. nonce: VSfGOI +.. section: Windows + +Added platform.win32_edition() and platform.win32_is_iot(). Added support +for cross-compiling packages for Windows ARM32. Skip tests that are not +expected to work on Windows IoT Core ARM32. + +.. + +.. bpo: 36649 +.. date: 2019-04-17-11-39-24 +.. nonce: arbzIo +.. section: Windows + +Remove trailing spaces for registry keys when installed via the Store. + +.. + +.. bpo: 34144 +.. date: 2019-04-10-04-35-31 +.. nonce: _KzB5z +.. section: Windows + +Fixed activate.bat to correctly update codepage when chcp.com returns dots +in output. Patch by Lorenz Mende. + +.. + +.. bpo: 36509 +.. date: 2019-04-02-10-11-18 +.. nonce: DdaM67 +.. section: Windows + +Added preset-iot layout for Windows IoT ARM containers. This layout doesn't +contain UI components like tkinter or IDLE. It also doesn't contain files to +support on-target builds since Windows ARM32 builds must be cross-compiled +when using MSVC. + +.. + +.. bpo: 35941 +.. date: 2019-03-28-03-51-16 +.. nonce: UnlAEE +.. section: Windows + +enum_certificates function of the ssl module now returns certificates from +all available certificate stores inside windows in a query instead of +returning only certificates from the system wide certificate store. This +includes certificates from these certificate stores: local machine, local +machine enterprise, local machine group policy, current user, current user +group policy, services, users. ssl.enum_crls() function is changed in the +same way to return all certificate revocation lists inside the windows +certificate revocation list stores. + +.. + +.. bpo: 36441 +.. date: 2019-03-26-11-46-15 +.. nonce: lYjGF1 +.. section: Windows + +Fixes creating a venv when debug binaries are installed. + +.. + +.. bpo: 36085 +.. date: 2019-03-18-11-44-49 +.. nonce: mLfxfc +.. section: Windows + +Enable better DLL resolution on Windows by using safe DLL search paths and +adding :func:`os.add_dll_directory`. + +.. + +.. bpo: 36010 +.. date: 2019-03-16-10-24-58 +.. nonce: dttWfp +.. section: Windows + +Add the venv standard library module to the nuget distribution for Windows. + +.. + +.. bpo: 29515 +.. date: 2019-03-05-18-09-43 +.. nonce: vwUTv0 +.. section: Windows + +Add the following socket module constants on Windows: IPPROTO_AH IPPROTO_CBT +IPPROTO_DSTOPTS IPPROTO_EGP IPPROTO_ESP IPPROTO_FRAGMENT IPPROTO_GGP +IPPROTO_HOPOPTS IPPROTO_ICLFXBM IPPROTO_ICMPV6 IPPROTO_IDP IPPROTO_IGMP +IPPROTO_IGP IPPROTO_IPV4 IPPROTO_IPV6 IPPROTO_L2TP IPPROTO_MAX IPPROTO_ND +IPPROTO_NONE IPPROTO_PGM IPPROTO_PIM IPPROTO_PUP IPPROTO_RDP IPPROTO_ROUTING +IPPROTO_SCTP IPPROTO_ST + +.. + +.. bpo: 35947 +.. date: 2019-02-11-14-53-17 +.. nonce: 9vI4hP +.. section: Windows + +Added current version of libffi to cpython-source-deps. Change _ctypes to +use current version of libffi on Windows. + +.. + +.. bpo: 34060 +.. date: 2018-07-20-13-09-19 +.. nonce: v-z87j +.. section: Windows + +Report system load when running test suite on Windows. Patch by Ammar Askar. +Based on prior work by Jeremy Kloth. + +.. + +.. bpo: 31512 +.. date: 2017-10-04-12-40-45 +.. nonce: YQeBt2 +.. section: Windows + +With the Windows 10 Creators Update, non-elevated users can now create +symlinks as long as the computer has Developer Mode enabled. + +.. + +.. bpo: 34602 +.. date: 2019-04-29-10-54-14 +.. nonce: Lrl2zU +.. section: macOS + +Avoid failures setting macOS stack resource limit with resource.setrlimit. +This reverts an earlier fix for bpo-18075 which forced a non-default stack +size when building the interpreter executable on macOS. + +.. + +.. bpo: 36429 +.. date: 2019-03-26-00-09-50 +.. nonce: w-jL2e +.. section: IDLE + +Fix starting IDLE with pyshell. Add idlelib.pyshell alias at top; remove +pyshell alias at bottom. Remove obsolete __name__=='__main__' command. + +.. + +.. bpo: 14546 +.. date: 2019-04-30-14-30-29 +.. nonce: r38Y-6 +.. section: Tools/Demos + +Fix the argument handling in Tools/scripts/lll.py. + +.. + +.. bpo: 36763 +.. date: 2019-05-01-00-42-08 +.. nonce: vghb86 +.. section: C API + +Fix memory leak in :c:func:`Py_SetStandardStreamEncoding`: release memory if +the function is called twice. + +.. + +.. bpo: 36641 +.. date: 2019-04-16-21-18-19 +.. nonce: pz-DIR +.. section: C API + +:c:macro:`PyDoc_VAR(name)` and :c:macro:`PyDoc_STRVAR(name,str)` now create +``static const char name[]`` instead of ``static char name[]``. Patch by +Inada Naoki. + +.. + +.. bpo: 36389 +.. date: 2019-04-11-12-20-35 +.. nonce: P9QFoP +.. section: C API + +Change the value of ``CLEANBYTE``, ``DEADDYTE`` and ``FORBIDDENBYTE`` +internal constants used by debug hooks on Python memory allocators +(:c:func:`PyMem_SetupDebugHooks` function). Byte patterns ``0xCB``, ``0xDB`` +and ``0xFB`` have been replaced with ``0xCD``, ``0xDD`` and ``0xFD`` to use +the same values than Windows CRT debug ``malloc()`` and ``free()``. + +.. + +.. bpo: 36443 +.. date: 2019-03-27-15-58-23 +.. nonce: tAfZR9 +.. section: C API + +Since Python 3.7.0, calling :c:func:`Py_DecodeLocale` before +:c:func:`Py_Initialize` produces mojibake if the ``LC_CTYPE`` locale is +coerced and/or if the UTF-8 Mode is enabled by the user configuration. The +LC_CTYPE coercion and UTF-8 Mode are now disabled by default to fix the +mojibake issue. They must now be enabled explicitly (opt-in) using the new +:c:func:`_Py_PreInitialize` API with ``_PyPreConfig``. + +.. + +.. bpo: 36025 +.. date: 2019-02-19-08-23-42 +.. nonce: tnwylQ +.. section: C API + +Fixed an accidental change to the datetime C API where the arguments to the +:c:func:`PyDate_FromTimestamp` function were incorrectly interpreted as a +single timestamp rather than an arguments tuple, which causes existing code +to start raising :exc:`TypeError`. The backwards-incompatible change was +only present in alpha releases of Python 3.8. Patch by Paul Ganssle. + +.. + +.. bpo: 35810 +.. date: 2019-01-23-12-38-11 +.. nonce: wpbWeb +.. section: C API + +Modify ``PyObject_Init`` to correctly increase the refcount of heap- +allocated Type objects. Also fix the refcounts of the heap-allocated types +that were either doing this manually or not decreasing the type's refcount +in tp_dealloc diff --git a/Misc/NEWS.d/next/Build/2019-02-21-14-48-31.bpo-31904.J82jY2.rst b/Misc/NEWS.d/next/Build/2019-02-21-14-48-31.bpo-31904.J82jY2.rst deleted file mode 100644 index 1292193b729..00000000000 --- a/Misc/NEWS.d/next/Build/2019-02-21-14-48-31.bpo-31904.J82jY2.rst +++ /dev/null @@ -1 +0,0 @@ -Enable build system to cross-build for VxWorks RTOS. diff --git a/Misc/NEWS.d/next/Build/2019-02-28-18-09-01.bpo-36146.IwPJVT.rst b/Misc/NEWS.d/next/Build/2019-02-28-18-09-01.bpo-36146.IwPJVT.rst deleted file mode 100644 index 93c1e1afac8..00000000000 --- a/Misc/NEWS.d/next/Build/2019-02-28-18-09-01.bpo-36146.IwPJVT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix setup.py on macOS: only add ``/usr/include/ffi`` to include -directories of _ctypes, not for all extensions. diff --git a/Misc/NEWS.d/next/Build/2019-03-01-17-49-22.bpo-36146.VeoyG7.rst b/Misc/NEWS.d/next/Build/2019-03-01-17-49-22.bpo-36146.VeoyG7.rst deleted file mode 100644 index f32a821302c..00000000000 --- a/Misc/NEWS.d/next/Build/2019-03-01-17-49-22.bpo-36146.VeoyG7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add ``TEST_EXTENSIONS`` constant to ``setup.py`` to allow to not build test -extensions like ``_testcapi``. diff --git a/Misc/NEWS.d/next/Build/2019-03-18-23-49-15.bpo-36356.WNrwYI.rst b/Misc/NEWS.d/next/Build/2019-03-18-23-49-15.bpo-36356.WNrwYI.rst deleted file mode 100644 index d30f5d586b7..00000000000 --- a/Misc/NEWS.d/next/Build/2019-03-18-23-49-15.bpo-36356.WNrwYI.rst +++ /dev/null @@ -1 +0,0 @@ -Fix leaks that led to build failure when configured with address sanitizer. diff --git a/Misc/NEWS.d/next/C API/2019-03-01-03-23-48.bpo-36142.7F6wJd.rst b/Misc/NEWS.d/next/C API/2019-03-01-03-23-48.bpo-36142.7F6wJd.rst deleted file mode 100644 index 0005270c22d..00000000000 --- a/Misc/NEWS.d/next/C API/2019-03-01-03-23-48.bpo-36142.7F6wJd.rst +++ /dev/null @@ -1,2 +0,0 @@ -The whole coreconfig.h header is now excluded from Py_LIMITED_API. Move -functions definitions into a new internal pycore_coreconfig.h header. diff --git a/Misc/NEWS.d/next/C API/2019-03-20-22-02-40.bpo-36381.xlzDJ2.rst b/Misc/NEWS.d/next/C API/2019-03-20-22-02-40.bpo-36381.xlzDJ2.rst deleted file mode 100644 index 66982aa7eaf..00000000000 --- a/Misc/NEWS.d/next/C API/2019-03-20-22-02-40.bpo-36381.xlzDJ2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise ``DeprecationWarning`` when '#' formats are used for building or -parsing values without ``PY_SSIZE_T_CLEAN``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-11-00-50-03.bpo-11814.M12CMH.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-11-00-50-03.bpo-11814.M12CMH.rst deleted file mode 100644 index b3bec728d9d..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-11-00-50-03.bpo-11814.M12CMH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Retire pgen and use a modified version of pgen2 to generate the parser. -Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-20-08-51-04.bpo-36048.I3LJt9.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-20-08-51-04.bpo-36048.I3LJt9.rst deleted file mode 100644 index d032e84341c..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-20-08-51-04.bpo-36048.I3LJt9.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :meth:`~object.__index__` special method will be used instead of -:meth:`~object.__int__` for implicit conversion of Python numbers to C -integers. Using the ``__int__()`` method in implicit conversions has been -deprecated. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-26-17-34-49.bpo-31904.R4KSj6.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-26-17-34-49.bpo-31904.R4KSj6.rst deleted file mode 100644 index 29514952fd7..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-26-17-34-49.bpo-31904.R4KSj6.rst +++ /dev/null @@ -1 +0,0 @@ -Use UTF-8 as the system encoding on VxWorks. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-27-16-49-08.bpo-35975.IescLY.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-27-16-49-08.bpo-35975.IescLY.rst deleted file mode 100644 index 3bbfc74469c..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-27-16-49-08.bpo-35975.IescLY.rst +++ /dev/null @@ -1,7 +0,0 @@ -Add a ``feature_version`` flag to ``ast.parse()`` (documented) and -``compile()`` (hidden) that allows tweaking the parser to support older -versions of the grammar. In particular, if ``feature_version`` is 5 or 6, -the hacks for the ``async`` and ``await`` keyword from PEP 492 are -reinstated. (For 7 or higher, these are unconditionally treated as keywords, -but they are still special tokens rather than ``NAME`` tokens that the -parser driver recognizes.) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst deleted file mode 100644 index ee9b0c11024..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-01-13-48-01.bpo-36124.Blzxq1.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add a new interpreter-specific dict and expose it in the C-API via -PyInterpreterState_GetDict(). This parallels PyThreadState_GetDict(). -However, extension modules should continue using PyModule_GetState() for -their own internal per-interpreter state. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst deleted file mode 100644 index f018e31ede9..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Cleaned up left-over vestiges of Python 2 unbound method handling in method objects and documentation. -Patch by Martijn Pieters \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-07-13-05-43.bpo-36218.dZemNt.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-07-13-05-43.bpo-36218.dZemNt.rst deleted file mode 100644 index ab6d207f37e..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-07-13-05-43.bpo-36218.dZemNt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a segfault occuring when sorting a list of heterogeneous values. Patch -contributed by Rémi Lapeyre and Elliot Gorokhovsky. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-09-15-47-05.bpo-36252.sCQFKq.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-09-15-47-05.bpo-36252.sCQFKq.rst deleted file mode 100644 index b79bc493f4f..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-09-15-47-05.bpo-36252.sCQFKq.rst +++ /dev/null @@ -1 +0,0 @@ -Update Unicode databases to version 12.0.0. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-11-15-37-33.bpo-36262.v3N6Fz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-11-15-37-33.bpo-36262.v3N6Fz.rst deleted file mode 100644 index b5ccc95fd70..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-11-15-37-33.bpo-36262.v3N6Fz.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix an unlikely memory leak on conversion from string to float in the function -``_Py_dg_strtod()`` used by ``float(str)``, ``complex(str)``, -:func:`pickle.load`, :func:`marshal.load`, etc. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-11-22-30-56.bpo-30040.W9z8X7.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-11-22-30-56.bpo-30040.W9z8X7.rst deleted file mode 100644 index 0975dba1f37..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-11-22-30-56.bpo-30040.W9z8X7.rst +++ /dev/null @@ -1,3 +0,0 @@ -New empty dict uses fewer memory for now. It used more memory than empty -dict created by ``dict.clear()``. And empty dict creation and deletion -is about 2x faster. Patch by Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-13-22-47-28.bpo-36282.zs7RKP.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-13-22-47-28.bpo-36282.zs7RKP.rst deleted file mode 100644 index f9ec51e381d..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-13-22-47-28.bpo-36282.zs7RKP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improved error message for too much positional arguments in some builtin -functions. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-18-09-27-54.bpo-36332.yEC-Vz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-18-09-27-54.bpo-36332.yEC-Vz.rst deleted file mode 100644 index 2c69c1c5652..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-18-09-27-54.bpo-36332.yEC-Vz.rst +++ /dev/null @@ -1,2 +0,0 @@ -The builtin :func:`compile` can now handle AST objects that contain -assignment expressions. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-18-10-56-53.bpo-36333.4dqemZ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-18-10-56-53.bpo-36333.4dqemZ.rst deleted file mode 100644 index e5af44fda40..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-18-10-56-53.bpo-36333.4dqemZ.rst +++ /dev/null @@ -1 +0,0 @@ -Fix leak in _PyRuntimeState_Fini. Contributed by Stéphane Wirtel. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst deleted file mode 100644 index 84e4b8a8523..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Python initialization now fails if decoding ``pybuilddir.txt`` configuration -file fails at startup. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-02-36-40.bpo-36352.qj2trz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-02-36-40.bpo-36352.qj2trz.rst deleted file mode 100644 index 148201cd1b6..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-02-36-40.bpo-36352.qj2trz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Python initialization now fails with an error, rather than silently -truncating paths, if a path is too long. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-03-08-26.bpo-36236.5qN9qK.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-03-08-26.bpo-36236.5qN9qK.rst deleted file mode 100644 index e1c1182d181..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-03-08-26.bpo-36236.5qN9qK.rst +++ /dev/null @@ -1,2 +0,0 @@ -At Python initialization, the current directory is no longer prepended to -:data:`sys.path` if it has been removed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-15-46-42.bpo-36374.EWKMZE.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-15-46-42.bpo-36374.EWKMZE.rst deleted file mode 100644 index 2eac3013685..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-15-46-42.bpo-36374.EWKMZE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a possible null pointer dereference in ``merge_consts_recursive()``. -Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-15-58-23.bpo-36365.jHaErz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-15-58-23.bpo-36365.jHaErz.rst deleted file mode 100644 index 206de56f08f..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-15-58-23.bpo-36365.jHaErz.rst +++ /dev/null @@ -1 +0,0 @@ -repr(structseq) is no longer limited to 512 bytes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-21-00-24-18.bpo-12477.OZHa0t.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-21-00-24-18.bpo-12477.OZHa0t.rst deleted file mode 100644 index aada7f912a6..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-21-00-24-18.bpo-12477.OZHa0t.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug in parsermodule when parsing a state in a DFA that has two or more -arcs with labels of the same type. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-21-22-19-38.bpo-36398.B_jXGe.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-21-22-19-38.bpo-36398.B_jXGe.rst deleted file mode 100644 index 2b00283096f..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-21-22-19-38.bpo-36398.B_jXGe.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a possible crash in ``structseq_repr()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-23-19-51-09.bpo-36412.C7acGn.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-23-19-51-09.bpo-36412.C7acGn.rst deleted file mode 100644 index 0146988151e..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-23-19-51-09.bpo-36412.C7acGn.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a possible crash when creating a new dictionary. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-24-21-33-22.bpo-36421.gJ2Pv9.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-24-21-33-22.bpo-36421.gJ2Pv9.rst deleted file mode 100644 index 2577511de2e..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-03-24-21-33-22.bpo-36421.gJ2Pv9.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a possible double decref in _ctypes.c's ``PyCArrayType_new()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst b/Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst new file mode 100644 index 00000000000..7ca5dd998d9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst @@ -0,0 +1,2 @@ +Fix incorrect use of ``%p`` in format strings. +Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst new file mode 100644 index 00000000000..6c79f97daca --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst @@ -0,0 +1,3 @@ +Removed ``__str__`` implementations from builtin types :class:`bool`, +:class:`int`, :class:`float`, :class:`complex` and few classes from the +standard library. They now inherit ``__str__()`` from :class:`object`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst new file mode 100644 index 00000000000..ae5b915969d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst @@ -0,0 +1,2 @@ +Correct return type for UserList slicing operations. Patch by Michael Blahay, +Erick Cervantes, and vaultah diff --git a/Misc/NEWS.d/next/Documentation/2018-11-21-23-01-37.bpo-21314.PG33VT.rst b/Misc/NEWS.d/next/Documentation/2018-11-21-23-01-37.bpo-21314.PG33VT.rst deleted file mode 100644 index 83080a3a580..00000000000 --- a/Misc/NEWS.d/next/Documentation/2018-11-21-23-01-37.bpo-21314.PG33VT.rst +++ /dev/null @@ -1,3 +0,0 @@ -A new entry was added to the Core Language Section of the Programming FAQ, -which explaines the usage of slash(/) in the signature of a function. Patch -by Lysandros Nikolaou diff --git a/Misc/NEWS.d/next/Documentation/2019-03-02-00-40-57.bpo-36138.yfjNzG.rst b/Misc/NEWS.d/next/Documentation/2019-03-02-00-40-57.bpo-36138.yfjNzG.rst deleted file mode 100644 index f5352bb3958..00000000000 --- a/Misc/NEWS.d/next/Documentation/2019-03-02-00-40-57.bpo-36138.yfjNzG.rst +++ /dev/null @@ -1 +0,0 @@ -Improve documentation about converting datetime.timedelta to scalars. diff --git a/Misc/NEWS.d/next/Documentation/2019-03-17-20-01-41.bpo-36329.L5dJPD.rst b/Misc/NEWS.d/next/Documentation/2019-03-17-20-01-41.bpo-36329.L5dJPD.rst deleted file mode 100644 index 94e5884cc9a..00000000000 --- a/Misc/NEWS.d/next/Documentation/2019-03-17-20-01-41.bpo-36329.L5dJPD.rst +++ /dev/null @@ -1,3 +0,0 @@ -Declare the path of the Python binary for the usage of -``Tools/scripts/serve.py`` when executing ``make -C Doc/ serve``. -Contributed by Stéphane Wirtel diff --git a/Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst b/Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst new file mode 100644 index 00000000000..d3cbf4f6e13 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst @@ -0,0 +1,2 @@ +Added C API Documentation for Time_FromTimeAndFold and PyDateTime_FromDateAndTimeAndFold as per PEP 495. +Patch by Edison Abahurire. \ No newline at end of file diff --git a/Misc/NEWS.d/next/IDLE/2018-06-27-21-18-41.bpo-30348.WbaRJW.rst b/Misc/NEWS.d/next/IDLE/2018-06-27-21-18-41.bpo-30348.WbaRJW.rst deleted file mode 100644 index f665241670c..00000000000 --- a/Misc/NEWS.d/next/IDLE/2018-06-27-21-18-41.bpo-30348.WbaRJW.rst +++ /dev/null @@ -1 +0,0 @@ -Increase test coverage of idlelib.autocomplete by 30%. diff --git a/Misc/NEWS.d/next/IDLE/2019-02-23-17-53-53.bpo-36096.mN5Ly3.rst b/Misc/NEWS.d/next/IDLE/2019-02-23-17-53-53.bpo-36096.mN5Ly3.rst deleted file mode 100644 index cd6f76e9ac2..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-02-23-17-53-53.bpo-36096.mN5Ly3.rst +++ /dev/null @@ -1 +0,0 @@ -Refactor class variables to instance variables in colorizer. diff --git a/Misc/NEWS.d/next/IDLE/2019-02-25-11-40-14.bpo-32129.4qVCzD.rst b/Misc/NEWS.d/next/IDLE/2019-02-25-11-40-14.bpo-32129.4qVCzD.rst deleted file mode 100644 index 54a5c724414..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-02-25-11-40-14.bpo-32129.4qVCzD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid blurry IDLE application icon on macOS with Tk 8.6. Patch by Kevin -Walzer. diff --git a/Misc/NEWS.d/next/IDLE/2019-02-28-18-52-40.bpo-36152.9pkHIU.rst b/Misc/NEWS.d/next/IDLE/2019-02-28-18-52-40.bpo-36152.9pkHIU.rst deleted file mode 100644 index b75ae89ef30..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-02-28-18-52-40.bpo-36152.9pkHIU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove colorizer.ColorDelegator.close_when_done and the -corresponding argument of .close(). In IDLE, both have -always been None or False since 2007. diff --git a/Misc/NEWS.d/next/IDLE/2019-03-02-19-39-53.bpo-23216.ZA7H8H.rst b/Misc/NEWS.d/next/IDLE/2019-03-02-19-39-53.bpo-23216.ZA7H8H.rst deleted file mode 100644 index ec091615a19..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-03-02-19-39-53.bpo-23216.ZA7H8H.rst +++ /dev/null @@ -1 +0,0 @@ -Add docstrings to IDLE search modules. diff --git a/Misc/NEWS.d/next/IDLE/2019-03-06-14-47-57.bpo-23205.Vv0gfH.rst b/Misc/NEWS.d/next/IDLE/2019-03-06-14-47-57.bpo-23205.Vv0gfH.rst deleted file mode 100644 index 9e7c222ffc4..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-03-06-14-47-57.bpo-23205.Vv0gfH.rst +++ /dev/null @@ -1,2 +0,0 @@ -For the grep module, add tests for findfiles, refactor findfiles to be a -module-level function, and refactor findfiles to use os.walk. diff --git a/Misc/NEWS.d/next/IDLE/2019-03-10-00-07-46.bpo-36176.jk_vv6.rst b/Misc/NEWS.d/next/IDLE/2019-03-10-00-07-46.bpo-36176.jk_vv6.rst deleted file mode 100644 index 5998c6fadfc..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-03-10-00-07-46.bpo-36176.jk_vv6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix IDLE autocomplete & calltip popup colors. Prevent conflicts with Linux -dark themes (and slightly darken calltip background). diff --git a/Misc/NEWS.d/next/IDLE/2019-03-21-22-43-21.bpo-36396.xSTX-I.rst b/Misc/NEWS.d/next/IDLE/2019-03-21-22-43-21.bpo-36396.xSTX-I.rst deleted file mode 100644 index 1d142b5c30f..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-03-21-22-43-21.bpo-36396.xSTX-I.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove fgBg param of idlelib.config.GetHighlight(). This param was only used -twice and changed the return type. diff --git a/Misc/NEWS.d/next/IDLE/2019-03-23-01-45-56.bpo-36405.m7Wv1F.rst b/Misc/NEWS.d/next/IDLE/2019-03-23-01-45-56.bpo-36405.m7Wv1F.rst deleted file mode 100644 index bef438d5a5a..00000000000 --- a/Misc/NEWS.d/next/IDLE/2019-03-23-01-45-56.bpo-36405.m7Wv1F.rst +++ /dev/null @@ -1 +0,0 @@ -Use dict unpacking in idlelib. diff --git a/Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst b/Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst new file mode 100644 index 00000000000..df3881bffaa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst @@ -0,0 +1,3 @@ +:meth:`asyncio.AbstractEventLoop.create_datagram_endpoint`: +Do not connect UDP socket when broadcast is allowed. +This allows to receive replies after a UDP broadcast. diff --git a/Misc/NEWS.d/next/Library/2018-11-09-12-45-28.bpo-35198.EJ8keW.rst b/Misc/NEWS.d/next/Library/2018-11-09-12-45-28.bpo-35198.EJ8keW.rst deleted file mode 100644 index 4ce7a7e3423..00000000000 --- a/Misc/NEWS.d/next/Library/2018-11-09-12-45-28.bpo-35198.EJ8keW.rst +++ /dev/null @@ -1 +0,0 @@ -Fix C++ extension compilation on AIX diff --git a/Misc/NEWS.d/next/Library/2018-12-21-09-54-30.bpo-21478.5gsXtc.rst b/Misc/NEWS.d/next/Library/2018-12-21-09-54-30.bpo-21478.5gsXtc.rst deleted file mode 100644 index 1000748c9c4..00000000000 --- a/Misc/NEWS.d/next/Library/2018-12-21-09-54-30.bpo-21478.5gsXtc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Calls to a child function created with :func:`unittest.mock.create_autospec` -should propagate to the parent. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst b/Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst deleted file mode 100644 index 032e1e2c00b..00000000000 --- a/Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Don't set cookie for a request when the request path is a prefix match of -the cookie's path attribute but doesn't end with "/". Patch by Karthikeyan -Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-01-05-16-16-20.bpo-35661.H_UOXc.rst b/Misc/NEWS.d/next/Library/2019-01-05-16-16-20.bpo-35661.H_UOXc.rst deleted file mode 100644 index 43189868611..00000000000 --- a/Misc/NEWS.d/next/Library/2019-01-05-16-16-20.bpo-35661.H_UOXc.rst +++ /dev/null @@ -1 +0,0 @@ -Store the venv prompt in pyvenv.cfg. diff --git a/Misc/NEWS.d/next/Library/2019-01-09-23-43-08.bpo-35493.kEcRGE.rst b/Misc/NEWS.d/next/Library/2019-01-09-23-43-08.bpo-35493.kEcRGE.rst deleted file mode 100644 index fa408c8163b..00000000000 --- a/Misc/NEWS.d/next/Library/2019-01-09-23-43-08.bpo-35493.kEcRGE.rst +++ /dev/null @@ -1,3 +0,0 @@ -Use :func:`multiprocessing.connection.wait` instead of polling each 0.2 -seconds for worker updates in :class:`multiprocessing.Pool`. Patch by Pablo -Galindo. diff --git a/Misc/NEWS.d/next/Library/2019-01-11-08-47-58.bpo-35715.Wi3gl0.rst b/Misc/NEWS.d/next/Library/2019-01-11-08-47-58.bpo-35715.Wi3gl0.rst deleted file mode 100644 index 0c1ec6b53fd..00000000000 --- a/Misc/NEWS.d/next/Library/2019-01-11-08-47-58.bpo-35715.Wi3gl0.rst +++ /dev/null @@ -1 +0,0 @@ -Librates the return value of a ProcessPoolExecutor _process_worker after it's no longer needed to free memory \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst b/Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst new file mode 100644 index 00000000000..0da9c4997e1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst @@ -0,0 +1,2 @@ +:func:`unittest.mock.mock_open` results now respects the argument of read([size]). +Patch contributed by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-01-21-13-56-55.bpo-35802.6633PE.rst b/Misc/NEWS.d/next/Library/2019-01-21-13-56-55.bpo-35802.6633PE.rst deleted file mode 100644 index 8b73d2bd585..00000000000 --- a/Misc/NEWS.d/next/Library/2019-01-21-13-56-55.bpo-35802.6633PE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Clean up code which checked presence of ``os.stat`` / ``os.lstat`` / -``os.chmod`` which are always present. Patch by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-01-28-10-19-40.bpo-35843.7rXGQE.rst b/Misc/NEWS.d/next/Library/2019-01-28-10-19-40.bpo-35843.7rXGQE.rst deleted file mode 100644 index 1a9eaf0d139..00000000000 --- a/Misc/NEWS.d/next/Library/2019-01-28-10-19-40.bpo-35843.7rXGQE.rst +++ /dev/null @@ -1 +0,0 @@ -Implement ``__getitem__`` for ``_NamespacePath``. Patch by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-02-06-12-07-46.bpo-30670.yffB3F.rst b/Misc/NEWS.d/next/Library/2019-02-06-12-07-46.bpo-30670.yffB3F.rst deleted file mode 100644 index 63cdbb363f7..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-06-12-07-46.bpo-30670.yffB3F.rst +++ /dev/null @@ -1,4 +0,0 @@ -`pprint.pp` has been added to pretty-print objects with dictionary -keys being sorted with their insertion order by default. Parameter -*sort_dicts* has been added to `pprint.pprint`, `pprint.pformat` and -`pprint.PrettyPrinter`. Contributed by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-02-10-16-49-16.bpo-21269.Fqi7VH.rst b/Misc/NEWS.d/next/Library/2019-02-10-16-49-16.bpo-21269.Fqi7VH.rst deleted file mode 100644 index 15ad636a5e8..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-10-16-49-16.bpo-21269.Fqi7VH.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``args`` and ``kwargs`` properties to mock call objects. Contributed by Kumar Akshay. diff --git a/Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst b/Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst new file mode 100644 index 00000000000..2e28a25d241 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst @@ -0,0 +1 @@ +Asyncio: Remove inner callback on outer cancellation in shield diff --git a/Misc/NEWS.d/next/Library/2019-02-16-07-11-02.bpo-35899.cjfn5a.rst b/Misc/NEWS.d/next/Library/2019-02-16-07-11-02.bpo-35899.cjfn5a.rst deleted file mode 100644 index 73d4fa17b33..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-16-07-11-02.bpo-35899.cjfn5a.rst +++ /dev/null @@ -1 +0,0 @@ -Enum has been fixed to correctly handle empty strings and strings with non-Latin characters (ie. 'α', 'א') without crashing. Original patch contributed by Maxwell. Assisted by Stéphane Wirtel. diff --git a/Misc/NEWS.d/next/Library/2019-02-19-19-53-46.bpo-36043.l867v0.rst b/Misc/NEWS.d/next/Library/2019-02-19-19-53-46.bpo-36043.l867v0.rst deleted file mode 100644 index f4911a0c8d0..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-19-19-53-46.bpo-36043.l867v0.rst +++ /dev/null @@ -1 +0,0 @@ -:class:`FileCookieJar` supports :term:`path-like object`. Contributed by Stéphane Wirtel diff --git a/Misc/NEWS.d/next/Library/2019-02-23-06-49-06.bpo-36091.26o4Lc.rst b/Misc/NEWS.d/next/Library/2019-02-23-06-49-06.bpo-36091.26o4Lc.rst deleted file mode 100644 index 582be449376..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-23-06-49-06.bpo-36091.26o4Lc.rst +++ /dev/null @@ -1 +0,0 @@ -Clean up reference to async generator in Lib/types. Patch by Henry Chen. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-02-25-13-21-43.bpo-36106.VuhEiQ.rst b/Misc/NEWS.d/next/Library/2019-02-25-13-21-43.bpo-36106.VuhEiQ.rst deleted file mode 100644 index 36e17508cd4..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-25-13-21-43.bpo-36106.VuhEiQ.rst +++ /dev/null @@ -1 +0,0 @@ -Resolve potential name clash with libm's sinpi(). Patch by Dmitrii Pasechnik. diff --git a/Misc/NEWS.d/next/Library/2019-02-25-23-04-00.bpo-35178.NA_rXa.rst b/Misc/NEWS.d/next/Library/2019-02-25-23-04-00.bpo-35178.NA_rXa.rst deleted file mode 100644 index 2593199cfe9..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-25-23-04-00.bpo-35178.NA_rXa.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure custom :func:`warnings.formatwarning` function can receive `line` as -positional argument. Based on patch by Tashrif Billah. diff --git a/Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst b/Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst deleted file mode 100644 index c247e1706a3..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-26-11-34-44.bpo-35652.6KRJu_.rst +++ /dev/null @@ -1,2 +0,0 @@ -shutil.copytree(copy_function=...) erroneously pass DirEntry instead of a -path string. diff --git a/Misc/NEWS.d/next/Library/2019-02-26-22-41-38.bpo-36130._BnZOo.rst b/Misc/NEWS.d/next/Library/2019-02-26-22-41-38.bpo-36130._BnZOo.rst deleted file mode 100644 index 3bab152871f..00000000000 --- a/Misc/NEWS.d/next/Library/2019-02-26-22-41-38.bpo-36130._BnZOo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``pdb`` with ``skip=...`` when stepping into a frame without a -``__name__`` global. Patch by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-03-01-16-10-01.bpo-36103.n6VgXL.rst b/Misc/NEWS.d/next/Library/2019-03-01-16-10-01.bpo-36103.n6VgXL.rst deleted file mode 100644 index 9f7330597e7..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-01-16-10-01.bpo-36103.n6VgXL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Default buffer size used by ``shutil.copyfileobj()`` is changed from 16 KiB -to 64 KiB on non-Windows platform to reduce system call overhead. Contributed -by Inada Naoki. diff --git a/Misc/NEWS.d/next/Library/2019-03-03-11-37-09.bpo-36169.8nWJy7.rst b/Misc/NEWS.d/next/Library/2019-03-03-11-37-09.bpo-36169.8nWJy7.rst deleted file mode 100644 index 49afa2eed29..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-03-11-37-09.bpo-36169.8nWJy7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add overlap() method to statistics.NormalDist. Computes the overlapping -coefficient for two normal distributions. diff --git a/Misc/NEWS.d/next/Library/2019-03-04-10-42-46.bpo-36179.jEyuI-.rst b/Misc/NEWS.d/next/Library/2019-03-04-10-42-46.bpo-36179.jEyuI-.rst deleted file mode 100644 index 61a98778b78..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-04-10-42-46.bpo-36179.jEyuI-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix two unlikely reference leaks in _hashopenssl. The leaks only occur in -out-of-memory cases. diff --git a/Misc/NEWS.d/next/Library/2019-03-06-13-07-29.bpo-36139.6kedum.rst b/Misc/NEWS.d/next/Library/2019-03-06-13-07-29.bpo-36139.6kedum.rst deleted file mode 100644 index 9dcd857cd25..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-06-13-07-29.bpo-36139.6kedum.rst +++ /dev/null @@ -1 +0,0 @@ -Release GIL when closing :class:`~mmap.mmap` objects. diff --git a/Misc/NEWS.d/next/Library/2019-03-06-13-21-33.bpo-35807.W7mmu3.rst b/Misc/NEWS.d/next/Library/2019-03-06-13-21-33.bpo-35807.W7mmu3.rst deleted file mode 100644 index 1109fbed3f9..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-06-13-21-33.bpo-35807.W7mmu3.rst +++ /dev/null @@ -1 +0,0 @@ -Update ensurepip to install pip 19.0.3 and setuptools 40.8.0. diff --git a/Misc/NEWS.d/next/Library/2019-03-08-13-32-21.bpo-36235._M72wU.rst b/Misc/NEWS.d/next/Library/2019-03-08-13-32-21.bpo-36235._M72wU.rst deleted file mode 100644 index 59df98c101a..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-08-13-32-21.bpo-36235._M72wU.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix ``CFLAGS`` in ``customize_compiler()`` of ``distutils.sysconfig``: when -the ``CFLAGS`` environment variable is defined, don't override ``CFLAGS`` -variable with the ``OPT`` variable anymore. Initial patch written by David -Malcolm. diff --git a/Misc/NEWS.d/next/Library/2019-03-09-18-01-24.bpo-36251.zOp9l0.rst b/Misc/NEWS.d/next/Library/2019-03-09-18-01-24.bpo-36251.zOp9l0.rst deleted file mode 100644 index 5138b0a0cb8..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-09-18-01-24.bpo-36251.zOp9l0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix format strings used for stderrprinter and re.Match reprs. Patch by -Stephan Hohe. diff --git a/Misc/NEWS.d/next/Library/2019-03-11-22-06-36.bpo-35931.Qp_Tbe.rst b/Misc/NEWS.d/next/Library/2019-03-11-22-06-36.bpo-35931.Qp_Tbe.rst deleted file mode 100644 index 68c57e2e69d..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-11-22-06-36.bpo-35931.Qp_Tbe.rst +++ /dev/null @@ -1 +0,0 @@ -The :mod:`pdb` ``debug`` command now gracefully handles all exceptions. diff --git a/Misc/NEWS.d/next/Library/2019-03-12-21-02-55.bpo-36280.mOd3iH.rst b/Misc/NEWS.d/next/Library/2019-03-12-21-02-55.bpo-36280.mOd3iH.rst deleted file mode 100644 index e97285431e5..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-12-21-02-55.bpo-36280.mOd3iH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a kind field to ast.Constant. It is 'u' if the literal has a 'u' prefix -(i.e. a Python 2 style unicode literal), else None. diff --git a/Misc/NEWS.d/next/Library/2019-03-13-14-14-36.bpo-36272.f3l2IG.rst b/Misc/NEWS.d/next/Library/2019-03-13-14-14-36.bpo-36272.f3l2IG.rst deleted file mode 100644 index 2f2f7905c01..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-13-14-14-36.bpo-36272.f3l2IG.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`logging` does not silently ignore RecursionError anymore. Patch -contributed by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-03-13-14-55-02.bpo-31904.834kfY.rst b/Misc/NEWS.d/next/Library/2019-03-13-14-55-02.bpo-31904.834kfY.rst deleted file mode 100644 index d859446b90a..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-13-14-55-02.bpo-31904.834kfY.rst +++ /dev/null @@ -1 +0,0 @@ -Add _signal module support for VxWorks. diff --git a/Misc/NEWS.d/next/Library/2019-03-14-01-09-59.bpo-36285.G-usj8.rst b/Misc/NEWS.d/next/Library/2019-03-14-01-09-59.bpo-36285.G-usj8.rst deleted file mode 100644 index bf16170c5f6..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-14-01-09-59.bpo-36285.G-usj8.rst +++ /dev/null @@ -1 +0,0 @@ -Fix integer overflows in the array module. Patch by Stephan Hohe. diff --git a/Misc/NEWS.d/next/Library/2019-03-14-16-25-17.bpo-36268.MDXLw6.rst b/Misc/NEWS.d/next/Library/2019-03-14-16-25-17.bpo-36268.MDXLw6.rst deleted file mode 100644 index 55f4e0f0d05..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-14-16-25-17.bpo-36268.MDXLw6.rst +++ /dev/null @@ -1,3 +0,0 @@ -Switch the default format used for writing tars with mod:`tarfile` to -the modern POSIX.1-2001 pax standard, from the vendor-specific GNU. -Contributed by C.A.M. Gerlach. diff --git a/Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst b/Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst deleted file mode 100644 index 14be079ddb9..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise ModuleNotFoundError in pyclbr when a module can't be found. -Thanks to 'mental' for the bug report. diff --git a/Misc/NEWS.d/next/Library/2019-03-15-21-41-22.bpo-36297.Gz9ZfU.rst b/Misc/NEWS.d/next/Library/2019-03-15-21-41-22.bpo-36297.Gz9ZfU.rst deleted file mode 100644 index f633feea5ca..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-15-21-41-22.bpo-36297.Gz9ZfU.rst +++ /dev/null @@ -1,2 +0,0 @@ -"unicode_internal" codec is removed. It was deprecated since Python 3.3. -Patch by Inada Naoki. diff --git a/Misc/NEWS.d/next/Library/2019-03-16-13-40-59.bpo-36321.s6crQx.rst b/Misc/NEWS.d/next/Library/2019-03-16-13-40-59.bpo-36321.s6crQx.rst deleted file mode 100644 index eea6f541848..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-16-13-40-59.bpo-36321.s6crQx.rst +++ /dev/null @@ -1,5 +0,0 @@ -collections.namedtuple() misspelled the name of an attribute. To be -consistent with typing.NamedTuple, the attribute name should have been -"_field_defaults" instead of "_fields_defaults". For backwards -compatibility, both spellings are now created. The misspelled version may -be removed in the future. diff --git a/Misc/NEWS.d/next/Library/2019-03-17-01-17-45.bpo-36324.dvNrRe.rst b/Misc/NEWS.d/next/Library/2019-03-17-01-17-45.bpo-36324.dvNrRe.rst deleted file mode 100644 index 536b2b8739d..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-17-01-17-45.bpo-36324.dvNrRe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add method to statistics.NormalDist for computing the inverse cumulative -normal distribution. diff --git a/Misc/NEWS.d/next/Library/2019-03-17-16-43-29.bpo-34745.nOfm7_.rst b/Misc/NEWS.d/next/Library/2019-03-17-16-43-29.bpo-34745.nOfm7_.rst deleted file mode 100644 index d88f36a6d21..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-17-16-43-29.bpo-34745.nOfm7_.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`asyncio` ssl memory issues caused by circular references diff --git a/Misc/NEWS.d/next/Library/2019-03-18-01-08-14.bpo-36320.-06b9_.rst b/Misc/NEWS.d/next/Library/2019-03-18-01-08-14.bpo-36320.-06b9_.rst deleted file mode 100644 index 9e9495f46b7..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-18-01-08-14.bpo-36320.-06b9_.rst +++ /dev/null @@ -1,3 +0,0 @@ -The typing.NamedTuple() class has deprecated the _field_types attribute in -favor of the __annotations__ attribute which carried the same information. -Also, both attributes were converted from OrderedDict to a regular dict. diff --git a/Misc/NEWS.d/next/Library/2019-03-23-10-25-07.bpo-36401.hYpVBS.rst b/Misc/NEWS.d/next/Library/2019-03-23-10-25-07.bpo-36401.hYpVBS.rst deleted file mode 100644 index cf097d7ed4a..00000000000 --- a/Misc/NEWS.d/next/Library/2019-03-23-10-25-07.bpo-36401.hYpVBS.rst +++ /dev/null @@ -1,2 +0,0 @@ -The class documentation created by pydoc now has a separate section for -readonly properties. diff --git a/Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst b/Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst new file mode 100644 index 00000000000..15c4222d483 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst @@ -0,0 +1,6 @@ +Reinitialize logging.Handler locks in forked child processes instead of +attempting to acquire them all in the parent before forking only to be +released in the child process. The acquire/release pattern was leading to +deadlocks in code that has implemented any form of chained logging handlers +that depend upon one another as the lock acquision order cannot be +guaranteed. diff --git a/Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst b/Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst new file mode 100644 index 00000000000..8374776e61e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst @@ -0,0 +1,2 @@ +The signature of Python functions can now be overridden by specifying the +``__text_signature__`` attribute. diff --git a/Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst b/Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst new file mode 100644 index 00000000000..43e51fe5ca9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst @@ -0,0 +1 @@ +Properly handle SSL connection closing in asyncio StreamWriter.drain() call. diff --git a/Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst b/Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst new file mode 100644 index 00000000000..7e3ff6cf0e1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst @@ -0,0 +1,2 @@ +Forbid creation of asyncio stream objects like StreamReader, StreamWriter, +Process, and their protocols outside of asyncio package. diff --git a/Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst b/Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst new file mode 100644 index 00000000000..23577d9b5a8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst @@ -0,0 +1 @@ +Introducing ``zipfile.Path``, a pathlib-compatible wrapper for traversing zip files. diff --git a/Misc/NEWS.d/next/Security/2018-10-31-15-39-17.bpo-35121.EgHv9k.rst b/Misc/NEWS.d/next/Security/2018-10-31-15-39-17.bpo-35121.EgHv9k.rst deleted file mode 100644 index d2eb8f1f352..00000000000 --- a/Misc/NEWS.d/next/Security/2018-10-31-15-39-17.bpo-35121.EgHv9k.rst +++ /dev/null @@ -1,4 +0,0 @@ -Don't send cookies of domain A without Domain attribute to domain B -when domain A is a suffix match of domain B while using a cookiejar -with :class:`http.cookiejar.DefaultCookiePolicy` policy. Patch by -Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst b/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst deleted file mode 100644 index 5546394157f..00000000000 --- a/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst +++ /dev/null @@ -1,3 +0,0 @@ -Changes urlsplit() to raise ValueError when the URL contains characters that -decompose under IDNA encoding (NFKC-normalization) into characters that -affect how the URL is parsed. diff --git a/Misc/NEWS.d/next/Tests/2019-02-26-12-51-35.bpo-36123.QRhhRS.rst b/Misc/NEWS.d/next/Tests/2019-02-26-12-51-35.bpo-36123.QRhhRS.rst deleted file mode 100644 index 5a7e5bb8f43..00000000000 --- a/Misc/NEWS.d/next/Tests/2019-02-26-12-51-35.bpo-36123.QRhhRS.rst +++ /dev/null @@ -1 +0,0 @@ -Fix race condition in test_socket. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2019-02-28-18-33-29.bpo-29571.r6b9fr.rst b/Misc/NEWS.d/next/Tests/2019-02-28-18-33-29.bpo-29571.r6b9fr.rst deleted file mode 100644 index 0f40c98514c..00000000000 --- a/Misc/NEWS.d/next/Tests/2019-02-28-18-33-29.bpo-29571.r6b9fr.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``test_re.test_locale_flag()``: use ``locale.getpreferredencoding()`` -rather than ``locale.getlocale()`` to get the locale encoding. With some -locales, ``locale.getlocale()`` returns the wrong encoding. diff --git a/Misc/NEWS.d/next/Tests/2019-03-08-12-53-37.bpo-36234.NRVK6W.rst b/Misc/NEWS.d/next/Tests/2019-03-08-12-53-37.bpo-36234.NRVK6W.rst deleted file mode 100644 index 33178b6c389..00000000000 --- a/Misc/NEWS.d/next/Tests/2019-03-08-12-53-37.bpo-36234.NRVK6W.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_posix.PosixUidGidTests: add tests for invalid uid/gid type (str). -Initial patch written by David Malcolm. diff --git a/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst b/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst new file mode 100644 index 00000000000..ad8cc8fc61a --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst @@ -0,0 +1 @@ +Skip httplib and nntplib networking tests when they would otherwise fail due to a modern OS or distro with a default OpenSSL policy of rejecting connections to servers with weak certificates. diff --git a/Misc/NEWS.d/next/Tools-Demos/2017-12-19-20-42-36.bpo-32217.axXcjA.rst b/Misc/NEWS.d/next/Tools-Demos/2017-12-19-20-42-36.bpo-32217.axXcjA.rst deleted file mode 100644 index 67feb9e9c3c..00000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2017-12-19-20-42-36.bpo-32217.axXcjA.rst +++ /dev/null @@ -1 +0,0 @@ -Fix freeze script on Windows. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-03-04-02-09-09.bpo-35132.1R_pnL.rst b/Misc/NEWS.d/next/Tools-Demos/2019-03-04-02-09-09.bpo-35132.1R_pnL.rst deleted file mode 100644 index d73452df429..00000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-03-04-02-09-09.bpo-35132.1R_pnL.rst +++ /dev/null @@ -1 +0,0 @@ -Fix py-list and py-bt commands of python-gdb.py on gdb7. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2019-02-24-07-52-39.bpo-24643.PofyiS.rst b/Misc/NEWS.d/next/Windows/2019-02-24-07-52-39.bpo-24643.PofyiS.rst deleted file mode 100644 index 7bc62d8b8fe..00000000000 --- a/Misc/NEWS.d/next/Windows/2019-02-24-07-52-39.bpo-24643.PofyiS.rst +++ /dev/null @@ -1 +0,0 @@ -Fix name collisions due to ``#define timezone _timezone`` in PC/pyconfig.h. diff --git a/Misc/NEWS.d/next/Windows/2019-03-11-09-33-47.bpo-36264.rTzWce.rst b/Misc/NEWS.d/next/Windows/2019-03-11-09-33-47.bpo-36264.rTzWce.rst deleted file mode 100644 index aae59865811..00000000000 --- a/Misc/NEWS.d/next/Windows/2019-03-11-09-33-47.bpo-36264.rTzWce.rst +++ /dev/null @@ -1,2 +0,0 @@ -Don't honor POSIX ``HOME`` in ``os.path.expanduser`` on windows. Patch by -Anthony Sottile. diff --git a/Misc/NEWS.d/next/Windows/2019-03-16-16-51-17.bpo-36312.Niwm-T.rst b/Misc/NEWS.d/next/Windows/2019-03-16-16-51-17.bpo-36312.Niwm-T.rst deleted file mode 100644 index 8b325db3a98..00000000000 --- a/Misc/NEWS.d/next/Windows/2019-03-16-16-51-17.bpo-36312.Niwm-T.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed decoders for the following code pages: 50220, 50221, 50222, 50225, -50227, 50229, 57002 through 57011, 65000 and 42. diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index c188dd70759..d1a032165f8 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -1,5 +1,5 @@ This file describes some special Python build types enabled via compile-time -preprocessor defines. +preprocessor directives. IMPORTANT: if you want to build a debug-enabled Python, it is recommended that you use ``./configure --with-pydebug``, rather than the options listed here. @@ -30,6 +30,8 @@ name "_" holds a reference to the last result displayed! Py_REF_DEBUG also checks after every decref to verify that the refcount hasn't gone negative, and causes an immediate fatal error if it has. +Py_DEBUG implies Py_REF_DEBUG. + Special gimmicks: sys.gettotalrefcount() @@ -39,6 +41,8 @@ sys.gettotalrefcount() Py_TRACE_REFS ------------- +Build option: ``./configure --with-trace-refs``. + Turn on heavy reference debugging. This is major surgery. Every PyObject grows two more pointers, to maintain a doubly-linked list of all live heap-allocated objects. Most built-in type objects are not in this list, as they're statically @@ -49,8 +53,6 @@ has been created. Note that because the fundamental PyObject layout changes, Python modules compiled with Py_TRACE_REFS are incompatible with modules compiled without it. -Py_TRACE_REFS implies Py_REF_DEBUG. - Special gimmicks: sys.getobjects(max[, type]) @@ -138,7 +140,8 @@ look at the object, you're likely to see that it's entirely filled with 0xDB (meaning freed memory is getting used) or 0xCB (meaning uninitialized memory is getting used). -Note that PYMALLOC_DEBUG requires WITH_PYMALLOC. +Note that PYMALLOC_DEBUG requires WITH_PYMALLOC. Py_DEBUG implies +PYMALLOC_DEBUG (if WITH_PYMALLOC is enabled). Special gimmicks: @@ -156,7 +159,7 @@ Py_DEBUG This is what is generally meant by "a debug build" of Python. -Py_DEBUG implies LLTRACE, Py_REF_DEBUG, Py_TRACE_REFS, and PYMALLOC_DEBUG (if +Py_DEBUG implies LLTRACE, Py_REF_DEBUG, and PYMALLOC_DEBUG (if WITH_PYMALLOC is enabled). In addition, C assert()s are enabled (via the C way: by not defining NDEBUG), and some routines do additional sanity checks inside "#ifdef Py_DEBUG" blocks. @@ -223,3 +226,5 @@ the interpreter is doing are sprayed to stdout, such as every opcode and opcode argument and values pushed onto and popped off the value stack. Not useful very often, but very useful when needed. + +Py_DEBUG implies LLTRACE. diff --git a/Misc/python-config.in b/Misc/python-config.in index e13da7543c9..1df30d261d8 100644 --- a/Misc/python-config.in +++ b/Misc/python-config.in @@ -47,16 +47,15 @@ for opt in opt_flags: print(' '.join(flags)) elif opt in ('--libs', '--ldflags'): - libs = ['-lpython' + pyver + sys.abiflags] - libs += getvar('LIBS').split() - libs += getvar('SYSLIBS').split() + libpython = getvar('LIBPYTHON') + libs = [libpython] if libpython else [] + libs.extend(getvar('LIBS').split() + getvar('SYSLIBS').split()) + # add the prefix/lib/pythonX.Y/config dir, but only if there is no # shared library in prefix/lib/. if opt == '--ldflags': if not getvar('Py_ENABLE_SHARED'): libs.insert(0, '-L' + getvar('LIBPL')) - if not getvar('PYTHONFRAMEWORK'): - libs.extend(getvar('LINKFORSHARED').split()) print(' '.join(libs)) elif opt == '--extension-suffix': diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in index d1d3275fa27..33991ef0c5d 100644 --- a/Misc/python-config.sh.in +++ b/Misc/python-config.sh.in @@ -41,10 +41,9 @@ LIBM="@LIBM@" LIBC="@LIBC@" SYSLIBS="$LIBM $LIBC" ABIFLAGS="@ABIFLAGS@" -LIBS="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" +LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS" BASECFLAGS="@BASECFLAGS@" LDLIBRARY="@LDLIBRARY@" -LINKFORSHARED="@LINKFORSHARED@" OPT="@OPT@" PY_ENABLE_SHARED="@PY_ENABLE_SHARED@" LDVERSION="@LDVERSION@" @@ -89,15 +88,11 @@ do echo "$LIBS" ;; --ldflags) - LINKFORSHAREDUSED= - if [ -z "$PYTHONFRAMEWORK" ] ; then - LINKFORSHAREDUSED=$LINKFORSHARED - fi LIBPLUSED= if [ "$PY_ENABLE_SHARED" = "0" ] ; then LIBPLUSED="-L$LIBPL" fi - echo "$LIBPLUSED -L$libdir $LIBS $LINKFORSHAREDUSED" + echo "$LIBPLUSED -L$libdir $LIBS" ;; --extension-suffix) echo "$SO" diff --git a/Modules/Setup b/Modules/Setup index 11ddd0c7b20..e729ab883f4 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -101,29 +101,29 @@ PYTHONPATH=$(COREPYTHONPATH) # This only contains the minimal set of modules required to run the # setup.py script in the root of the Python source tree. -posix -DPy_BUILD_CORE -I$(srcdir)/Include/internal posixmodule.c # posix (UNIX) system calls +posix -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal posixmodule.c # posix (UNIX) system calls errno errnomodule.c # posix (UNIX) errno values pwd pwdmodule.c # this is needed to find out the user's home dir # if $HOME is not set _sre _sre.c # Fredrik Lundh's new regular expressions _codecs _codecsmodule.c # access to the builtin codecs and codec registry _weakref _weakref.c # weak references -_functools -DPy_BUILD_CORE -I$(srcdir)/Include/internal _functoolsmodule.c # Tools for working with functions and callable objects +_functools -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _functoolsmodule.c # Tools for working with functions and callable objects _operator _operator.c # operator.add() and similar goodies _collections _collectionsmodule.c # Container types _abc _abc.c # Abstract base classes itertools itertoolsmodule.c # Functions creating iterators for efficient looping atexit atexitmodule.c # Register functions to be run at interpreter-shutdown -_signal -DPy_BUILD_CORE -I$(srcdir)/Include/internal signalmodule.c +_signal -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal signalmodule.c _stat _stat.c # stat.h interface -time -DPy_BUILD_CORE -I$(srcdir)/Include/internal timemodule.c # -lm # time operations and variables -_thread -DPy_BUILD_CORE -I$(srcdir)/Include/internal _threadmodule.c # low-level threading interface +time -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal timemodule.c # -lm # time operations and variables +_thread -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _threadmodule.c # low-level threading interface # access to ISO C locale support -_locale -DPy_BUILD_CORE _localemodule.c # -lintl +_locale -DPy_BUILD_CORE_BUILTIN _localemodule.c # -lintl # Standard I/O baseline -_io -DPy_BUILD_CORE -I$(srcdir)/Include/internal -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c +_io -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c # faulthandler module faulthandler faulthandler.c @@ -173,6 +173,7 @@ _symtable symtablemodule.c #_struct _struct.c # binary structure packing/unpacking #_weakref _weakref.c # basic weak reference support #_testcapi _testcapimodule.c # Python C API test module +#_testinternalcapi _testinternalcapi.c -I$(srcdir)/Include/internal -DPy_BUILD_CORE_MODULE # Python internal C API test module #_random _randommodule.c # Random number generator #_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator #_pickle _pickle.c # pickle accelerator diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 45102f3304e..13cf76a16d7 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -403,24 +403,35 @@ static PyCArgObject * StructUnionType_paramfunc(CDataObject *self) { PyCArgObject *parg; + CDataObject *copied_self; StgDictObject *stgdict; + if ((size_t)self->b_size > sizeof(void*)) { + void *new_ptr = PyMem_Malloc(self->b_size); + if (new_ptr == NULL) + return NULL; + memcpy(new_ptr, self->b_ptr, self->b_size); + copied_self = (CDataObject *)PyCData_AtAddress( + (PyObject *)Py_TYPE(self), new_ptr); + copied_self->b_needsfree = 1; + } else { + copied_self = self; + Py_INCREF(copied_self); + } + parg = PyCArgObject_new(); - if (parg == NULL) + if (parg == NULL) { + Py_DECREF(copied_self); return NULL; + } parg->tag = 'V'; - stgdict = PyObject_stgdict((PyObject *)self); + stgdict = PyObject_stgdict((PyObject *)copied_self); assert(stgdict); /* Cannot be NULL for structure/union instances */ parg->pffi_type = &stgdict->ffi_type_pointer; - /* For structure parameters (by value), parg->value doesn't contain the structure - data itself, instead parg->value.p *points* to the structure's data - See also _ctypes.c, function _call_function_pointer(). - */ - parg->value.p = self->b_ptr; - parg->size = self->b_size; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->value.p = copied_self->b_ptr; + parg->size = copied_self->b_size; + parg->obj = (PyObject *)copied_self; return parg; } @@ -1293,8 +1304,6 @@ static int WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) { Py_ssize_t result = 0; - Py_UNICODE *wstr; - Py_ssize_t len; if (value == NULL) { PyErr_SetString(PyExc_TypeError, @@ -1309,12 +1318,14 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored } else Py_INCREF(value); - wstr = PyUnicode_AsUnicodeAndSize(value, &len); - if (wstr == NULL) + Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0); + if (len < 0) { return -1; - if ((size_t)len > self->b_size/sizeof(wchar_t)) { - PyErr_SetString(PyExc_ValueError, - "string too long"); + } + // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, + // when it is called with NULL. + if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) { + PyErr_SetString(PyExc_ValueError, "string too long"); result = -1; goto done; } @@ -1507,7 +1518,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } itemsize = itemdict->size; - if (length * itemsize < 0) { + if (length > PY_SSIZE_T_MAX / itemsize) { PyErr_SetString(PyExc_OverflowError, "array too large"); goto error; @@ -2732,10 +2743,11 @@ PyCData_reduce(PyObject *myself, PyObject *args) "ctypes objects containing pointers cannot be pickled"); return NULL; } - return Py_BuildValue("O(O(NN))", - _unpickle, - Py_TYPE(myself), - PyObject_GetAttrString(myself, "__dict__"), + PyObject *dict = PyObject_GetAttrString(myself, "__dict__"); + if (dict == NULL) { + return NULL; + } + return Py_BuildValue("O(O(NN))", _unpickle, Py_TYPE(myself), dict, PyBytes_FromStringAndSize(self->b_ptr, self->b_size)); } diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index f8420580ffa..bae4976a08d 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -87,7 +87,7 @@ EXPORT(void)testfunc_array(int values[4]) EXPORT(long double)testfunc_Ddd(double a, double b) { long double result = (long double)(a * b); - printf("testfunc_Ddd(%p, %p)\n", &a, &b); + printf("testfunc_Ddd(%p, %p)\n", (void *)&a, (void *)&b); printf("testfunc_Ddd(%g, %g)\n", a, b); return result; } @@ -95,7 +95,7 @@ EXPORT(long double)testfunc_Ddd(double a, double b) EXPORT(long double)testfunc_DDD(long double a, long double b) { long double result = a * b; - printf("testfunc_DDD(%p, %p)\n", &a, &b); + printf("testfunc_DDD(%p, %p)\n", (void *)&a, (void *)&b); printf("testfunc_DDD(%Lg, %Lg)\n", a, b); return result; } @@ -103,7 +103,7 @@ EXPORT(long double)testfunc_DDD(long double a, long double b) EXPORT(int)testfunc_iii(int a, int b) { int result = a * b; - printf("testfunc_iii(%p, %p)\n", &a, &b); + printf("testfunc_iii(%p, %p)\n", (void *)&a, (void *)&b); return result; } @@ -361,7 +361,7 @@ static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *)) { void *ptr; - printf("_xxx_init got %p %p\n", Xalloc, Xfree); + printf("_xxx_init got %p %p\n", (void *)Xalloc, (void *)Xfree); printf("calling\n"); ptr = Xalloc(32); Xfree(ptr); diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 2b7cb06ea8a..9f793c2771b 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -380,7 +380,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, } cc = FFI_DEFAULT_ABI; -#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) +#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) && !defined(_M_ARM) if ((flags & FUNCFLAG_CDECL) == 0) cc = FFI_STDCALL; #endif diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index d91e84613b2..a8ba84be4a7 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -531,11 +531,11 @@ PyCArg_repr(PyCArgObject *self) default: if (is_literal_char((unsigned char)self->tag)) { sprintf(buffer, "", - (unsigned char)self->tag, self); + (unsigned char)self->tag, (void *)self); } else { sprintf(buffer, "", - (unsigned char)self->tag, self); + (unsigned char)self->tag, (void *)self); } break; } @@ -729,6 +729,28 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) } } +#if defined(MS_WIN32) && !defined(_WIN32_WCE) +/* +Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx +To be returned by value in RAX, user-defined types must have a length +of 1, 2, 4, 8, 16, 32, or 64 bits +*/ +int can_return_struct_as_int(size_t s) +{ + return s == 1 || s == 2 || s == 4; +} + +int can_return_struct_as_sint64(size_t s) +{ +#ifdef _M_ARM + // 8 byte structs cannot be returned in a register on ARM32 + return 0; +#else + return s == 8; +#endif +} +#endif + ffi_type *_ctypes_get_ffi_type(PyObject *obj) { @@ -778,12 +800,9 @@ static int _call_function_pointer(int flags, int *space; ffi_cif cif; int cc; -#ifdef MS_WIN32 - int delta; -#ifndef DONT_USE_SEH +#if defined(MS_WIN32) && !defined(DONT_USE_SEH) DWORD dwExceptionCode = 0; EXCEPTION_RECORD record; -#endif #endif /* XXX check before here */ if (restype == NULL) { @@ -793,7 +812,7 @@ static int _call_function_pointer(int flags, } cc = FFI_DEFAULT_ABI; -#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) +#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) && !defined(_M_ARM) if ((flags & FUNCFLAG_CDECL) == 0) cc = FFI_STDCALL; #endif @@ -828,7 +847,6 @@ static int _call_function_pointer(int flags, #ifndef DONT_USE_SEH __try { #endif - delta = #endif ffi_call(&cif, (void *)pProc, resmem, avalues); #ifdef MS_WIN32 @@ -860,35 +878,6 @@ static int _call_function_pointer(int flags, return -1; } #endif -#ifdef MS_WIN64 - if (delta != 0) { - PyErr_Format(PyExc_RuntimeError, - "ffi_call failed with code %d", - delta); - return -1; - } -#else - if (delta < 0) { - if (flags & FUNCFLAG_CDECL) - PyErr_Format(PyExc_ValueError, - "Procedure called with not enough " - "arguments (%d bytes missing) " - "or wrong calling convention", - -delta); - else - PyErr_Format(PyExc_ValueError, - "Procedure probably called with not enough " - "arguments (%d bytes missing)", - -delta); - return -1; - } else if (delta > 0) { - PyErr_Format(PyExc_ValueError, - "Procedure probably called with too many " - "arguments (%d bytes in excess)", - delta); - return -1; - } -#endif #endif if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred()) return -1; @@ -1267,19 +1256,21 @@ static PyObject *format_error(PyObject *self, PyObject *args) } static const char load_library_doc[] = -"LoadLibrary(name) -> handle\n\ +"LoadLibrary(name, load_flags) -> handle\n\ \n\ Load an executable (usually a DLL), and return a handle to it.\n\ The handle may be used to locate exported functions in this\n\ -module.\n"; +module. load_flags are as defined for LoadLibraryEx in the\n\ +Windows API.\n"; static PyObject *load_library(PyObject *self, PyObject *args) { const WCHAR *name; PyObject *nameobj; - PyObject *ignored; + int load_flags = 0; HMODULE hMod; + DWORD err; - if (!PyArg_ParseTuple(args, "U|O:LoadLibrary", &nameobj, &ignored)) + if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags)) return NULL; name = _PyUnicode_AsUnicode(nameobj); @@ -1287,11 +1278,22 @@ static PyObject *load_library(PyObject *self, PyObject *args) return NULL; Py_BEGIN_ALLOW_THREADS - hMod = LoadLibraryW(name); + /* bpo-36085: Limit DLL search directories to avoid pre-loading + * attacks and enable use of the AddDllDirectory function. + */ + hMod = LoadLibraryExW(name, NULL, (DWORD)load_flags); + err = hMod ? 0 : GetLastError(); Py_END_ALLOW_THREADS - if (!hMod) - return PyErr_SetFromWindowsErr(GetLastError()); + if (err == ERROR_MOD_NOT_FOUND) { + PyErr_Format(PyExc_FileNotFoundError, + ("Could not find module '%.500S'. Try using " + "the full path with constructor syntax."), + nameobj); + return NULL; + } else if (err) { + return PyErr_SetFromWindowsErr(err); + } #ifdef _WIN64 return PyLong_FromVoidPtr(hMod); #else @@ -1307,15 +1309,18 @@ static PyObject *free_library(PyObject *self, PyObject *args) { void *hMod; BOOL result; + DWORD err; if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod)) return NULL; Py_BEGIN_ALLOW_THREADS result = FreeLibrary((HMODULE)hMod); + err = result ? 0 : GetLastError(); Py_END_ALLOW_THREADS - if (!result) - return PyErr_SetFromWindowsErr(GetLastError()); + if (!result) { + return PyErr_SetFromWindowsErr(err); + } Py_RETURN_NONE; } diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 5f194e21550..157c32fd909 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1229,9 +1229,6 @@ U_get(void *ptr, Py_ssize_t size) static PyObject * U_set(void *ptr, PyObject *value, Py_ssize_t length) { - Py_UNICODE *wstr; - Py_ssize_t size; - /* It's easier to calculate in characters than in bytes */ length /= sizeof(wchar_t); @@ -1242,9 +1239,14 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) return NULL; } - wstr = PyUnicode_AsUnicodeAndSize(value, &size); - if (wstr == NULL) + Py_ssize_t size = PyUnicode_AsWideChar(value, NULL, 0); + if (size < 0) { return NULL; + } + // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, + // when it is called with NULL. + size--; + assert(size >= 0); if (size > length) { PyErr_Format(PyExc_ValueError, "string too long (%zd, maximum length %zd)", @@ -1421,16 +1423,18 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) /* create a BSTR from value */ if (value) { - wchar_t* wvalue; Py_ssize_t wsize; - wvalue = PyUnicode_AsUnicodeAndSize(value, &wsize); - if (wvalue == NULL) + wchar_t *wvalue = PyUnicode_AsWideCharString(value, &wsize); + if (wvalue == NULL) { return NULL; + } if ((unsigned) wsize != wsize) { PyErr_SetString(PyExc_ValueError, "String too long for BSTR"); + PyMem_Free(wvalue); return NULL; } bstr = SysAllocStringLen(wvalue, (unsigned)wsize); + PyMem_Free(wvalue); } else bstr = NULL; diff --git a/Modules/_ctypes/libffi_msvc/LICENSE b/Modules/_ctypes/libffi_msvc/LICENSE deleted file mode 100644 index f591795152d..00000000000 --- a/Modules/_ctypes/libffi_msvc/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -libffi - Copyright (c) 1996-2003 Red Hat, Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -``Software''), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Modules/_ctypes/libffi_msvc/README b/Modules/_ctypes/libffi_msvc/README deleted file mode 100644 index 69e46cbf8a4..00000000000 --- a/Modules/_ctypes/libffi_msvc/README +++ /dev/null @@ -1,500 +0,0 @@ -This directory contains the libffi package, which is not part of GCC but -shipped with GCC as convenience. - -Status -====== - -libffi-2.00 has not been released yet! This is a development snapshot! - -libffi-1.20 was released on October 5, 1998. Check the libffi web -page for updates: . - - -What is libffi? -=============== - -Compilers for high level languages generate code that follow certain -conventions. These conventions are necessary, in part, for separate -compilation to work. One such convention is the "calling -convention". The "calling convention" is essentially a set of -assumptions made by the compiler about where function arguments will -be found on entry to a function. A "calling convention" also specifies -where the return value for a function is found. - -Some programs may not know at the time of compilation what arguments -are to be passed to a function. For instance, an interpreter may be -told at run-time about the number and types of arguments used to call -a given function. Libffi can be used in such programs to provide a -bridge from the interpreter program to compiled code. - -The libffi library provides a portable, high level programming -interface to various calling conventions. This allows a programmer to -call any function specified by a call interface description at run -time. - -Ffi stands for Foreign Function Interface. A foreign function -interface is the popular name for the interface that allows code -written in one language to call code written in another language. The -libffi library really only provides the lowest, machine dependent -layer of a fully featured foreign function interface. A layer must -exist above libffi that handles type conversions for values passed -between the two languages. - - -Supported Platforms and Prerequisites -===================================== - -Libffi has been ported to: - - SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9) - - Irix 5.3 & 6.2 (System V/o32 & n32) - - Intel x86 - Linux (System V ABI) - - Alpha - Linux and OSF/1 - - m68k - Linux (System V ABI) - - PowerPC - Linux (System V ABI, Darwin, AIX) - - ARM - Linux (System V ABI) - -Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are -that other versions will work. Libffi has also been built and tested -with the SGI compiler tools. - -On PowerPC, the tests failed (see the note below). - -You must use GNU make to build libffi. SGI's make will not work. -Sun's probably won't either. - -If you port libffi to another platform, please let me know! I assume -that some will be easy (x86 NetBSD), and others will be more difficult -(HP). - - -Installing libffi -================= - -[Note: before actually performing any of these installation steps, - you may wish to read the "Platform Specific Notes" below.] - -First you must configure the distribution for your particular -system. Go to the directory you wish to build libffi in and run the -"configure" program found in the root directory of the libffi source -distribution. - -You may want to tell configure where to install the libffi library and -header files. To do that, use the --prefix configure switch. Libffi -will install under /usr/local by default. - -If you want to enable extra run-time debugging checks use the the ---enable-debug configure switch. This is useful when your program dies -mysteriously while using libffi. - -Another useful configure switch is --enable-purify-safety. Using this -will add some extra code which will suppress certain warnings when you -are using Purify with libffi. Only use this switch when using -Purify, as it will slow down the library. - -Configure has many other options. Use "configure --help" to see them all. - -Once configure has finished, type "make". Note that you must be using -GNU make. SGI's make will not work. Sun's probably won't either. -You can ftp GNU make from prep.ai.mit.edu:/pub/gnu. - -To ensure that libffi is working as advertised, type "make test". - -To install the library and header files, type "make install". - - -Using libffi -============ - - The Basics - ---------- - -Libffi assumes that you have a pointer to the function you wish to -call and that you know the number and types of arguments to pass it, -as well as the return type of the function. - -The first thing you must do is create an ffi_cif object that matches -the signature of the function you wish to call. The cif in ffi_cif -stands for Call InterFace. To prepare a call interface object, use the -following function: - -ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, - unsigned int nargs, - ffi_type *rtype, ffi_type **atypes); - - CIF is a pointer to the call interface object you wish - to initialize. - - ABI is an enum that specifies the calling convention - to use for the call. FFI_DEFAULT_ABI defaults - to the system's native calling convention. Other - ABI's may be used with care. They are system - specific. - - NARGS is the number of arguments this function accepts. - libffi does not yet support vararg functions. - - RTYPE is a pointer to an ffi_type structure that represents - the return type of the function. Ffi_type objects - describe the types of values. libffi provides - ffi_type objects for many of the native C types: - signed int, unsigned int, signed char, unsigned char, - etc. There is also a pointer ffi_type object and - a void ffi_type. Use &ffi_type_void for functions that - don't return values. - - ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long. - If NARGS is 0, this is ignored. - - -ffi_prep_cif will return a status code that you are responsible -for checking. It will be one of the following: - - FFI_OK - All is good. - - FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif - came across is bad. - - -Before making the call, the VALUES vector should be initialized -with pointers to the appropriate argument values. - -To call the the function using the initialized ffi_cif, use the -ffi_call function: - -void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); - - CIF is a pointer to the ffi_cif initialized specifically - for this function. - - FN is a pointer to the function you want to call. - - RVALUE is a pointer to a chunk of memory that is to hold the - result of the function call. Currently, it must be - at least one word in size (except for the n32 version - under Irix 6.x, which must be a pointer to an 8 byte - aligned value (a long long). It must also be at least - word aligned (depending on the return type, and the - system's alignment requirements). If RTYPE is - &ffi_type_void, this is ignored. If RVALUE is NULL, - the return value is discarded. - - AVALUES is a vector of void* that point to the memory locations - holding the argument values for a call. - If NARGS is 0, this is ignored. - - -If you are expecting a return value from FN it will have been stored -at RVALUE. - - - - An Example - ---------- - -Here is a trivial example that calls puts() a few times. - - #include - #include - - int main() - { - ffi_cif cif; - ffi_type *args[1]; - void *values[1]; - char *s; - int rc; - - /* Initialize the argument info vectors */ - args[0] = &ffi_type_uint; - values[0] = &s; - - /* Initialize the cif */ - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) - { - s = "Hello World!"; - ffi_call(&cif, puts, &rc, values); - /* rc now holds the result of the call to puts */ - - /* values holds a pointer to the function's arg, so to - call puts() again all we need to do is change the - value of s */ - s = "This is cool!"; - ffi_call(&cif, puts, &rc, values); - } - - return 0; - } - - - - Aggregate Types - --------------- - -Although libffi has no special support for unions or bit-fields, it is -perfectly happy passing structures back and forth. You must first -describe the structure to libffi by creating a new ffi_type object -for it. Here is the definition of ffi_type: - - typedef struct _ffi_type - { - unsigned size; - short alignment; - short type; - struct _ffi_type **elements; - } ffi_type; - -All structures must have type set to FFI_TYPE_STRUCT. You may set -size and alignment to 0. These will be calculated and reset to the -appropriate values by ffi_prep_cif(). - -elements is a NULL terminated array of pointers to ffi_type objects -that describe the type of the structure elements. These may, in turn, -be structure elements. - -The following example initializes a ffi_type object representing the -tm struct from Linux's time.h: - - struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - /* Those are for future use. */ - long int __tm_gmtoff__; - __const char *__tm_zone__; - }; - - { - ffi_type tm_type; - ffi_type *tm_type_elements[12]; - int i; - - tm_type.size = tm_type.alignment = 0; - tm_type.elements = &tm_type_elements; - - for (i = 0; i < 9; i++) - tm_type_elements[i] = &ffi_type_sint; - - tm_type_elements[9] = &ffi_type_slong; - tm_type_elements[10] = &ffi_type_pointer; - tm_type_elements[11] = NULL; - - /* tm_type can now be used to represent tm argument types and - return types for ffi_prep_cif() */ - } - - - -Platform Specific Notes -======================= - - Intel x86 - --------- - -There are no known problems with the x86 port. - - Sun SPARC - SunOS 4.1.3 & Solaris 2.x - ------------------------------------- - -You must use GNU Make to build libffi on Sun platforms. - - MIPS - Irix 5.3 & 6.x - --------------------- - -Irix 6.2 and better supports three different calling conventions: o32, -n32 and n64. Currently, libffi only supports both o32 and n32 under -Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be -configured for whichever calling convention it was built for. - -By default, the configure script will try to build libffi with the GNU -development tools. To build libffi with the SGI development tools, set -the environment variable CC to either "cc -32" or "cc -n32" before -running configure under Irix 6.x (depending on whether you want an o32 -or n32 library), or just "cc" for Irix 5.3. - -With the n32 calling convention, when returning structures smaller -than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned. -Here's one way of forcing this: - - double struct_storage[2]; - my_small_struct *s = (my_small_struct *) struct_storage; - /* Use s for RVALUE */ - -If you don't do this you are liable to get spurious bus errors. - -"long long" values are not supported yet. - -You must use GNU Make to build libffi on SGI platforms. - - ARM - System V ABI - ------------------ - -The ARM port was performed on a NetWinder running ARM Linux ELF -(2.0.31) and gcc 2.8.1. - - - - PowerPC System V ABI - -------------------- - -There are two `System V ABI's which libffi implements for PowerPC. -They differ only in how small structures are returned from functions. - -In the FFI_SYSV version, structures that are 8 bytes or smaller are -returned in registers. This is what GCC does when it is configured -for solaris, and is what the System V ABI I have (dated September -1995) says. - -In the FFI_GCC_SYSV version, all structures are returned the same way: -by passing a pointer as the first argument to the function. This is -what GCC does when it is configured for linux or a generic sysv -target. - -EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a -inconsistency with the SysV ABI: When a procedure is called with many -floating-point arguments, some of them get put on the stack. They are -all supposed to be stored in double-precision format, even if they are -only single-precision, but EGCS stores single-precision arguments as -single-precision anyway. This causes one test to fail (the `many -arguments' test). - - -What's With The Cryptic Comments? -================================= - -You might notice a number of cryptic comments in the code, delimited -by /*@ and @*/. These are annotations read by the program LCLint, a -tool for statically checking C programs. You can read all about it at -. - - -History -======= - -1.20 Oct-5-98 - Raffaele Sena produces ARM port. - -1.19 Oct-5-98 - Fixed x86 long double and long long return support. - m68k bug fixes from Andreas Schwab. - Patch for DU assembler compatibility for the Alpha from Richard - Henderson. - -1.18 Apr-17-98 - Bug fixes and MIPS configuration changes. - -1.17 Feb-24-98 - Bug fixes and m68k port from Andreas Schwab. PowerPC port from - Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. - -1.16 Feb-11-98 - Richard Henderson produces Alpha port. - -1.15 Dec-4-97 - Fixed an n32 ABI bug. New libtool, auto* support. - -1.14 May-13-97 - libtool is now used to generate shared and static libraries. - Fixed a minor portability problem reported by Russ McManus - . - -1.13 Dec-2-96 - Added --enable-purify-safety to keep Purify from complaining - about certain low level code. - Sparc fix for calling functions with < 6 args. - Linux x86 a.out fix. - -1.12 Nov-22-96 - Added missing ffi_type_void, needed for supporting void return - types. Fixed test case for non MIPS machines. Cygnus Support - is now Cygnus Solutions. - -1.11 Oct-30-96 - Added notes about GNU make. - -1.10 Oct-29-96 - Added configuration fix for non GNU compilers. - -1.09 Oct-29-96 - Added --enable-debug configure switch. Clean-ups based on LCLint - feedback. ffi_mips.h is always installed. Many configuration - fixes. Fixed ffitest.c for sparc builds. - -1.08 Oct-15-96 - Fixed n32 problem. Many clean-ups. - -1.07 Oct-14-96 - Gordon Irlam rewrites v8.S again. Bug fixes. - -1.06 Oct-14-96 - Gordon Irlam improved the sparc port. - -1.05 Oct-14-96 - Interface changes based on feedback. - -1.04 Oct-11-96 - Sparc port complete (modulo struct passing bug). - -1.03 Oct-10-96 - Passing struct args, and returning struct values works for - all architectures/calling conventions. Expanded tests. - -1.02 Oct-9-96 - Added SGI n32 support. Fixed bugs in both o32 and Linux support. - Added "make test". - -1.01 Oct-8-96 - Fixed float passing bug in mips version. Restructured some - of the code. Builds cleanly with SGI tools. - -1.00 Oct-7-96 - First release. No public announcement. - - -Authors & Credits -================= - -libffi was written by Anthony Green . - -Portions of libffi were derived from Gianni Mariani's free gencall -library for Silicon Graphics machines. - -The closure mechanism was designed and implemented by Kresten Krab -Thorup. - -The Sparc port was derived from code contributed by the fine folks at -Visible Decisions Inc . Further enhancements were -made by Gordon Irlam at Cygnus Solutions . - -The Alpha port was written by Richard Henderson at Cygnus Solutions. - -Andreas Schwab ported libffi to m68k Linux and provided a number of -bug fixes. - -Geoffrey Keating ported libffi to the PowerPC. - -Raffaele Sena ported libffi to the ARM. - -Jesper Skov and Andrew Haley both did more than their fair share of -stepping through the code and tracking down bugs. - -Thanks also to Tom Tromey for bug fixes and configuration help. - -Thanks to Jim Blandy, who provided some useful feedback on the libffi -interface. - -If you have a problem, or have found a bug, please send a note to -green@cygnus.com. diff --git a/Modules/_ctypes/libffi_msvc/README.ctypes b/Modules/_ctypes/libffi_msvc/README.ctypes deleted file mode 100644 index 17e8a40b83f..00000000000 --- a/Modules/_ctypes/libffi_msvc/README.ctypes +++ /dev/null @@ -1,7 +0,0 @@ -The purpose is to hack the libffi sources so that they can be compiled -with MSVC, and to extend them so that they have the features I need -for ctypes. - -I retrieved the libffi sources from the gcc cvs repository on -2004-01-27. Then I did 'configure' in a 'build' subdirectory on a x86 -linux system, and copied the files I found useful. diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c deleted file mode 100644 index d202b158b07..00000000000 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ /dev/null @@ -1,530 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. - Copyright (c) 2002 Ranjit Mathew - Copyright (c) 2002 Bo Thorsen - Copyright (c) 2002 Roger Sayle - - x86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -extern void Py_FatalError(const char *msg); - -/*@-exportheader@*/ -void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) - { - *(void **) argp = ecif->rvalue; - argp += sizeof(void *); - } - - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i != 0; - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(void *) - 1) & (size_t) argp) - argp = (char *) ALIGN(argp, sizeof(void *)); - - z = (*p_arg)->size; - if (z < sizeof(intptr_t)) - { - z = sizeof(intptr_t); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(intptr_t *) argp = (intptr_t)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(uintptr_t *) argp = (uintptr_t)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(intptr_t *) argp = (intptr_t)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(uintptr_t *) argp = (uintptr_t)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(intptr_t *) argp = (intptr_t)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(uintptr_t *) argp = (uintptr_t)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_FLOAT: - *(uintptr_t *) argp = 0; - *(float *) argp = *(float *)(* p_argv); - break; - - // 64-bit value cases should never be used for x86 and AMD64 builds - case FFI_TYPE_SINT64: - *(intptr_t *) argp = (intptr_t)*(SINT64 *)(* p_argv); - break; - - case FFI_TYPE_UINT64: - *(uintptr_t *) argp = (uintptr_t)*(UINT64 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(uintptr_t *) argp = (uintptr_t)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_DOUBLE: - *(uintptr_t *) argp = 0; - *(double *) argp = *(double *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } -#ifdef _WIN64 - else if (z > 8) - { - /* On Win64, if a single argument takes more than 8 bytes, - then it is always passed by reference. */ - *(void **)argp = *p_argv; - z = 8; - } -#endif - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - - if (argp >= stack && (unsigned)(argp - stack) > ecif->cif->bytes) - { - Py_FatalError("FFI BUG: not enough stack space for arguments"); - } - return; -} - -/* -Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx -To be returned by value in RAX, user-defined types must have a length -of 1, 2, 4, 8, 16, 32, or 64 bits -*/ -int can_return_struct_as_int(size_t s) -{ - return s == 1 || s == 2 || s == 4; -} - -int can_return_struct_as_sint64(size_t s) -{ - return s == 8; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_STRUCT: - /* MSVC returns small structures in registers. Put in cif->flags - the value FFI_TYPE_STRUCT only if the structure is big enough; - otherwise, put the 4- or 8-bytes integer type. */ - if (can_return_struct_as_int(cif->rtype->size)) - cif->flags = FFI_TYPE_INT; - else if (can_return_struct_as_sint64(cif->rtype->size)) - cif->flags = FFI_TYPE_SINT64; - else - cif->flags = FFI_TYPE_STRUCT; - break; - - case FFI_TYPE_UINT64: -#ifdef _WIN64 - case FFI_TYPE_POINTER: -#endif - cif->flags = FFI_TYPE_SINT64; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -#ifdef _WIN32 -extern int -ffi_call_x86(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -#endif - -#ifdef _WIN64 -extern int -ffi_call_AMD64(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -#endif - -int -ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { -#if !defined(_WIN64) - case FFI_SYSV: - case FFI_STDCALL: - return ffi_call_x86(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#else - case FFI_SYSV: - /* If a single argument takes more than 8 bytes, - then a copy is passed by reference. */ - for (unsigned i = 0; i < cif->nargs; i++) { - size_t z = cif->arg_types[i]->size; - if (z > 8) { - void *temp = alloca(z); - memcpy(temp, avalue[i], z); - avalue[i] = temp; - } - } - /*@-usedef@*/ - return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; -#endif - - default: - FFI_ASSERT(0); - break; - } - return -1; /* theller: Hrm. */ -} - - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); -/* This function is jumped to by the trampoline */ - -#ifdef _WIN64 -void * -#else -static void __fastcall -#endif -ffi_closure_SYSV (ffi_closure *closure, char *argp) -{ - // this is our return value storage - long double res; - - // our various things... - ffi_cif *cif; - void **arg_area; - unsigned short rtype; - void *resp = (void*)&res; - void *args = argp + sizeof(void*); - - cif = closure->cif; - arg_area = (void**) alloca (cif->nargs * sizeof (void*)); - - /* this call will initialize ARG_AREA, such that each - * element in that array points to the corresponding - * value on the stack; and if the function returns - * a structure, it will re-set RESP to point to the - * structure return address. */ - - ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); - - rtype = cif->flags; - -#if defined(_WIN32) && !defined(_WIN64) -#ifdef _MSC_VER - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - _asm mov eax, resp ; - _asm mov eax, [eax] ; - } - else if (rtype == FFI_TYPE_FLOAT) - { - _asm mov eax, resp ; - _asm fld DWORD PTR [eax] ; -// asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - _asm mov eax, resp ; - _asm fld QWORD PTR [eax] ; -// asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { -// asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - _asm mov edx, resp ; - _asm mov eax, [edx] ; - _asm mov edx, [edx + 4] ; -// asm ("movl 0(%0),%%eax;" -// "movl 4(%0),%%edx" -// : : "r"(resp) -// : "eax", "edx"); - } -#else - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax;" - "movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -#endif -#endif - -#ifdef _WIN64 - /* The result is returned in rax. This does the right thing for - result types except for floats; we have to 'mov xmm0, rax' in the - caller to correct this. - */ - return *(void **)resp; -#endif -} - -/*@-exportheader@*/ -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, - void **avalue, ffi_cif *cif) -/*@=exportheader@*/ -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if ( cif->rtype->type == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += sizeof(void *); - } - - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(char *) - 1) & (size_t) argp) { - argp = (char *) ALIGN(argp, sizeof(char*)); - } - - z = (*p_arg)->size; - - /* because we're little endian, this is what it turns into. */ - -#ifdef _WIN64 - if (z > 8) { - /* On Win64, if a single argument takes more than 8 bytes, - * then it is always passed by reference. - */ - *p_argv = *((void**) argp); - z = 8; - } - else -#endif - *p_argv = (void*) argp; - - p_argv++; - argp += z; - } - - return; -} - -/* the cif must already be prep'ed */ -extern void ffi_closure_OUTER(); - -ffi_status -ffi_prep_closure_loc (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data, - void *codeloc) -{ - short bytes; - char *tramp; -#ifdef _WIN64 - int mask = 0; -#endif - FFI_ASSERT (cif->abi == FFI_SYSV); - - if (cif->abi == FFI_SYSV) - bytes = 0; -#if !defined(_WIN64) - else if (cif->abi == FFI_STDCALL) - bytes = cif->bytes; -#endif - else - return FFI_BAD_ABI; - - tramp = &closure->tramp[0]; - -#define BYTES(text) memcpy(tramp, text, sizeof(text)), tramp += sizeof(text)-1 -#define POINTER(x) *(void**)tramp = (void*)(x), tramp += sizeof(void*) -#define SHORT(x) *(short*)tramp = x, tramp += sizeof(short) -#define INT(x) *(int*)tramp = x, tramp += sizeof(int) - -#ifdef _WIN64 - if (cif->nargs >= 1 && - (cif->arg_types[0]->type == FFI_TYPE_FLOAT - || cif->arg_types[0]->type == FFI_TYPE_DOUBLE)) - mask |= 1; - if (cif->nargs >= 2 && - (cif->arg_types[1]->type == FFI_TYPE_FLOAT - || cif->arg_types[1]->type == FFI_TYPE_DOUBLE)) - mask |= 2; - if (cif->nargs >= 3 && - (cif->arg_types[2]->type == FFI_TYPE_FLOAT - || cif->arg_types[2]->type == FFI_TYPE_DOUBLE)) - mask |= 4; - if (cif->nargs >= 4 && - (cif->arg_types[3]->type == FFI_TYPE_FLOAT - || cif->arg_types[3]->type == FFI_TYPE_DOUBLE)) - mask |= 8; - - /* 41 BB ---- mov r11d,mask */ - BYTES("\x41\xBB"); INT(mask); - - /* 48 B8 -------- mov rax, closure */ - BYTES("\x48\xB8"); POINTER(closure); - - /* 49 BA -------- mov r10, ffi_closure_OUTER */ - BYTES("\x49\xBA"); POINTER(ffi_closure_OUTER); - - /* 41 FF E2 jmp r10 */ - BYTES("\x41\xFF\xE2"); - -#else - - /* mov ecx, closure */ - BYTES("\xb9"); POINTER(closure); - - /* mov edx, esp */ - BYTES("\x8b\xd4"); - - /* call ffi_closure_SYSV */ - BYTES("\xe8"); POINTER((char*)&ffi_closure_SYSV - (tramp + 4)); - - /* ret bytes */ - BYTES("\xc2"); - SHORT(bytes); - -#endif - - if (tramp - &closure->tramp[0] > FFI_TRAMPOLINE_SIZE) - Py_FatalError("FFI_TRAMPOLINE_SIZE too small in " __FILE__); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - return FFI_OK; -} diff --git a/Modules/_ctypes/libffi_msvc/ffi.h b/Modules/_ctypes/libffi_msvc/ffi.h deleted file mode 100644 index ba74202720a..00000000000 --- a/Modules/_ctypes/libffi_msvc/ffi.h +++ /dev/null @@ -1,322 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------- - The basic API is described in the README file. - - The raw API is designed to bypass some of the argument packing - and unpacking on architectures for which it can be avoided. - - The closure API allows interpreted functions to be packaged up - inside a C function pointer, so that they can be called as C functions, - with no understanding on the client side that they are interpreted. - It can also be used in other cases in which it is necessary to package - up a user specified parameter and a function pointer as a single - function pointer. - - The closure API must be implemented in order to get its functionality, - e.g. for use by gij. Routines are provided to emulate the raw API - if the underlying platform doesn't allow faster implementation. - - More details on the raw and cloure API can be found in: - - http://gcc.gnu.org/ml/java/1999-q3/msg00138.html - - and - - http://gcc.gnu.org/ml/java/1999-q3/msg00174.html - -------------------------------------------------------------------- */ - -#ifndef LIBFFI_H -#define LIBFFI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Specify which architecture libffi is configured for. */ -//XXX #define X86 - -/* ---- System configuration information --------------------------------- */ - -#include - -#ifndef LIBFFI_ASM - -#include -#include - -/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). - But we can find it either under the correct ANSI name, or under GNU - C's internal name. */ -#ifdef LONG_LONG_MAX -# define FFI_LONG_LONG_MAX LONG_LONG_MAX -#else -# ifdef LLONG_MAX -# define FFI_LONG_LONG_MAX LLONG_MAX -# else -# ifdef __GNUC__ -# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ -# endif -# ifdef _MSC_VER -# define FFI_LONG_LONG_MAX _I64_MAX -# endif -# endif -#endif - -#if SCHAR_MAX == 127 -# define ffi_type_uchar ffi_type_uint8 -# define ffi_type_schar ffi_type_sint8 -#else - #error "char size not supported" -#endif - -#if SHRT_MAX == 32767 -# define ffi_type_ushort ffi_type_uint16 -# define ffi_type_sshort ffi_type_sint16 -#elif SHRT_MAX == 2147483647 -# define ffi_type_ushort ffi_type_uint32 -# define ffi_type_sshort ffi_type_sint32 -#else - #error "short size not supported" -#endif - -#if INT_MAX == 32767 -# define ffi_type_uint ffi_type_uint16 -# define ffi_type_sint ffi_type_sint16 -#elif INT_MAX == 2147483647 -# define ffi_type_uint ffi_type_uint32 -# define ffi_type_sint ffi_type_sint32 -#elif INT_MAX == 9223372036854775807 -# define ffi_type_uint ffi_type_uint64 -# define ffi_type_sint ffi_type_sint64 -#else - #error "int size not supported" -#endif - -#define ffi_type_ulong ffi_type_uint64 -#define ffi_type_slong ffi_type_sint64 -#if LONG_MAX == 2147483647 -# if FFI_LONG_LONG_MAX != 9223372036854775807 - #error "no 64-bit data type supported" -# endif -#elif LONG_MAX != 9223372036854775807 - #error "long size not supported" -#endif - -/* The closure code assumes that this works on pointers, i.e. a size_t */ -/* can hold a pointer. */ - -typedef struct _ffi_type -{ - size_t size; - unsigned short alignment; - unsigned short type; - /*@null@*/ struct _ffi_type **elements; -} ffi_type; - -int can_return_struct_as_int(size_t); -int can_return_struct_as_sint64(size_t); - -/* These are defined in types.c */ -extern ffi_type ffi_type_void; -extern ffi_type ffi_type_uint8; -extern ffi_type ffi_type_sint8; -extern ffi_type ffi_type_uint16; -extern ffi_type ffi_type_sint16; -extern ffi_type ffi_type_uint32; -extern ffi_type ffi_type_sint32; -extern ffi_type ffi_type_uint64; -extern ffi_type ffi_type_sint64; -extern ffi_type ffi_type_float; -extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; -extern ffi_type ffi_type_pointer; - - -typedef enum { - FFI_OK = 0, - FFI_BAD_TYPEDEF, - FFI_BAD_ABI -} ffi_status; - -typedef unsigned FFI_TYPE; - -typedef struct { - ffi_abi abi; - unsigned nargs; - /*@dependent@*/ ffi_type **arg_types; - /*@dependent@*/ ffi_type *rtype; - unsigned bytes; - unsigned flags; -#ifdef FFI_EXTRA_CIF_FIELDS - FFI_EXTRA_CIF_FIELDS; -#endif -} ffi_cif; - -/* ---- Definitions for the raw API -------------------------------------- */ - -#ifdef _WIN64 -#define FFI_SIZEOF_ARG 8 -#else -#define FFI_SIZEOF_ARG 4 -#endif - -typedef union { - ffi_sarg sint; - ffi_arg uint; - float flt; - char data[FFI_SIZEOF_ARG]; - void* ptr; -} ffi_raw; - -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); - -void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); -size_t ffi_raw_size (ffi_cif *cif); - -/* This is analogous to the raw API, except it uses Java parameter */ -/* packing, even on 64-bit machines. I.e. on 64-bit machines */ -/* longs and doubles are followed by an empty 64-bit word. */ - -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); - -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); -size_t ffi_java_raw_size (ffi_cif *cif); - -/* ---- Definitions for closures ----------------------------------------- */ - -#if FFI_CLOSURES - -typedef struct { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif *cif; - void (*fun)(ffi_cif*,void*,void**,void*); - void *user_data; -} ffi_closure; - -void ffi_closure_free(void *); -void *ffi_closure_alloc (size_t size, void **code); - -ffi_status -ffi_prep_closure_loc (ffi_closure*, - ffi_cif *, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data, - void *codeloc); - -typedef struct { - char tramp[FFI_TRAMPOLINE_SIZE]; - - ffi_cif *cif; - -#if !FFI_NATIVE_RAW_API - - /* if this is enabled, then a raw closure has the same layout - as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ - - void (*translate_args)(ffi_cif*,void*,void**,void*); - void *this_closure; - -#endif - - void (*fun)(ffi_cif*,void*,ffi_raw*,void*); - void *user_data; - -} ffi_raw_closure; - -ffi_status -ffi_prep_raw_closure (ffi_raw_closure*, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data); - -ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure*, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data); - -#endif /* FFI_CLOSURES */ - -/* ---- Public interface definition -------------------------------------- */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, - unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes); - -int -ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue); - -/* Useful for eliminating compiler warnings */ -#define FFI_FN(f) ((void (*)())f) - -/* ---- Definitions shared with assembly code ---------------------------- */ - -#endif - -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 -#if 1 -#define FFI_TYPE_LONGDOUBLE 4 -#else -#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 - -/* This should always refer to the last type code (for sanity checks) */ -#define FFI_TYPE_LAST FFI_TYPE_POINTER - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/Modules/_ctypes/libffi_msvc/ffi_common.h b/Modules/_ctypes/libffi_msvc/ffi_common.h deleted file mode 100644 index 43fb83b4810..00000000000 --- a/Modules/_ctypes/libffi_msvc/ffi_common.h +++ /dev/null @@ -1,77 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi_common.h - Copyright (c) 1996 Red Hat, Inc. - - Common internal definitions and macros. Only necessary for building - libffi. - ----------------------------------------------------------------------- */ - -#ifndef FFI_COMMON_H -#define FFI_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* Check for the existence of memcpy. */ -#if STDC_HEADERS -# include -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy ((s), (d), (n)) -# endif -#endif - -#if defined(FFI_DEBUG) -#include -#endif - -#ifdef FFI_DEBUG -/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); -void ffi_stop_here(void); -void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); - -#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) -#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) -#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) -#else -#define FFI_ASSERT(x) -#define FFI_ASSERT_AT(x, f, l) -#define FFI_ASSERT_VALID_TYPE(x) -#endif - -#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif); - -/* Extended cif, used in callback from assembly routine */ -typedef struct -{ - /*@dependent@*/ ffi_cif *cif; - /*@dependent@*/ void *rvalue; - /*@dependent@*/ void **avalue; -} extended_cif; - -/* Terse sized type definitions. */ -typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); -typedef signed int SINT8 __attribute__((__mode__(__QI__))); -typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); -typedef signed int SINT16 __attribute__((__mode__(__HI__))); -typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); -typedef signed int SINT32 __attribute__((__mode__(__SI__))); -typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); -typedef signed int SINT64 __attribute__((__mode__(__DI__))); - -typedef float FLOAT32; - - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/Modules/_ctypes/libffi_msvc/fficonfig.h b/Modules/_ctypes/libffi_msvc/fficonfig.h deleted file mode 100644 index c14f653ec89..00000000000 --- a/Modules/_ctypes/libffi_msvc/fficonfig.h +++ /dev/null @@ -1,96 +0,0 @@ -/* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */ - -/* fficonfig.h. Generated automatically by configure. */ -/* fficonfig.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define this for MSVC, but not for mingw32! */ -#ifdef _MSC_VER -#define __attribute__(x) /* */ -#endif -#define alloca _alloca - -/*----------------------------------------------------------------*/ - -/* Define if using alloca.c. */ -/* #undef C_ALLOCA */ - -/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. - This function is required for alloca.c support on those systems. */ -/* #undef CRAY_STACKSEG_END */ - -/* Define if you have alloca, as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define if you have and it should be used (not on Ultrix). */ -/* #define HAVE_ALLOCA_H 1 */ - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown - */ -/* #undef STACK_DIRECTION */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you have the memcpy function. */ -#define HAVE_MEMCPY 1 - -/* Define if read-only mmap of a plain file works. */ -//#define HAVE_MMAP_FILE 1 - -/* Define if mmap of /dev/zero works. */ -//#define HAVE_MMAP_DEV_ZERO 1 - -/* Define if mmap with MAP_ANON(YMOUS) works. */ -//#define HAVE_MMAP_ANON 1 - -/* The number of bytes in type double */ -#define SIZEOF_DOUBLE 8 - -/* The number of bytes in type long double */ -#define SIZEOF_LONG_DOUBLE 12 - -/* Define if you have the long double type and it is bigger than a double */ -#define HAVE_LONG_DOUBLE 1 - -/* whether byteorder is bigendian */ -/* #undef WORDS_BIGENDIAN */ - -/* Define if the host machine stores words of multi-word integers in - big-endian order. */ -/* #undef HOST_WORDS_BIG_ENDIAN */ - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 1234 - -/* Define if your assembler and linker support unaligned PC relative relocs. */ -/* #undef HAVE_AS_SPARC_UA_PCREL */ - -/* Define if your assembler supports .register. */ -/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ - -/* Define if .eh_frame sections should be read-only. */ -/* #undef HAVE_RO_EH_FRAME */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -/* #define EH_FRAME_FLAGS "aw" */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -/* #define EH_FRAME_FLAGS "aw" */ - -/* Define this if you want extra debugging. */ -/* #undef FFI_DEBUG */ - -/* Define this is you do not want support for aggregate types. */ -/* #undef FFI_NO_STRUCTS */ - -/* Define this is you do not want support for the raw API. */ -/* #undef FFI_NO_RAW_API */ - -/* Define this if you are using Purify and want to suppress spurious messages. */ -/* #undef USING_PURIFY */ - diff --git a/Modules/_ctypes/libffi_msvc/ffitarget.h b/Modules/_ctypes/libffi_msvc/ffitarget.h deleted file mode 100644 index 85f5ee81bbe..00000000000 --- a/Modules/_ctypes/libffi_msvc/ffitarget.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for x86 and x86-64. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -/* ---- System specific configurations ----------------------------------- */ - -#if defined (X86_64) && defined (__i386__) -#undef X86_64 -#define X86 -#endif - -/* ---- Generic type definitions ----------------------------------------- */ - -#ifndef LIBFFI_ASM -#ifndef _WIN64 -typedef unsigned long ffi_arg; -#else -typedef unsigned __int64 ffi_arg; -#endif -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - - /* ---- Intel x86 Win32 ---------- */ - FFI_SYSV, -#ifndef _WIN64 - FFI_STDCALL, -#endif - /* TODO: Add fastcall support for the sake of completeness */ - FFI_DEFAULT_ABI = FFI_SYSV, - - /* ---- Intel x86 and AMD x86-64 - */ -/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */ -/* FFI_SYSV, */ -/* FFI_UNIX64,*/ /* Unix variants all use the same ABI for x86-64 */ -/* #ifdef __i386__ */ -/* FFI_DEFAULT_ABI = FFI_SYSV, */ -/* #else */ -/* FFI_DEFAULT_ABI = FFI_UNIX64, */ -/* #endif */ -/* #endif */ - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; -#endif - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 - -#ifdef _WIN64 -#define FFI_TRAMPOLINE_SIZE 29 -#define FFI_NATIVE_RAW_API 0 -#else -#define FFI_TRAMPOLINE_SIZE 15 -#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ -#endif - -#endif - diff --git a/Modules/_ctypes/libffi_msvc/prep_cif.c b/Modules/_ctypes/libffi_msvc/prep_cif.c deleted file mode 100644 index 022435e53fc..00000000000 --- a/Modules/_ctypes/libffi_msvc/prep_cif.c +++ /dev/null @@ -1,188 +0,0 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include -#include - - -/* Round up to FFI_SIZEOF_ARG. */ - -#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) -{ - ffi_type **ptr; - - FFI_ASSERT(arg != NULL); - - /*@-usedef@*/ - - FFI_ASSERT(arg->elements != NULL); - FFI_ASSERT(arg->size == 0); - FFI_ASSERT(arg->alignment == 0); - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT_VALID_TYPE(*ptr); - - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; - - ptr++; - } - - /* Structure size includes tail padding. This is important for - structures that fit in one register on ABIs like the PowerPC64 - Linux ABI that right justify small structs in a register. - It's also needed for nested structure layout, for example - struct A { long a; char b; }; struct B { struct A x; char y; }; - should find y at an offset of 2*sizeof(long) and result in a - total size of 3*sizeof(long). */ - arg->size = ALIGN (arg->size, arg->alignment); - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - else - return FFI_OK; - - /*@=usedef@*/ -} - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes) -{ - unsigned bytes = 0; - unsigned int i; - ffi_type **ptr; - - FFI_ASSERT(cif != NULL); - FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT_VALID_TYPE(cif->rtype); - - /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined __x86_64__ && !defined S390 - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT -#ifdef _WIN32 - && !can_return_struct_as_int(cif->rtype->size) /* MSVC returns small structs in registers */ - && !can_return_struct_as_sint64(cif->rtype->size) -#endif -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif - ) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type, do this - check after the initialization. */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#if !defined __x86_64__ && !defined S390 -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#elif defined (_WIN64) - if ((*ptr)->type == FFI_TYPE_STRUCT && - !can_return_struct_as_int((*ptr)->size) && - !can_return_struct_as_sint64((*ptr)->size)) - bytes += sizeof(void*); - else -#endif - { -#if !defined(_MSC_VER) && !defined(__MINGW32__) - /* Don't know if this is a libffi bug or not. At least on - Windows with MSVC, function call parameters are *not* - aligned in the same way as structure fields are, they are - only aligned in integer boundaries. - - This doesn't do any harm for cdecl functions and closures, - since the caller cleans up the stack, but it is wrong for - stdcall functions where the callee cleans. - */ - - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - -#endif - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#endif - } - -#ifdef _WIN64 - /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ - if (bytes < 40) - bytes = 40; -#endif - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} diff --git a/Modules/_ctypes/libffi_msvc/types.c b/Modules/_ctypes/libffi_msvc/types.c deleted file mode 100644 index 4433ac28c8c..00000000000 --- a/Modules/_ctypes/libffi_msvc/types.c +++ /dev/null @@ -1,104 +0,0 @@ -/* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Predefined ffi_types needed by libffi. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -/* Type definitions */ - -#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } -#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } - -/* Size and alignment are fake here. They must not be 0. */ -FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); - -FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); -FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); -FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); -FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); -FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); -FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); -FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); - -#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ - || defined IA64 || defined _WIN64 - -FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); - -#else - -FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); - -#endif - -#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined SH - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#else - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); - -#endif - - -#if defined X86 || defined X86_WIN32 || defined M68K - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined SPARC - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -#ifdef SPARC64 -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -#else -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); -#endif - -#elif defined X86_64 - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); - -#else - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); - -#endif - diff --git a/Modules/_ctypes/libffi_msvc/win32.c b/Modules/_ctypes/libffi_msvc/win32.c deleted file mode 100644 index f44a5fe3697..00000000000 --- a/Modules/_ctypes/libffi_msvc/win32.c +++ /dev/null @@ -1,162 +0,0 @@ -/* ----------------------------------------------------------------------- - win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. - Copyright (c) 2001 John Beniton - Copyright (c) 2002 Ranjit Mathew - - - X86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -/* theller: almost verbatim translation from gas syntax to MSVC inline - assembler code. */ - -/* theller: ffi_call_x86 now returns an integer - the difference of the stack - pointer before and after the function call. If everything is ok, zero is - returned. If stdcall functions are passed the wrong number of arguments, - the difference will be nonzero. */ - -#include -#include - -__declspec(naked) int -ffi_call_x86(void (* prepfunc)(char *, extended_cif *), /* 8 */ - extended_cif *ecif, /* 12 */ - unsigned bytes, /* 16 */ - unsigned flags, /* 20 */ - unsigned *rvalue, /* 24 */ - void (*fn)()) /* 28 */ -{ - _asm { - push ebp - mov ebp, esp - - push esi // NEW: this register must be preserved across function calls -// XXX SAVE ESP NOW! - mov esi, esp // save stack pointer before the call - -// Make room for all of the new args. - mov ecx, [ebp+16] - sub esp, ecx // sub esp, bytes - - mov eax, esp - -// Place all of the ffi_prep_args in position - push [ebp + 12] // ecif - push eax - call [ebp + 8] // prepfunc - -// Return stack to previous state and call the function - add esp, 8 -// FIXME: Align the stack to a 128-bit boundary to avoid -// potential performance hits. - call [ebp + 28] - -// Load ecif->cif->abi - mov ecx, [ebp + 12] - mov ecx, [ecx]ecif.cif - mov ecx, [ecx]ecif.cif.abi - - cmp ecx, FFI_STDCALL - je noclean -// STDCALL: Remove the space we pushed for the args - mov ecx, [ebp + 16] - add esp, ecx -// CDECL: Caller has already cleaned the stack -noclean: -// Check that esp has the same value as before! - sub esi, esp - -// Load %ecx with the return type code - mov ecx, [ebp + 20] - -// If the return value pointer is NULL, assume no return value. -/* - Intel asm is weird. We have to explicitly specify 'DWORD PTR' in the next instruction, - otherwise only one BYTE will be compared (instead of a DWORD)! - */ - cmp DWORD PTR [ebp + 24], 0 - jne sc_retint - -// Even if there is no space for the return value, we are -// obliged to handle floating-point values. - cmp ecx, FFI_TYPE_FLOAT - jne sc_noretval -// fstp %st(0) - fstp st(0) - - jmp sc_epilogue - -sc_retint: - cmp ecx, FFI_TYPE_INT - jne sc_retfloat -// # Load %ecx with the pointer to storage for the return value - mov ecx, [ebp + 24] - mov [ecx + 0], eax - jmp sc_epilogue - -sc_retfloat: - cmp ecx, FFI_TYPE_FLOAT - jne sc_retdouble -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] -// fstps (%ecx) - fstp DWORD PTR [ecx] - jmp sc_epilogue - -sc_retdouble: - cmp ecx, FFI_TYPE_DOUBLE - jne sc_retlongdouble -// movl 24(%ebp),%ecx - mov ecx, [ebp+24] - fstp QWORD PTR [ecx] - jmp sc_epilogue - - jmp sc_retlongdouble // avoid warning about unused label -sc_retlongdouble: - cmp ecx, FFI_TYPE_LONGDOUBLE - jne sc_retint64 -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] -// fstpt (%ecx) - fstp QWORD PTR [ecx] /* XXX ??? */ - jmp sc_epilogue - -sc_retint64: - cmp ecx, FFI_TYPE_SINT64 - jne sc_retstruct -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] - mov [ecx+0], eax - mov [ecx+4], edx - -sc_retstruct: -// Nothing to do! - -sc_noretval: -sc_epilogue: - mov eax, esi - pop esi // NEW restore: must be preserved across function calls - mov esp, ebp - pop ebp - ret - } -} diff --git a/Modules/_ctypes/libffi_msvc/win64.asm b/Modules/_ctypes/libffi_msvc/win64.asm deleted file mode 100644 index 301188bc9c1..00000000000 --- a/Modules/_ctypes/libffi_msvc/win64.asm +++ /dev/null @@ -1,156 +0,0 @@ -PUBLIC ffi_call_AMD64 - -EXTRN __chkstk:NEAR -EXTRN ffi_closure_SYSV:NEAR - -_TEXT SEGMENT - -;;; ffi_closure_OUTER will be called with these registers set: -;;; rax points to 'closure' -;;; r11 contains a bit mask that specifies which of the -;;; first four parameters are float or double -;;; -;;; It must move the parameters passed in registers to their stack location, -;;; call ffi_closure_SYSV for the actual work, then return the result. -;;; -ffi_closure_OUTER PROC FRAME - ;; save actual arguments to their stack space. - test r11, 1 - jne first_is_float - mov QWORD PTR [rsp+8], rcx - jmp second -first_is_float: - movlpd QWORD PTR [rsp+8], xmm0 - -second: - test r11, 2 - jne second_is_float - mov QWORD PTR [rsp+16], rdx - jmp third -second_is_float: - movlpd QWORD PTR [rsp+16], xmm1 - -third: - test r11, 4 - jne third_is_float - mov QWORD PTR [rsp+24], r8 - jmp forth -third_is_float: - movlpd QWORD PTR [rsp+24], xmm2 - -forth: - test r11, 8 - jne forth_is_float - mov QWORD PTR [rsp+32], r9 - jmp done -forth_is_float: - movlpd QWORD PTR [rsp+32], xmm3 - -done: -.ALLOCSTACK 40 - sub rsp, 40 -.ENDPROLOG - mov rcx, rax ; context is first parameter - mov rdx, rsp ; stack is second parameter - add rdx, 40 ; correct our own area - mov rax, ffi_closure_SYSV - call rax ; call the real closure function - ;; Here, code is missing that handles float return values - add rsp, 40 - movd xmm0, rax ; In case the closure returned a float. - ret 0 -ffi_closure_OUTER ENDP - - -;;; ffi_call_AMD64 - -stack$ = 0 -prepfunc$ = 32 -ecif$ = 40 -bytes$ = 48 -flags$ = 56 -rvalue$ = 64 -fn$ = 72 - -ffi_call_AMD64 PROC FRAME - - mov QWORD PTR [rsp+32], r9 - mov QWORD PTR [rsp+24], r8 - mov QWORD PTR [rsp+16], rdx - mov QWORD PTR [rsp+8], rcx -.PUSHREG rbp - push rbp -.ALLOCSTACK 48 - sub rsp, 48 ; 00000030H -.SETFRAME rbp, 32 - lea rbp, QWORD PTR [rsp+32] -.ENDPROLOG - - mov eax, DWORD PTR bytes$[rbp] - add rax, 15 - and rax, -16 - call __chkstk - sub rsp, rax - lea rax, QWORD PTR [rsp+32] - mov QWORD PTR stack$[rbp], rax - - mov rdx, QWORD PTR ecif$[rbp] - mov rcx, QWORD PTR stack$[rbp] - call QWORD PTR prepfunc$[rbp] - - mov rsp, QWORD PTR stack$[rbp] - - movlpd xmm3, QWORD PTR [rsp+24] - movd r9, xmm3 - - movlpd xmm2, QWORD PTR [rsp+16] - movd r8, xmm2 - - movlpd xmm1, QWORD PTR [rsp+8] - movd rdx, xmm1 - - movlpd xmm0, QWORD PTR [rsp] - movd rcx, xmm0 - - call QWORD PTR fn$[rbp] -ret_int$: - cmp DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT - jne ret_float$ - - mov rcx, QWORD PTR rvalue$[rbp] - mov DWORD PTR [rcx], eax - jmp SHORT ret_nothing$ - -ret_float$: - cmp DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT - jne SHORT ret_double$ - - mov rax, QWORD PTR rvalue$[rbp] - movlpd QWORD PTR [rax], xmm0 - jmp SHORT ret_nothing$ - -ret_double$: - cmp DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE - jne SHORT ret_int64$ - - mov rax, QWORD PTR rvalue$[rbp] - movlpd QWORD PTR [rax], xmm0 - jmp SHORT ret_nothing$ - -ret_int64$: - cmp DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64 - jne ret_nothing$ - - mov rcx, QWORD PTR rvalue$[rbp] - mov QWORD PTR [rcx], rax - jmp SHORT ret_nothing$ - -ret_nothing$: - xor eax, eax - - lea rsp, QWORD PTR [rbp+16] - pop rbp - ret 0 -ffi_call_AMD64 ENDP -_TEXT ENDS -END diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 8ad76497c7b..f9cdb336958 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -106,6 +106,11 @@ void *ffi_closure_alloc(size_t ignored, void** codeloc) return NULL; item = free_list; free_list = item->next; +#ifdef _M_ARM + // set Thumb bit so that blx is called correctly + *codeloc = (ITEM*)((uintptr_t)item | 1); +#else *codeloc = (void *)item; +#endif return (void *)item; } diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index e7bbefd50fd..53849e3a29c 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -250,7 +250,10 @@ PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) static void PyCursesPanel_Dealloc(PyCursesPanelObject *po) { - PyObject *obj = (PyObject *) panel_userptr(po->pan); + PyObject *tp, *obj; + + tp = (PyObject *) Py_TYPE(po); + obj = (PyObject *) panel_userptr(po->pan); if (obj) { (void)set_panel_userptr(po->pan, NULL); Py_DECREF(obj); @@ -261,6 +264,7 @@ PyCursesPanel_Dealloc(PyCursesPanelObject *po) remove_lop(po); } PyObject_DEL(po); + Py_DECREF(tp); } /* panel_above(NULL) returns the bottom panel in the stack. To get diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index c1557b5e6f4..83e43a24395 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -2921,6 +2921,23 @@ datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp) return date_fromtimestamp((PyObject *) type, timestamp); } +/* bpo-36025: This is a wrapper for API compatibility with the public C API, + * which expects a function that takes an *args tuple, whereas the argument + * clinic generates code that takes METH_O. + */ +static PyObject * +datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args) +{ + PyObject *timestamp; + PyObject *result = NULL; + + if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, ×tamp)) { + result = date_fromtimestamp(cls, timestamp); + } + + return result; +} + /* Return new date from proleptic Gregorian ordinal. Raises ValueError if * the ordinal is out of range. */ @@ -2986,6 +3003,67 @@ date_fromisoformat(PyObject *cls, PyObject *dtstr) return NULL; } + +static PyObject * +date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) +{ + static char *keywords[] = { + "year", "week", "day", NULL + }; + + int year, week, day; + if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar", + keywords, + &year, &week, &day) == 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(PyExc_ValueError, + "ISO calendar component out of range"); + + } + return NULL; + } + + // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5) + if (year < MINYEAR || year > MAXYEAR) { + PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year); + return NULL; + } + + if (week <= 0 || week >= 53) { + int out_of_range = 1; + if (week == 53) { + // ISO years have 53 weeks in it on years starting with a Thursday + // and on leap years starting on Wednesday + int first_weekday = weekday(year, 1, 1); + if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) { + out_of_range = 0; + } + } + + if (out_of_range) { + PyErr_Format(PyExc_ValueError, "Invalid week: %d", week); + return NULL; + } + } + + if (day <= 0 || day >= 8) { + PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])", + day); + return NULL; + } + + // Convert (Y, W, D) to (Y, M, D) in-place + int day_1 = iso_week1_monday(year); + + int month = week; + int day_offset = (month - 1)*7 + day - 1; + + ord_to_ymd(day_1 + day_offset, &year, &month, &day); + + return new_date_subclass_ex(year, month, day, cls); +} + + /* * Date arithmetic. */ @@ -3279,6 +3357,12 @@ static PyMethodDef date_methods[] = { METH_CLASS, PyDoc_STR("str -> Construct a date from the output of date.isoformat()")}, + {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("int, int, int -> Construct a date from the ISO year, week " + "number and weekday.\n\n" + "This is the inverse of the date.isocalendar() function")}, + {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS, PyDoc_STR("Current date or datetime: same as " "self.__class__.fromtimestamp(time.time()).")}, @@ -6275,7 +6359,7 @@ static PyDateTime_CAPI CAPI = { new_delta_ex, new_timezone, datetime_fromtimestamp, - date_fromtimestamp, + datetime_date_fromtimestamp_capi, new_datetime_ex2, new_time_ex2 }; diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 51aed2c67dc..d977b14f5b0 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -5390,7 +5390,7 @@ static PyTypeObject PyDecContext_Type = 0, /* tp_as_mapping */ (hashfunc) 0, /* tp_hash */ 0, /* tp_call */ - (reprfunc) context_repr, /* tp_str */ + 0, /* tp_str */ (getattrofunc) context_getattr, /* tp_getattro */ (setattrofunc) context_setattr, /* tp_setattro */ (PyBufferProcs *) 0, /* tp_as_buffer */ diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 1e58cd05b51..e9a0ea21b29 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -92,6 +92,8 @@ typedef struct { PyObject *parseerror_obj; PyObject *deepcopy_obj; PyObject *elementpath_obj; + PyObject *comment_factory; + PyObject *pi_factory; } elementtreestate; static struct PyModuleDef elementtreemodule; @@ -114,6 +116,8 @@ elementtree_clear(PyObject *m) Py_CLEAR(st->parseerror_obj); Py_CLEAR(st->deepcopy_obj); Py_CLEAR(st->elementpath_obj); + Py_CLEAR(st->comment_factory); + Py_CLEAR(st->pi_factory); return 0; } @@ -124,6 +128,8 @@ elementtree_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->parseerror_obj); Py_VISIT(st->deepcopy_obj); Py_VISIT(st->elementpath_obj); + Py_VISIT(st->comment_factory); + Py_VISIT(st->pi_factory); return 0; } @@ -1143,6 +1149,13 @@ checkpath(PyObject* tag) const Py_ssize_t len = PyUnicode_GET_LENGTH(tag); void *data = PyUnicode_DATA(tag); unsigned int kind = PyUnicode_KIND(tag); + if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && ( + PyUnicode_READ(kind, data, 1) == '}' || ( + PyUnicode_READ(kind, data, 1) == '*' && + PyUnicode_READ(kind, data, 2) == '}'))) { + /* wildcard: '{}tag' or '{*}tag' */ + return 1; + } for (i = 0; i < len; i++) { Py_UCS4 ch = PyUnicode_READ(kind, data, i); if (ch == '{') @@ -1156,7 +1169,13 @@ checkpath(PyObject* tag) } if (PyBytes_Check(tag)) { char *p = PyBytes_AS_STRING(tag); - for (i = 0; i < PyBytes_GET_SIZE(tag); i++) { + const Py_ssize_t len = PyBytes_GET_SIZE(tag); + if (len >= 3 && p[0] == '{' && ( + p[1] == '}' || (p[1] == '*' && p[2] == '}'))) { + /* wildcard: '{}tag' or '{*}tag' */ + return 1; + } + for (i = 0; i < len; i++) { if (p[i] == '{') check = 0; else if (p[i] == '}') @@ -2385,6 +2404,8 @@ typedef struct { Py_ssize_t index; /* current stack size (0 means empty) */ PyObject *element_factory; + PyObject *comment_factory; + PyObject *pi_factory; /* element tracing */ PyObject *events_append; /* the append method of the list of events, or NULL */ @@ -2392,6 +2413,11 @@ typedef struct { PyObject *end_event_obj; PyObject *start_ns_event_obj; PyObject *end_ns_event_obj; + PyObject *comment_event_obj; + PyObject *pi_event_obj; + + char insert_comments; + char insert_pis; } TreeBuilderObject; #define TreeBuilder_CheckExact(op) (Py_TYPE(op) == &TreeBuilder_Type) @@ -2413,6 +2439,8 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t->data = NULL; t->element_factory = NULL; + t->comment_factory = NULL; + t->pi_factory = NULL; t->stack = PyList_New(20); if (!t->stack) { Py_DECREF(t->this); @@ -2425,6 +2453,8 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t->events_append = NULL; t->start_event_obj = t->end_event_obj = NULL; t->start_ns_event_obj = t->end_ns_event_obj = NULL; + t->comment_event_obj = t->pi_event_obj = NULL; + t->insert_comments = t->insert_pis = 0; } return (PyObject *)t; } @@ -2433,17 +2463,53 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) _elementtree.TreeBuilder.__init__ element_factory: object = NULL + * + comment_factory: object = NULL + pi_factory: object = NULL + insert_comments: bool = False + insert_pis: bool = False [clinic start generated code]*/ static int _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, - PyObject *element_factory) -/*[clinic end generated code: output=91cfa7558970ee96 input=1b424eeefc35249c]*/ + PyObject *element_factory, + PyObject *comment_factory, + PyObject *pi_factory, + int insert_comments, int insert_pis) +/*[clinic end generated code: output=8571d4dcadfdf952 input=1f967b5c245e0a71]*/ { - if (element_factory) { + if (element_factory && element_factory != Py_None) { Py_INCREF(element_factory); Py_XSETREF(self->element_factory, element_factory); + } else { + Py_CLEAR(self->element_factory); + } + + if (!comment_factory || comment_factory == Py_None) { + elementtreestate *st = ET_STATE_GLOBAL; + comment_factory = st->comment_factory; + } + if (comment_factory) { + Py_INCREF(comment_factory); + Py_XSETREF(self->comment_factory, comment_factory); + self->insert_comments = insert_comments; + } else { + Py_CLEAR(self->comment_factory); + self->insert_comments = 0; + } + + if (!pi_factory || pi_factory == Py_None) { + elementtreestate *st = ET_STATE_GLOBAL; + pi_factory = st->pi_factory; + } + if (pi_factory) { + Py_INCREF(pi_factory); + Py_XSETREF(self->pi_factory, pi_factory); + self->insert_pis = insert_pis; + } else { + Py_CLEAR(self->pi_factory); + self->insert_pis = 0; } return 0; @@ -2452,6 +2518,8 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, static int treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) { + Py_VISIT(self->pi_event_obj); + Py_VISIT(self->comment_event_obj); Py_VISIT(self->end_ns_event_obj); Py_VISIT(self->start_ns_event_obj); Py_VISIT(self->end_event_obj); @@ -2462,6 +2530,8 @@ treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) Py_VISIT(self->last); Py_VISIT(self->data); Py_VISIT(self->stack); + Py_VISIT(self->pi_factory); + Py_VISIT(self->comment_factory); Py_VISIT(self->element_factory); return 0; } @@ -2469,6 +2539,8 @@ treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) static int treebuilder_gc_clear(TreeBuilderObject *self) { + Py_CLEAR(self->pi_event_obj); + Py_CLEAR(self->comment_event_obj); Py_CLEAR(self->end_ns_event_obj); Py_CLEAR(self->start_ns_event_obj); Py_CLEAR(self->end_event_obj); @@ -2478,6 +2550,8 @@ treebuilder_gc_clear(TreeBuilderObject *self) Py_CLEAR(self->data); Py_CLEAR(self->last); Py_CLEAR(self->this); + Py_CLEAR(self->pi_factory); + Py_CLEAR(self->comment_factory); Py_CLEAR(self->element_factory); Py_CLEAR(self->root); return 0; @@ -2494,6 +2568,57 @@ treebuilder_dealloc(TreeBuilderObject *self) /* -------------------------------------------------------------------- */ /* helpers for handling of arbitrary element-like objects */ +/*[clinic input] +_elementtree._set_factories + + comment_factory: object + pi_factory: object + / + +Change the factories used to create comments and processing instructions. + +For internal use only. +[clinic start generated code]*/ + +static PyObject * +_elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, + PyObject *pi_factory) +/*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/ +{ + elementtreestate *st = ET_STATE_GLOBAL; + PyObject *old; + + if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) { + PyErr_Format(PyExc_TypeError, "Comment factory must be callable, not %.100s", + Py_TYPE(comment_factory)->tp_name); + return NULL; + } + if (!PyCallable_Check(pi_factory) && pi_factory != Py_None) { + PyErr_Format(PyExc_TypeError, "PI factory must be callable, not %.100s", + Py_TYPE(pi_factory)->tp_name); + return NULL; + } + + old = PyTuple_Pack(2, + st->comment_factory ? st->comment_factory : Py_None, + st->pi_factory ? st->pi_factory : Py_None); + + if (comment_factory == Py_None) { + Py_CLEAR(st->comment_factory); + } else { + Py_INCREF(comment_factory); + Py_XSETREF(st->comment_factory, comment_factory); + } + if (pi_factory == Py_None) { + Py_CLEAR(st->pi_factory); + } else { + Py_INCREF(pi_factory); + Py_XSETREF(st->pi_factory, pi_factory); + } + + return old; +} + static int treebuilder_set_element_text_or_tail(PyObject *element, PyObject **data, PyObject **dest, _Py_Identifier *name) @@ -2569,7 +2694,7 @@ treebuilder_append_event(TreeBuilderObject *self, PyObject *action, PyObject *event = PyTuple_Pack(2, action, node); if (event == NULL) return -1; - res = PyObject_CallFunctionObjArgs(self->events_append, event, NULL); + res = _PyObject_FastCall(self->events_append, &event, 1); Py_DECREF(event); if (res == NULL) return -1; @@ -2593,7 +2718,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, return NULL; } - if (!self->element_factory || self->element_factory == Py_None) { + if (!self->element_factory) { node = create_new_element(tag, attrib); } else if (attrib == Py_None) { attrib = PyDict_New(); @@ -2721,6 +2846,117 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) return (PyObject*) self->last; } +LOCAL(PyObject*) +treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) +{ + PyObject* comment = NULL; + PyObject* this; + + if (treebuilder_flush_data(self) < 0) { + return NULL; + } + + if (self->comment_factory) { + comment = _PyObject_FastCall(self->comment_factory, &text, 1); + if (!comment) + return NULL; + + this = self->this; + if (self->insert_comments && this != Py_None) { + if (treebuilder_add_subelement(this, comment) < 0) + goto error; + } + } else { + Py_INCREF(text); + comment = text; + } + + if (self->events_append && self->comment_event_obj) { + if (treebuilder_append_event(self, self->comment_event_obj, comment) < 0) + goto error; + } + + return comment; + + error: + Py_DECREF(comment); + return NULL; +} + +LOCAL(PyObject*) +treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) +{ + PyObject* pi = NULL; + PyObject* this; + PyObject* stack[2] = {target, text}; + + if (treebuilder_flush_data(self) < 0) { + return NULL; + } + + if (self->pi_factory) { + pi = _PyObject_FastCall(self->pi_factory, stack, 2); + if (!pi) { + return NULL; + } + + this = self->this; + if (self->insert_pis && this != Py_None) { + if (treebuilder_add_subelement(this, pi) < 0) + goto error; + } + } else { + pi = PyTuple_Pack(2, target, text); + if (!pi) { + return NULL; + } + } + + if (self->events_append && self->pi_event_obj) { + if (treebuilder_append_event(self, self->pi_event_obj, pi) < 0) + goto error; + } + + return pi; + + error: + Py_DECREF(pi); + return NULL; +} + +LOCAL(PyObject*) +treebuilder_handle_start_ns(TreeBuilderObject* self, PyObject* prefix, PyObject* uri) +{ + PyObject* parcel; + + if (self->events_append && self->start_ns_event_obj) { + parcel = PyTuple_Pack(2, prefix, uri); + if (!parcel) { + return NULL; + } + + if (treebuilder_append_event(self, self->start_ns_event_obj, parcel) < 0) { + Py_DECREF(parcel); + return NULL; + } + Py_DECREF(parcel); + } + + Py_RETURN_NONE; +} + +LOCAL(PyObject*) +treebuilder_handle_end_ns(TreeBuilderObject* self, PyObject* prefix) +{ + if (self->events_append && self->end_ns_event_obj) { + if (treebuilder_append_event(self, self->end_ns_event_obj, prefix) < 0) { + return NULL; + } + } + + Py_RETURN_NONE; +} + /* -------------------------------------------------------------------- */ /* methods (in alphabetical order) */ @@ -2754,6 +2990,38 @@ _elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag) return treebuilder_handle_end(self, tag); } +/*[clinic input] +_elementtree.TreeBuilder.comment + + text: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_comment(TreeBuilderObject *self, PyObject *text) +/*[clinic end generated code: output=22835be41deeaa27 input=47e7ebc48ed01dfa]*/ +{ + return treebuilder_handle_comment(self, text); +} + +/*[clinic input] +_elementtree.TreeBuilder.pi + + target: object + text: object = None + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, + PyObject *text) +/*[clinic end generated code: output=21eb95ec9d04d1d9 input=349342bd79c35570]*/ +{ + return treebuilder_handle_pi(self, target, text); +} + LOCAL(PyObject*) treebuilder_done(TreeBuilderObject* self) { @@ -2824,6 +3092,8 @@ typedef struct { PyObject *names; + PyObject *handle_start_ns; + PyObject *handle_end_ns; PyObject *handle_start; PyObject *handle_data; PyObject *handle_end; @@ -2925,7 +3195,7 @@ expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, if (errmsg == NULL) return; - error = PyObject_CallFunctionObjArgs(st->parseerror_obj, errmsg, NULL); + error = _PyObject_FastCall(st->parseerror_obj, &errmsg, 1); Py_DECREF(errmsg); if (!error) return; @@ -2988,7 +3258,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, (TreeBuilderObject*) self->target, value ); else if (self->handle_data) - res = PyObject_CallFunctionObjArgs(self->handle_data, value, NULL); + res = _PyObject_FastCall(self->handle_data, &value, 1); else res = NULL; Py_XDECREF(res); @@ -3099,7 +3369,7 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) - res = PyObject_CallFunctionObjArgs(self->handle_data, data, NULL); + res = _PyObject_FastCall(self->handle_data, &data, 1); else res = NULL; @@ -3126,7 +3396,7 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) else if (self->handle_end) { tag = makeuniversal(self, tag_in); if (tag) { - res = PyObject_CallFunctionObjArgs(self->handle_end, tag, NULL); + res = _PyObject_FastCall(self->handle_end, &tag, 1); Py_DECREF(tag); } } @@ -3135,62 +3405,119 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) } static void -expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix, - const XML_Char *uri) +expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, + const XML_Char *uri_in) { - TreeBuilderObject *target = (TreeBuilderObject*) self->target; - PyObject *parcel; + PyObject* res = NULL; + PyObject* uri; + PyObject* prefix; + PyObject* stack[2]; if (PyErr_Occurred()) return; - if (!target->events_append || !target->start_ns_event_obj) - return; + if (!uri_in) + uri_in = ""; + if (!prefix_in) + prefix_in = ""; - if (!uri) - uri = ""; - if (!prefix) - prefix = ""; + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut - TreeBuilder does not actually implement .start_ns() */ + TreeBuilderObject *target = (TreeBuilderObject*) self->target; - parcel = Py_BuildValue("ss", prefix, uri); - if (!parcel) - return; - treebuilder_append_event(target, target->start_ns_event_obj, parcel); - Py_DECREF(parcel); + if (target->events_append && target->start_ns_event_obj) { + prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); + if (!prefix) + return; + uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict"); + if (!uri) { + Py_DECREF(prefix); + return; + } + + res = treebuilder_handle_start_ns(target, prefix, uri); + Py_DECREF(uri); + Py_DECREF(prefix); + } + } else if (self->handle_start_ns) { + prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); + if (!prefix) + return; + uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict"); + if (!uri) { + Py_DECREF(prefix); + return; + } + + stack[0] = prefix; + stack[1] = uri; + res = _PyObject_FastCall(self->handle_start_ns, stack, 2); + Py_DECREF(uri); + Py_DECREF(prefix); + } + + Py_XDECREF(res); } static void expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) { - TreeBuilderObject *target = (TreeBuilderObject*) self->target; + PyObject *res = NULL; + PyObject* prefix; if (PyErr_Occurred()) return; - if (!target->events_append) - return; + if (!prefix_in) + prefix_in = ""; - treebuilder_append_event(target, target->end_ns_event_obj, Py_None); + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut - TreeBuilder does not actually implement .end_ns() */ + TreeBuilderObject *target = (TreeBuilderObject*) self->target; + + if (target->events_append && target->end_ns_event_obj) { + res = treebuilder_handle_end_ns(target, Py_None); + } + } else if (self->handle_end_ns) { + prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); + if (!prefix) + return; + + res = _PyObject_FastCall(self->handle_end_ns, &prefix, 1); + Py_DECREF(prefix); + } + + Py_XDECREF(res); } static void expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) { - PyObject* comment; - PyObject* res; + PyObject* comment = NULL; + PyObject* res = NULL; if (PyErr_Occurred()) return; - if (self->handle_comment) { + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut */ + TreeBuilderObject *target = (TreeBuilderObject*) self->target; + comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); - if (comment) { - res = PyObject_CallFunctionObjArgs(self->handle_comment, - comment, NULL); - Py_XDECREF(res); - Py_DECREF(comment); - } + if (!comment) + return; /* parser will look for errors */ + + res = treebuilder_handle_comment(target, comment); + } else if (self->handle_comment) { + comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); + if (!comment) + return; + + res = _PyObject_FastCall(self->handle_comment, &comment, 1); } + + Py_XDECREF(res); + Py_DECREF(comment); } static void @@ -3258,27 +3585,51 @@ static void expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, const XML_Char* data_in) { - PyObject* target; + PyObject* pi_target = NULL; PyObject* data; PyObject* res; + PyObject* stack[2]; if (PyErr_Occurred()) return; - if (self->handle_pi) { - target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); - data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); - if (target && data) { - res = PyObject_CallFunctionObjArgs(self->handle_pi, - target, data, NULL); + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut */ + TreeBuilderObject *target = (TreeBuilderObject*) self->target; + + if (target->events_append && target->pi_event_obj) { + pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); + if (!pi_target) + goto error; + data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); + if (!data) + goto error; + res = treebuilder_handle_pi(target, pi_target, data); Py_XDECREF(res); Py_DECREF(data); - Py_DECREF(target); - } else { - Py_XDECREF(data); - Py_XDECREF(target); + Py_DECREF(pi_target); } + } else if (self->handle_pi) { + pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); + if (!pi_target) + goto error; + data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); + if (!data) + goto error; + + stack[0] = pi_target; + stack[1] = data; + res = _PyObject_FastCall(self->handle_pi, stack, 2); + Py_XDECREF(res); + Py_DECREF(data); + Py_DECREF(pi_target); } + + return; + + error: + Py_XDECREF(pi_target); + return; } /* -------------------------------------------------------------------- */ @@ -3290,6 +3641,7 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self) { self->parser = NULL; self->target = self->entity = self->names = NULL; + self->handle_start_ns = self->handle_end_ns = NULL; self->handle_start = self->handle_data = self->handle_end = NULL; self->handle_comment = self->handle_pi = self->handle_close = NULL; self->handle_doctype = NULL; @@ -3358,6 +3710,14 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, } self->target = target; + self->handle_start_ns = PyObject_GetAttrString(target, "start_ns"); + if (ignore_attribute_error(self->handle_start_ns)) { + return -1; + } + self->handle_end_ns = PyObject_GetAttrString(target, "end_ns"); + if (ignore_attribute_error(self->handle_end_ns)) { + return -1; + } self->handle_start = PyObject_GetAttrString(target, "start"); if (ignore_attribute_error(self->handle_start)) { return -1; @@ -3389,6 +3749,12 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, /* configure parser */ EXPAT(SetUserData)(self->parser, self); + if (self->handle_start_ns || self->handle_end_ns) + EXPAT(SetNamespaceDeclHandler)( + self->parser, + (XML_StartNamespaceDeclHandler) expat_start_ns_handler, + (XML_EndNamespaceDeclHandler) expat_end_ns_handler + ); EXPAT(SetElementHandler)( self->parser, (XML_StartElementHandler) expat_start_handler, @@ -3433,6 +3799,9 @@ xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) Py_VISIT(self->handle_end); Py_VISIT(self->handle_data); Py_VISIT(self->handle_start); + Py_VISIT(self->handle_start_ns); + Py_VISIT(self->handle_end_ns); + Py_VISIT(self->handle_doctype); Py_VISIT(self->target); Py_VISIT(self->entity); @@ -3456,6 +3825,8 @@ xmlparser_gc_clear(XMLParserObject *self) Py_CLEAR(self->handle_end); Py_CLEAR(self->handle_data); Py_CLEAR(self->handle_start); + Py_CLEAR(self->handle_start_ns); + Py_CLEAR(self->handle_end_ns); Py_CLEAR(self->handle_doctype); Py_CLEAR(self->target); @@ -3695,6 +4066,8 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, Py_CLEAR(target->end_event_obj); Py_CLEAR(target->start_ns_event_obj); Py_CLEAR(target->end_ns_event_obj); + Py_CLEAR(target->comment_event_obj); + Py_CLEAR(target->pi_event_obj); if (events_to_report == Py_None) { /* default is "end" only */ @@ -3740,6 +4113,18 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); + } else if (strcmp(event_name, "comment") == 0) { + Py_XSETREF(target->comment_event_obj, event_name_obj); + EXPAT(SetCommentHandler)( + self->parser, + (XML_CommentHandler) expat_comment_handler + ); + } else if (strcmp(event_name, "pi") == 0) { + Py_XSETREF(target->pi_event_obj, event_name_obj); + EXPAT(SetProcessingInstructionHandler)( + self->parser, + (XML_ProcessingInstructionHandler) expat_pi_handler + ); } else { Py_DECREF(event_name_obj); Py_DECREF(events_seq); @@ -3882,6 +4267,8 @@ static PyMethodDef treebuilder_methods[] = { _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF _ELEMENTTREE_TREEBUILDER_START_METHODDEF _ELEMENTTREE_TREEBUILDER_END_METHODDEF + _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF + _ELEMENTTREE_TREEBUILDER_PI_METHODDEF _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF {NULL, NULL} }; @@ -3983,6 +4370,7 @@ static PyTypeObject XMLParser_Type = { static PyMethodDef _functions[] = { {"SubElement", (PyCFunction)(void(*)(void)) subelement, METH_VARARGS | METH_KEYWORDS}, + _ELEMENTTREE__SET_FACTORIES_METHODDEF {NULL, NULL} }; diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 3f1c01651de..dcc9129fc6b 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -750,8 +750,10 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) PyObject *key, *keyword, *value; Py_ssize_t key_size, pos, key_pos, kwds_size; + kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0; + /* short path, key will match args anyway, which is a tuple */ - if (!typed && !kwds) { + if (!typed && !kwds_size) { if (PyTuple_GET_SIZE(args) == 1) { key = PyTuple_GET_ITEM(args, 0); if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) { @@ -765,9 +767,6 @@ lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) return args; } - kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0; - assert(kwds_size >= 0); - key_size = PyTuple_GET_SIZE(args); if (kwds_size) key_size += kwds_size * 2 + 1; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 965c4846bdb..d482142d080 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -324,7 +324,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, if (universal) { if (creating || writing || appending || updating) { PyErr_SetString(PyExc_ValueError, - "mode U cannot be combined with x', 'w', 'a', or '+'"); + "mode U cannot be combined with 'x', 'w', 'a', or '+'"); goto error; } if (PyErr_WarnEx(PyExc_DeprecationWarning, diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index a5c8eea3ec3..ddaff7b5d13 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -242,7 +242,11 @@ exit: PyDoc_STRVAR(_io__IOBase_writelines__doc__, "writelines($self, lines, /)\n" "--\n" -"\n"); +"\n" +"Write a list of lines to stream.\n" +"\n" +"Line separators are not added, so it is usual for each of the\n" +"lines provided to have a line separator at the end."); #define _IO__IOBASE_WRITELINES_METHODDEF \ {"writelines", (PyCFunction)_io__IOBase_writelines, METH_O, _io__IOBase_writelines__doc__}, @@ -311,4 +315,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=60e43a7cbd9f314e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=61b6ea7153ef9940 input=a9049054013a1b77]*/ diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 9b063cd372f..6a0d9bec5af 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -286,10 +286,22 @@ iobase_finalize(PyObject *self) /* Silencing I/O errors is bad, but printing spurious tracebacks is equally as bad, and potentially more frequent (because of shutdown issues). */ - if (res == NULL) - PyErr_Clear(); - else + if (res == NULL) { +#ifndef Py_DEBUG + const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + if (config->dev_mode) { + PyErr_WriteUnraisable(self); + } + else { + PyErr_Clear(); + } +#else + PyErr_WriteUnraisable(self); +#endif + } + else { Py_DECREF(res); + } } /* Restore the saved exception. */ @@ -739,11 +751,16 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) _io._IOBase.writelines lines: object / + +Write a list of lines to stream. + +Line separators are not added, so it is usual for each of the +lines provided to have a line separator at the end. [clinic start generated code]*/ static PyObject * _io__IOBase_writelines(PyObject *self, PyObject *lines) -/*[clinic end generated code: output=976eb0a9b60a6628 input=432e729a8450b3cb]*/ +/*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/ { PyObject *iter, *res; diff --git a/Modules/_json.c b/Modules/_json.c index 94a7c0d2bf0..4faa9cc22ed 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1,8 +1,11 @@ +/* JSON accelerator C extensor: _json module. + * + * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows + * and as an extension module (Py_BUILD_CORE_MODULE define) on other + * platforms. */ -/* Core extension modules are built-in on some platforms (e.g. Windows). */ -#ifdef Py_BUILD_CORE -#define Py_BUILD_CORE_BUILTIN -#undef Py_BUILD_CORE +#if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE) +# error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined" #endif #include "Python.h" @@ -1479,7 +1482,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, return _steal_accumulate(acc, encoded); } else if (PyLong_Check(obj)) { - PyObject *encoded = PyLong_Type.tp_str(obj); + PyObject *encoded = PyLong_Type.tp_repr(obj); if (encoded == NULL) return -1; return _steal_accumulate(acc, encoded); @@ -1643,7 +1646,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, goto bail; } else if (PyLong_Check(key)) { - kstr = PyLong_Type.tp_str(key); + kstr = PyLong_Type.tp_repr(key); if (kstr == NULL) { goto bail; } diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 4508f5e6569..c4e0f52389d 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -2,62 +2,6 @@ #include "frameobject.h" #include "rotatingtree.h" -/*** Selection of a high-precision timer ***/ - -#ifdef MS_WINDOWS - -#include - -static long long -hpTimer(void) -{ - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - return li.QuadPart; -} - -static double -hpTimerUnit(void) -{ - LARGE_INTEGER li; - if (QueryPerformanceFrequency(&li)) - return 1.0 / li.QuadPart; - else - return 0.000001; /* unlikely */ -} - -#else /* !MS_WINDOWS */ - -#ifndef HAVE_GETTIMEOFDAY -#error "This module requires gettimeofday() on non-Windows platforms!" -#endif - -#include -#include - -static long long -hpTimer(void) -{ - struct timeval tv; - long long ret; -#ifdef GETTIMEOFDAY_NO_TZ - gettimeofday(&tv); -#else - gettimeofday(&tv, (struct timezone *)NULL); -#endif - ret = tv.tv_sec; - ret = ret * 1000000 + tv.tv_usec; - return ret; -} - -static double -hpTimerUnit(void) -{ - return 0.000001; -} - -#endif /* MS_WINDOWS */ - /************************************************************/ /* Written by Brett Rosen and Ted Czotter */ @@ -66,8 +10,8 @@ struct _ProfilerEntry; /* represents a function called from another function */ typedef struct _ProfilerSubEntry { rotating_node_t header; - long long tt; - long long it; + _PyTime_t tt; + _PyTime_t it; long callcount; long recursivecallcount; long recursionLevel; @@ -77,8 +21,8 @@ typedef struct _ProfilerSubEntry { typedef struct _ProfilerEntry { rotating_node_t header; PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ - long long tt; /* total time in this entry */ - long long it; /* inline time in this entry (not in subcalls) */ + _PyTime_t tt; /* total time in this entry */ + _PyTime_t it; /* inline time in this entry (not in subcalls) */ long callcount; /* how many times this was called */ long recursivecallcount; /* how many times called recursively */ long recursionLevel; @@ -86,8 +30,8 @@ typedef struct _ProfilerEntry { } ProfilerEntry; typedef struct _ProfilerContext { - long long t0; - long long subt; + _PyTime_t t0; + _PyTime_t subt; struct _ProfilerContext *previous; ProfilerEntry *ctxEntry; } ProfilerContext; @@ -114,41 +58,46 @@ static PyTypeObject PyProfiler_Type; /*** External Timers ***/ -#define DOUBLE_TIMER_PRECISION 4294967296.0 -static PyObject *empty_tuple; - -static long long CallExternalTimer(ProfilerObject *pObj) +static _PyTime_t CallExternalTimer(ProfilerObject *pObj) { - long long result; - PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL); + PyObject *o = _PyObject_CallNoArg(pObj->externalTimer); if (o == NULL) { PyErr_WriteUnraisable(pObj->externalTimer); return 0; } + + _PyTime_t result; + int err; if (pObj->externalTimerUnit > 0.0) { /* interpret the result as an integer that will be scaled in profiler_getstats() */ - result = PyLong_AsLongLong(o); + err = _PyTime_FromNanosecondsObject(&result, o); } else { /* interpret the result as a double measured in seconds. - As the profiler works with long long internally + As the profiler works with _PyTime_t internally we convert it to a large integer */ - double val = PyFloat_AsDouble(o); - /* error handling delayed to the code below */ - result = (long long) (val * DOUBLE_TIMER_PRECISION); + err = _PyTime_FromSecondsObject(&result, o, _PyTime_ROUND_FLOOR); } Py_DECREF(o); - if (PyErr_Occurred()) { + if (err < 0) { PyErr_WriteUnraisable(pObj->externalTimer); return 0; } return result; } -#define CALL_TIMER(pObj) ((pObj)->externalTimer ? \ - CallExternalTimer(pObj) : \ - hpTimer()) +static inline _PyTime_t +call_timer(ProfilerObject *pObj) +{ + if (pObj->externalTimer != NULL) { + return CallExternalTimer(pObj); + } + else { + return _PyTime_GetPerfCounter(); + } +} + /*** ProfilerObject ***/ @@ -332,14 +281,14 @@ initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) if (subentry) ++subentry->recursionLevel; } - self->t0 = CALL_TIMER(pObj); + self->t0 = call_timer(pObj); } static void Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) { - long long tt = CALL_TIMER(pObj) - self->t0; - long long it = tt - self->subt; + _PyTime_t tt = call_timer(pObj) - self->t0; + _PyTime_t it = tt - self->subt; if (self->previous) self->previous->subt += tt; pObj->currentProfilerContext = self->previous; @@ -631,12 +580,14 @@ profiler_getstats(ProfilerObject *pObj, PyObject* noarg) statscollector_t collect; if (pending_exception(pObj)) return NULL; - if (!pObj->externalTimer) - collect.factor = hpTimerUnit(); - else if (pObj->externalTimerUnit > 0.0) + if (!pObj->externalTimer || pObj->externalTimerUnit == 0.0) { + _PyTime_t onesec = _PyTime_FromSeconds(1); + collect.factor = (double)1 / onesec; + } + else { collect.factor = pObj->externalTimerUnit; - else - collect.factor = 1.0 / DOUBLE_TIMER_PRECISION; + } + collect.list = PyList_New(0); if (collect.list == NULL) return NULL; @@ -882,7 +833,6 @@ PyInit__lsprof(void) (PyObject*) &StatsEntryType); PyModule_AddObject(module, "profiler_subentry", (PyObject*) &StatsSubEntryType); - empty_tuple = PyTuple_New(0); initialized = 1; return module; } diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 2b97294e1e8..391ce5e923c 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -1,8 +1,11 @@ +/* pickle accelerator C extensor: _pickle module. + * + * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows + * and as an extension module (Py_BUILD_CORE_MODULE define) on other + * platforms. */ -/* Core extension modules are built-in on some platforms (e.g. Windows). */ -#ifdef Py_BUILD_CORE -#define Py_BUILD_CORE_BUILTIN -#undef Py_BUILD_CORE +#if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE) +# error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined" #endif #include "Python.h" @@ -1116,6 +1119,8 @@ _Pickler_New(void) Py_DECREF(self); return NULL; } + + PyObject_GC_Track(self); return self; } @@ -1493,6 +1498,7 @@ _Unpickler_New(void) return NULL; } + PyObject_GC_Track(self); return self; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f2ce7fa627e..e75e3466dd3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -557,7 +557,7 @@ SSLError_str(PyOSErrorObject *self) static PyType_Slot sslerror_type_slots[] = { {Py_tp_base, NULL}, /* Filled out in module init as it's not a constant */ - {Py_tp_doc, SSLError_doc}, + {Py_tp_doc, (void*)SSLError_doc}, {Py_tp_str, SSLError_str}, {0, 0}, }; @@ -5400,6 +5400,68 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) return retval; } +static HCERTSTORE +ssl_collect_certificates(const char *store_name) +{ +/* this function collects the system certificate stores listed in + * system_stores into a collection certificate store for being + * enumerated. The store must be readable to be added to the + * store collection. + */ + + HCERTSTORE hCollectionStore = NULL, hSystemStore = NULL; + static DWORD system_stores[] = { + CERT_SYSTEM_STORE_LOCAL_MACHINE, + CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, + CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, + CERT_SYSTEM_STORE_CURRENT_USER, + CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, + CERT_SYSTEM_STORE_SERVICES, + CERT_SYSTEM_STORE_USERS}; + size_t i, storesAdded; + BOOL result; + + hCollectionStore = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, + (HCRYPTPROV)NULL, 0, NULL); + if (!hCollectionStore) { + return NULL; + } + storesAdded = 0; + for (i = 0; i < sizeof(system_stores) / sizeof(DWORD); i++) { + hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, + (HCRYPTPROV)NULL, + CERT_STORE_READONLY_FLAG | + system_stores[i], store_name); + if (hSystemStore) { + result = CertAddStoreToCollection(hCollectionStore, hSystemStore, + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); + if (result) { + ++storesAdded; + } + } + } + if (storesAdded == 0) { + CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG); + return NULL; + } + + return hCollectionStore; +} + +/* code from Objects/listobject.c */ + +static int +list_contains(PyListObject *a, PyObject *el) +{ + Py_ssize_t i; + int cmp; + + for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) + cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i), + Py_EQ); + return cmp; +} + /*[clinic input] _ssl.enum_certificates store_name: str @@ -5417,7 +5479,7 @@ static PyObject * _ssl_enum_certificates_impl(PyObject *module, const char *store_name) /*[clinic end generated code: output=5134dc8bb3a3c893 input=915f60d70461ea4e]*/ { - HCERTSTORE hStore = NULL; + HCERTSTORE hCollectionStore = NULL; PCCERT_CONTEXT pCertCtx = NULL; PyObject *keyusage = NULL, *cert = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; @@ -5426,15 +5488,13 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) if (result == NULL) { return NULL; } - hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, (HCRYPTPROV)NULL, - CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, - store_name); - if (hStore == NULL) { + hCollectionStore = ssl_collect_certificates(store_name); + if (hCollectionStore == NULL) { Py_DECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); } - while (pCertCtx = CertEnumCertificatesInStore(hStore, pCertCtx)) { + while (pCertCtx = CertEnumCertificatesInStore(hCollectionStore, pCertCtx)) { cert = PyBytes_FromStringAndSize((const char*)pCertCtx->pbCertEncoded, pCertCtx->cbCertEncoded); if (!cert) { @@ -5464,9 +5524,11 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) enc = NULL; PyTuple_SET_ITEM(tup, 2, keyusage); keyusage = NULL; - if (PyList_Append(result, tup) < 0) { - Py_CLEAR(result); - break; + if (!list_contains((PyListObject*)result, tup)) { + if (PyList_Append(result, tup) < 0) { + Py_CLEAR(result); + break; + } } Py_CLEAR(tup); } @@ -5481,11 +5543,15 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) Py_XDECREF(keyusage); Py_XDECREF(tup); - if (!CertCloseStore(hStore, 0)) { + /* CERT_CLOSE_STORE_FORCE_FLAG forces freeing of memory for all contexts + associated with the store, in this case our collection store and the + associated system stores. */ + if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG)) { /* This error case might shadow another exception.*/ Py_XDECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); } + return result; } @@ -5505,7 +5571,7 @@ static PyObject * _ssl_enum_crls_impl(PyObject *module, const char *store_name) /*[clinic end generated code: output=bce467f60ccd03b6 input=a1f1d7629f1c5d3d]*/ { - HCERTSTORE hStore = NULL; + HCERTSTORE hCollectionStore = NULL; PCCRL_CONTEXT pCrlCtx = NULL; PyObject *crl = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; @@ -5514,15 +5580,13 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) if (result == NULL) { return NULL; } - hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, (HCRYPTPROV)NULL, - CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, - store_name); - if (hStore == NULL) { + hCollectionStore = ssl_collect_certificates(store_name); + if (hCollectionStore == NULL) { Py_DECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); } - while (pCrlCtx = CertEnumCRLsInStore(hStore, pCrlCtx)) { + while (pCrlCtx = CertEnumCRLsInStore(hCollectionStore, pCrlCtx)) { crl = PyBytes_FromStringAndSize((const char*)pCrlCtx->pbCrlEncoded, pCrlCtx->cbCrlEncoded); if (!crl) { @@ -5542,9 +5606,11 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) PyTuple_SET_ITEM(tup, 1, enc); enc = NULL; - if (PyList_Append(result, tup) < 0) { - Py_CLEAR(result); - break; + if (!list_contains((PyListObject*)result, tup)) { + if (PyList_Append(result, tup) < 0) { + Py_CLEAR(result); + break; + } } Py_CLEAR(tup); } @@ -5558,7 +5624,10 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) Py_XDECREF(enc); Py_XDECREF(tup); - if (!CertCloseStore(hStore, 0)) { + /* CERT_CLOSE_STORE_FORCE_FLAG forces freeing of memory for all contexts + associated with the store, in this case our collection store and the + associated system stores. */ + if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG)) { /* This error case might shadow another exception.*/ Py_XDECREF(result); return PyErr_SetFromWindowsErr(GetLastError()); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 350ef771630..c52e3499638 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5,6 +5,11 @@ * standard Python regression test, via Lib/test/test_capi.py. */ +/* The Visual Studio projects builds _testcapi with Py_BUILD_CORE_MODULE + define, but we only want to test the public C API, not the internal + C API. */ +#undef Py_BUILD_CORE_MODULE + #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -2335,6 +2340,71 @@ get_timezone_utc_capi(PyObject* self, PyObject *args) { } } +static PyObject * +get_date_fromtimestamp(PyObject* self, PyObject *args) +{ + PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; + int macro = 0; + + if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { + return NULL; + } + + // Construct the argument tuple + if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { + return NULL; + } + + // Pass along to the API function + if (macro) { + rv = PyDate_FromTimestamp(tsargs); + } + else { + rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs + ); + } + + Py_DECREF(tsargs); + return rv; +} + +static PyObject * +get_datetime_fromtimestamp(PyObject* self, PyObject *args) +{ + int macro = 0; + int usetz = 0; + PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; + if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { + return NULL; + } + + // Construct the argument tuple + if (usetz) { + tsargs = PyTuple_Pack(2, ts, tzinfo); + } + else { + tsargs = PyTuple_Pack(1, ts); + } + + if (tsargs == NULL) { + return NULL; + } + + // Pass along to the API function + if (macro) { + rv = PyDateTime_FromTimestamp(tsargs); + } + else { + rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL + ); + } + + Py_DECREF(tsargs); + return rv; +} + /* test_thread_state spawns a thread of its own, and that thread releases * `thread_done` when it's finished. The driver code has to know when the @@ -4184,6 +4254,10 @@ pymem_buffer_overflow(PyObject *self, PyObject *args) /* Deliberate buffer overflow to check that PyMem_Free() detects the overflow when debug hooks are installed. */ buffer = PyMem_Malloc(16); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } buffer[16] = 'x'; PyMem_Free(buffer); @@ -4232,6 +4306,59 @@ test_pymem_getallocatorsname(PyObject *self, PyObject *args) } +static PyObject* +pyobject_is_freed(PyObject *self, PyObject *op) +{ + int res = _PyObject_IsFreed(op); + return PyBool_FromLong(res); +} + + +static PyObject* +pyobject_uninitialized(PyObject *self, PyObject *args) +{ + PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); + if (op == NULL) { + return NULL; + } + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_REFCNT(op) = 1; + /* object fields like ob_type are uninitialized! */ + return op; +} + + +static PyObject* +pyobject_forbidden_bytes(PyObject *self, PyObject *args) +{ + /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ + PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); + if (op == NULL) { + return NULL; + } + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_REFCNT(op) = 1; + /* ob_type field is after the memory block: part of "forbidden bytes" + when using debug hooks on memory allocatrs! */ + return op; +} + + +static PyObject* +pyobject_freed(PyObject *self, PyObject *args) +{ + PyObject *op = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); + if (op == NULL) { + return NULL; + } + Py_TYPE(op)->tp_dealloc(op); + /* Reset reference count to avoid early crash in ceval or GC */ + Py_REFCNT(op) = 1; + /* object memory is freed! */ + return op; +} + + static PyObject* pyobject_malloc_without_gil(PyObject *self, PyObject *args) { @@ -4674,31 +4801,6 @@ decode_locale_ex(PyObject *self, PyObject *args) } -static PyObject * -get_global_config(PyObject *self, PyObject *Py_UNUSED(args)) -{ - return _Py_GetGlobalVariablesAsDict(); -} - - -static PyObject * -get_core_config(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyCoreConfig *config = _PyInterpreterState_GetCoreConfig(interp); - return _PyCoreConfig_AsDict(config); -} - - -static PyObject * -get_main_config(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyMainInterpreterConfig *config = _PyInterpreterState_GetMainConfig(interp); - return _PyMainInterpreterConfig_AsDict(config); -} - - #ifdef Py_REF_DEBUG static PyObject * negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) @@ -4732,7 +4834,9 @@ static PyMethodDef TestMethods[] = { {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS}, {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, - {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, + {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, + {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, + {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, {"test_list_api", test_list_api, METH_NOARGS}, {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, @@ -4921,6 +5025,10 @@ static PyMethodDef TestMethods[] = { {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, + {"pyobject_is_freed", (PyCFunction)(void(*)(void))pyobject_is_freed, METH_O}, + {"pyobject_uninitialized", pyobject_uninitialized, METH_NOARGS}, + {"pyobject_forbidden_bytes", pyobject_forbidden_bytes, METH_NOARGS}, + {"pyobject_freed", pyobject_freed, METH_NOARGS}, {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, @@ -4942,9 +5050,6 @@ static PyMethodDef TestMethods[] = { {"bad_get", (PyCFunction)(void(*)(void))bad_get, METH_FASTCALL}, {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, - {"get_global_config", get_global_config, METH_NOARGS}, - {"get_core_config", get_core_config, METH_NOARGS}, - {"get_main_config", get_main_config, METH_NOARGS}, #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, #endif diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c new file mode 100644 index 00000000000..3a43ec16850 --- /dev/null +++ b/Modules/_testinternalcapi.c @@ -0,0 +1,45 @@ +/* + * C Extension module to test Python internal C APIs (Include/internal). + */ + +#if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE) +# error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined" +#endif + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "pycore_coreconfig.h" + + +static PyObject * +get_configs(PyObject *self, PyObject *Py_UNUSED(args)) +{ + return _Py_GetConfigsAsDict(); +} + + +static PyMethodDef TestMethods[] = { + {"get_configs", get_configs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef _testcapimodule = { + PyModuleDef_HEAD_INIT, + "_testinternalcapi", + NULL, + -1, + TestMethods, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__testinternalcapi(void) +{ + return PyModule_Create(&_testcapimodule); +} diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 73babaf9ca8..3c02d8dd514 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -994,7 +994,7 @@ t_bootstrap(void *boot_raw) tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); - _PyThreadState_Init(tstate); + _PyThreadState_Init(&_PyRuntime, tstate); PyEval_AcquireThread(tstate); tstate->interp->num_threads++; res = PyObject_Call(boot->func, boot->args, boot->keyw); diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index a96924c9c6e..613a95b0897 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -617,7 +617,6 @@ Tkapp_New(const char *screenName, const char *className, v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type); if (v == NULL) return NULL; - Py_INCREF(Tkapp_Type); v->interp = Tcl_CreateInterp(); v->wantobjects = wantobjects; @@ -802,7 +801,6 @@ newPyTclObject(Tcl_Obj *arg) self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type); if (self == NULL) return NULL; - Py_INCREF(PyTclObject_Type); Tcl_IncrRefCount(arg); self->value = arg; self->string = NULL; @@ -2722,7 +2720,6 @@ Tktt_New(PyObject *func) v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type); if (v == NULL) return NULL; - Py_INCREF(Tktt_Type); Py_INCREF(func); v->token = NULL; diff --git a/Modules/_winapi.c b/Modules/_winapi.c index e7b221d888e..2eb708e9073 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -752,12 +752,12 @@ gethandle(PyObject* obj, const char* name) return ret; } -static PyObject* +static wchar_t * getenvironment(PyObject* environment) { Py_ssize_t i, envsize, totalsize; - Py_UCS4 *buffer = NULL, *p, *end; - PyObject *keys, *values, *res; + wchar_t *buffer = NULL, *p, *end; + PyObject *keys, *values; /* convert environment dictionary to windows environment string */ if (! PyMapping_Check(environment)) { @@ -775,8 +775,8 @@ getenvironment(PyObject* environment) goto error; } - envsize = PySequence_Fast_GET_SIZE(keys); - if (PySequence_Fast_GET_SIZE(values) != envsize) { + envsize = PyList_GET_SIZE(keys); + if (PyList_GET_SIZE(values) != envsize) { PyErr_SetString(PyExc_RuntimeError, "environment changed size during iteration"); goto error; @@ -784,8 +784,9 @@ getenvironment(PyObject* environment) totalsize = 1; /* trailing null character */ for (i = 0; i < envsize; i++) { - PyObject* key = PySequence_Fast_GET_ITEM(keys, i); - PyObject* value = PySequence_Fast_GET_ITEM(values, i); + PyObject* key = PyList_GET_ITEM(keys, i); + PyObject* value = PyList_GET_ITEM(values, i); + Py_ssize_t size; if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, @@ -806,19 +807,25 @@ getenvironment(PyObject* environment) PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); goto error; } - if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(key) - 1) { + + size = PyUnicode_AsWideChar(key, NULL, 0); + assert(size > 1); + if (totalsize > PY_SSIZE_T_MAX - size) { PyErr_SetString(PyExc_OverflowError, "environment too long"); goto error; } - totalsize += PyUnicode_GET_LENGTH(key) + 1; /* +1 for '=' */ - if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(value) - 1) { + totalsize += size; /* including '=' */ + + size = PyUnicode_AsWideChar(value, NULL, 0); + assert(size > 0); + if (totalsize > PY_SSIZE_T_MAX - size) { PyErr_SetString(PyExc_OverflowError, "environment too long"); goto error; } - totalsize += PyUnicode_GET_LENGTH(value) + 1; /* +1 for '\0' */ + totalsize += size; /* including trailing '\0' */ } - buffer = PyMem_NEW(Py_UCS4, totalsize); + buffer = PyMem_NEW(wchar_t, totalsize); if (! buffer) { PyErr_NoMemory(); goto error; @@ -827,34 +834,25 @@ getenvironment(PyObject* environment) end = buffer + totalsize; for (i = 0; i < envsize; i++) { - PyObject* key = PySequence_Fast_GET_ITEM(keys, i); - PyObject* value = PySequence_Fast_GET_ITEM(values, i); - if (!PyUnicode_AsUCS4(key, p, end - p, 0)) - goto error; - p += PyUnicode_GET_LENGTH(key); - *p++ = '='; - if (!PyUnicode_AsUCS4(value, p, end - p, 0)) - goto error; - p += PyUnicode_GET_LENGTH(value); - *p++ = '\0'; + PyObject* key = PyList_GET_ITEM(keys, i); + PyObject* value = PyList_GET_ITEM(values, i); + Py_ssize_t size = PyUnicode_AsWideChar(key, p, end - p); + assert(1 <= size && size < end - p); + p += size; + *p++ = L'='; + size = PyUnicode_AsWideChar(value, p, end - p); + assert(0 <= size && size < end - p); + p += size + 1; } - /* add trailing null byte */ - *p++ = '\0'; + /* add trailing null character */ + *p++ = L'\0'; assert(p == end); - Py_XDECREF(keys); - Py_XDECREF(values); - - res = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, p - buffer); - PyMem_Free(buffer); - return res; - error: - PyMem_Free(buffer); Py_XDECREF(keys); Py_XDECREF(values); - return NULL; + return buffer; } static LPHANDLE @@ -1053,8 +1051,7 @@ _winapi_CreateProcess_impl(PyObject *module, BOOL result; PROCESS_INFORMATION pi; STARTUPINFOEXW si; - PyObject *environment = NULL; - wchar_t *wenvironment; + wchar_t *wenvironment = NULL; wchar_t *command_line_copy = NULL; AttributeList attribute_list = {0}; @@ -1071,20 +1068,11 @@ _winapi_CreateProcess_impl(PyObject *module, goto cleanup; if (env_mapping != Py_None) { - environment = getenvironment(env_mapping); - if (environment == NULL) { - goto cleanup; - } - /* contains embedded null characters */ - wenvironment = PyUnicode_AsUnicode(environment); + wenvironment = getenvironment(env_mapping); if (wenvironment == NULL) { goto cleanup; } } - else { - environment = NULL; - wenvironment = NULL; - } if (getattributelist(startup_info, "lpAttributeList", &attribute_list) < 0) goto cleanup; @@ -1131,7 +1119,7 @@ _winapi_CreateProcess_impl(PyObject *module, cleanup: PyMem_Free(command_line_copy); - Py_XDECREF(environment); + PyMem_Free(wenvironment); freeattributelist(&attribute_list); return ret; diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 1cf43b7ac76..0d8e5f3127d 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1250,7 +1250,7 @@ _channel_finish_closing(struct _channel *chan) { // Do the things that would have been done in _channels_close(). ref->chan = NULL; _channel_free(chan); -}; +} /* "high"-level channel-related functions */ diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index 2ae28ecbe20..b67f3482faf 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -149,40 +149,42 @@ static const struct dbcs_map *mapping_list; writer->pos += 2; \ } while (0) -#define OUTBYTE1(c) \ - do { ((*outbuf)[0]) = (c); } while (0) -#define OUTBYTE2(c) \ - do { ((*outbuf)[1]) = (c); } while (0) -#define OUTBYTE3(c) \ - do { ((*outbuf)[2]) = (c); } while (0) -#define OUTBYTE4(c) \ - do { ((*outbuf)[3]) = (c); } while (0) +#define OUTBYTEI(c, i) \ + do { \ + assert((unsigned char)(c) == (c)); \ + ((*outbuf)[i]) = (c); \ + } while (0) + +#define OUTBYTE1(c) OUTBYTEI(c, 0) +#define OUTBYTE2(c) OUTBYTEI(c, 1) +#define OUTBYTE3(c) OUTBYTEI(c, 2) +#define OUTBYTE4(c) OUTBYTEI(c, 3) #define WRITEBYTE1(c1) \ do { \ REQUIRE_OUTBUF(1); \ - (*outbuf)[0] = (c1); \ + OUTBYTE1(c1); \ } while (0) #define WRITEBYTE2(c1, c2) \ do { \ REQUIRE_OUTBUF(2); \ - (*outbuf)[0] = (c1); \ - (*outbuf)[1] = (c2); \ + OUTBYTE1(c1); \ + OUTBYTE2(c2); \ } while (0) #define WRITEBYTE3(c1, c2, c3) \ do { \ REQUIRE_OUTBUF(3); \ - (*outbuf)[0] = (c1); \ - (*outbuf)[1] = (c2); \ - (*outbuf)[2] = (c3); \ + OUTBYTE1(c1); \ + OUTBYTE2(c2); \ + OUTBYTE3(c3); \ } while (0) #define WRITEBYTE4(c1, c2, c3, c4) \ do { \ REQUIRE_OUTBUF(4); \ - (*outbuf)[0] = (c1); \ - (*outbuf)[1] = (c2); \ - (*outbuf)[2] = (c3); \ - (*outbuf)[3] = (c4); \ + OUTBYTE1(c1); \ + OUTBYTE2(c2); \ + OUTBYTE3(c3); \ + OUTBYTE4(c4); \ } while (0) #define _TRYMAP_ENC(m, assi, val) \ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index d239c802583..0f55480140b 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -635,19 +635,26 @@ exit: static int _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, - PyObject *element_factory); + PyObject *element_factory, + PyObject *comment_factory, + PyObject *pi_factory, + int insert_comments, int insert_pis); static int _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"element_factory", NULL}; + static const char * const _keywords[] = {"element_factory", "comment_factory", "pi_factory", "insert_comments", "insert_pis", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "TreeBuilder", 0}; - PyObject *argsbuf[1]; + PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; PyObject *element_factory = NULL; + PyObject *comment_factory = NULL; + PyObject *pi_factory = NULL; + int insert_comments = 0; + int insert_pis = 0; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); if (!fastargs) { @@ -656,9 +663,76 @@ _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwar if (!noptargs) { goto skip_optional_pos; } - element_factory = fastargs[0]; + if (fastargs[0]) { + element_factory = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } skip_optional_pos: - return_value = _elementtree_TreeBuilder___init___impl((TreeBuilderObject *)self, element_factory); + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + comment_factory = fastargs[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + pi_factory = fastargs[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + insert_comments = PyObject_IsTrue(fastargs[3]); + if (insert_comments < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + insert_pis = PyObject_IsTrue(fastargs[4]); + if (insert_pis < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = _elementtree_TreeBuilder___init___impl((TreeBuilderObject *)self, element_factory, comment_factory, pi_factory, insert_comments, insert_pis); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree__set_factories__doc__, +"_set_factories($module, comment_factory, pi_factory, /)\n" +"--\n" +"\n" +"Change the factories used to create comments and processing instructions.\n" +"\n" +"For internal use only."); + +#define _ELEMENTTREE__SET_FACTORIES_METHODDEF \ + {"_set_factories", (PyCFunction)(void(*)(void))_elementtree__set_factories, METH_FASTCALL, _elementtree__set_factories__doc__}, + +static PyObject * +_elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, + PyObject *pi_factory); + +static PyObject * +_elementtree__set_factories(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *comment_factory; + PyObject *pi_factory; + + if (!_PyArg_CheckPositional("_set_factories", nargs, 2, 2)) { + goto exit; + } + comment_factory = args[0]; + pi_factory = args[1]; + return_value = _elementtree__set_factories_impl(module, comment_factory, pi_factory); exit: return return_value; @@ -680,6 +754,48 @@ PyDoc_STRVAR(_elementtree_TreeBuilder_end__doc__, #define _ELEMENTTREE_TREEBUILDER_END_METHODDEF \ {"end", (PyCFunction)_elementtree_TreeBuilder_end, METH_O, _elementtree_TreeBuilder_end__doc__}, +PyDoc_STRVAR(_elementtree_TreeBuilder_comment__doc__, +"comment($self, text, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF \ + {"comment", (PyCFunction)_elementtree_TreeBuilder_comment, METH_O, _elementtree_TreeBuilder_comment__doc__}, + +PyDoc_STRVAR(_elementtree_TreeBuilder_pi__doc__, +"pi($self, target, text=None, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_PI_METHODDEF \ + {"pi", (PyCFunction)(void(*)(void))_elementtree_TreeBuilder_pi, METH_FASTCALL, _elementtree_TreeBuilder_pi__doc__}, + +static PyObject * +_elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, + PyObject *text); + +static PyObject * +_elementtree_TreeBuilder_pi(TreeBuilderObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *target; + PyObject *text = Py_None; + + if (!_PyArg_CheckPositional("pi", nargs, 1, 2)) { + goto exit; + } + target = args[0]; + if (nargs < 2) { + goto skip_optional; + } + text = args[1]; +skip_optional: + return_value = _elementtree_TreeBuilder_pi_impl(self, target, text); + +exit: + return return_value; +} + PyDoc_STRVAR(_elementtree_TreeBuilder_close__doc__, "close($self, /)\n" "--\n" @@ -853,4 +969,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=440b5d90a4b86590 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=386a68425d072b5c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 55f2cbb91a0..43f8ba6b4e6 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7961,6 +7961,94 @@ exit: #endif /* defined(HAVE_GETRANDOM_SYSCALL) */ +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__add_dll_directory__doc__, +"_add_dll_directory($module, /, path)\n" +"--\n" +"\n" +"Add a path to the DLL search path.\n" +"\n" +"This search path is used when resolving dependencies for imported\n" +"extension modules (the module itself is resolved through sys.path),\n" +"and also by ctypes.\n" +"\n" +"Returns an opaque value that may be passed to os.remove_dll_directory\n" +"to remove this directory from the search path."); + +#define OS__ADD_DLL_DIRECTORY_METHODDEF \ + {"_add_dll_directory", (PyCFunction)(void(*)(void))os__add_dll_directory, METH_FASTCALL|METH_KEYWORDS, os__add_dll_directory__doc__}, + +static PyObject * +os__add_dll_directory_impl(PyObject *module, path_t *path); + +static PyObject * +os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_add_dll_directory", 0}; + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__add_dll_directory_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__remove_dll_directory__doc__, +"_remove_dll_directory($module, /, cookie)\n" +"--\n" +"\n" +"Removes a path from the DLL search path.\n" +"\n" +"The parameter is an opaque value that was returned from\n" +"os.add_dll_directory. You can only remove directories that you added\n" +"yourself."); + +#define OS__REMOVE_DLL_DIRECTORY_METHODDEF \ + {"_remove_dll_directory", (PyCFunction)(void(*)(void))os__remove_dll_directory, METH_FASTCALL|METH_KEYWORDS, os__remove_dll_directory__doc__}, + +static PyObject * +os__remove_dll_directory_impl(PyObject *module, PyObject *cookie); + +static PyObject * +os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"cookie", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_remove_dll_directory", 0}; + PyObject *argsbuf[1]; + PyObject *cookie; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + cookie = args[0]; + return_value = os__remove_dll_directory_impl(module, cookie); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + #ifndef OS_TTYNAME_METHODDEF #define OS_TTYNAME_METHODDEF #endif /* !defined(OS_TTYNAME_METHODDEF) */ @@ -8480,4 +8568,12 @@ exit: #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=1a9c62f5841221ae input=a9049054013a1b77]*/ + +#ifndef OS__ADD_DLL_DIRECTORY_METHODDEF + #define OS__ADD_DLL_DIRECTORY_METHODDEF +#endif /* !defined(OS__ADD_DLL_DIRECTORY_METHODDEF) */ + +#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF + #define OS__REMOVE_DLL_DIRECTORY_METHODDEF +#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ +/*[clinic end generated code: output=ab36ec0376a422ae input=a9049054013a1b77]*/ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 30fe18695fe..d45b8660ee6 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1370,7 +1370,8 @@ void _PyFaulthandler_Fini(void) #ifdef HAVE_SIGALTSTACK if (stack.ss_sp != NULL) { /* Fetch the current alt stack */ - stack_t current_stack = {}; + stack_t current_stack; + memset(¤t_stack, 0, sizeof(current_stack)); if (sigaltstack(NULL, ¤t_stack) == 0) { if (current_stack.ss_sp == stack.ss_sp) { /* The current alt stack is the one that we installed. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index fad1356d6b4..be9b73a8446 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -123,14 +123,14 @@ static PyObject *gc_str = NULL; DEBUG_UNCOLLECTABLE | \ DEBUG_SAVEALL -#define GEN_HEAD(n) (&_PyRuntime.gc.generations[n].head) +#define GEN_HEAD(state, n) (&(state)->generations[n].head) void _PyGC_Initialize(struct _gc_runtime_state *state) { state->enabled = 1; /* automatic collection enabled? */ -#define _GEN_HEAD(n) (&state->generations[n].head) +#define _GEN_HEAD(n) GEN_HEAD(state, n) struct gc_generation generations[NUM_GENERATIONS] = { /* PyGC_Head, threshold, count */ {{(uintptr_t)_GEN_HEAD(0), (uintptr_t)_GEN_HEAD(0)}, 700, 0}, @@ -140,7 +140,7 @@ _PyGC_Initialize(struct _gc_runtime_state *state) for (int i = 0; i < NUM_GENERATIONS; i++) { state->generations[i] = generations[i]; }; - state->generation0 = GEN_HEAD(0); + state->generation0 = GEN_HEAD(state, 0); struct gc_generation permanent_generation = { {(uintptr_t)&state->permanent_generation.head, (uintptr_t)&state->permanent_generation.head}, 0, 0 @@ -808,21 +808,22 @@ debug_cycle(const char *msg, PyObject *op) * merged into the old list regardless. */ static void -handle_legacy_finalizers(PyGC_Head *finalizers, PyGC_Head *old) +handle_legacy_finalizers(struct _gc_runtime_state *state, + PyGC_Head *finalizers, PyGC_Head *old) { - PyGC_Head *gc = GC_NEXT(finalizers); - assert(!PyErr_Occurred()); - if (_PyRuntime.gc.garbage == NULL) { - _PyRuntime.gc.garbage = PyList_New(0); - if (_PyRuntime.gc.garbage == NULL) + + PyGC_Head *gc = GC_NEXT(finalizers); + if (state->garbage == NULL) { + state->garbage = PyList_New(0); + if (state->garbage == NULL) Py_FatalError("gc couldn't create gc.garbage list"); } for (; gc != finalizers; gc = GC_NEXT(gc)) { PyObject *op = FROM_GC(gc); - if ((_PyRuntime.gc.debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { - if (PyList_Append(_PyRuntime.gc.garbage, op) < 0) { + if ((state->debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { + if (PyList_Append(state->garbage, op) < 0) { PyErr_Clear(); break; } @@ -904,11 +905,11 @@ check_garbage(PyGC_Head *collectable) * objects may be freed. It is possible I screwed something up here. */ static void -delete_garbage(PyGC_Head *collectable, PyGC_Head *old) +delete_garbage(struct _gc_runtime_state *state, + PyGC_Head *collectable, PyGC_Head *old) { - inquiry clear; - assert(!PyErr_Occurred()); + while (!gc_list_is_empty(collectable)) { PyGC_Head *gc = GC_NEXT(collectable); PyObject *op = FROM_GC(gc); @@ -916,13 +917,14 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old) _PyObject_ASSERT_WITH_MSG(op, Py_REFCNT(op) > 0, "refcount is too small"); - if (_PyRuntime.gc.debug & DEBUG_SAVEALL) { - assert(_PyRuntime.gc.garbage != NULL); - if (PyList_Append(_PyRuntime.gc.garbage, op) < 0) { + if (state->debug & DEBUG_SAVEALL) { + assert(state->garbage != NULL); + if (PyList_Append(state->garbage, op) < 0) { PyErr_Clear(); } } else { + inquiry clear; if ((clear = Py_TYPE(op)->tp_clear) != NULL) { Py_INCREF(op); (void) clear(op); @@ -965,8 +967,8 @@ clear_freelists(void) /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t -collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, - int nofail) +collect(struct _gc_runtime_state *state, int generation, + Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) { int i; Py_ssize_t m = 0; /* # objects collected */ @@ -978,17 +980,15 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, PyGC_Head *gc; _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ - struct gc_generation_stats *stats = &_PyRuntime.gc.generation_stats[generation]; - - if (_PyRuntime.gc.debug & DEBUG_STATS) { + if (state->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); PySys_WriteStderr("gc: objects in each generation:"); for (i = 0; i < NUM_GENERATIONS; i++) PySys_FormatStderr(" %zd", - gc_list_size(GEN_HEAD(i))); + gc_list_size(GEN_HEAD(state, i))); PySys_WriteStderr("\ngc: objects in permanent generation: %zd", - gc_list_size(&_PyRuntime.gc.permanent_generation.head)); + gc_list_size(&state->permanent_generation.head)); t1 = _PyTime_GetMonotonicClock(); PySys_WriteStderr("\n"); @@ -999,19 +999,19 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, /* update collection and allocation counters */ if (generation+1 < NUM_GENERATIONS) - _PyRuntime.gc.generations[generation+1].count += 1; + state->generations[generation+1].count += 1; for (i = 0; i <= generation; i++) - _PyRuntime.gc.generations[i].count = 0; + state->generations[i].count = 0; /* merge younger generations with one we are currently collecting */ for (i = 0; i < generation; i++) { - gc_list_merge(GEN_HEAD(i), GEN_HEAD(generation)); + gc_list_merge(GEN_HEAD(state, i), GEN_HEAD(state, generation)); } /* handy references */ - young = GEN_HEAD(generation); + young = GEN_HEAD(state, generation); if (generation < NUM_GENERATIONS-1) - old = GEN_HEAD(generation+1); + old = GEN_HEAD(state, generation+1); else old = young; @@ -1039,7 +1039,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, /* Move reachable objects to next generation. */ if (young != old) { if (generation == NUM_GENERATIONS - 2) { - _PyRuntime.gc.long_lived_pending += gc_list_size(young); + state->long_lived_pending += gc_list_size(young); } gc_list_merge(young, old); } @@ -1047,8 +1047,8 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, /* We only untrack dicts in full collections, to avoid quadratic dict build-up. See issue #14775. */ untrack_dicts(young); - _PyRuntime.gc.long_lived_pending = 0; - _PyRuntime.gc.long_lived_total = gc_list_size(young); + state->long_lived_pending = 0; + state->long_lived_total = gc_list_size(young); } /* All objects in unreachable are trash, but objects reachable from @@ -1072,7 +1072,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, */ for (gc = GC_NEXT(&unreachable); gc != &unreachable; gc = GC_NEXT(gc)) { m++; - if (_PyRuntime.gc.debug & DEBUG_COLLECTABLE) { + if (state->debug & DEBUG_COLLECTABLE) { debug_cycle("collectable", FROM_GC(gc)); } } @@ -1094,17 +1094,17 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, * the reference cycles to be broken. It may also cause some objects * in finalizers to be freed. */ - delete_garbage(&unreachable, old); + delete_garbage(state, &unreachable, old); } /* Collect statistics on uncollectable objects found and print * debugging information. */ for (gc = GC_NEXT(&finalizers); gc != &finalizers; gc = GC_NEXT(gc)) { n++; - if (_PyRuntime.gc.debug & DEBUG_UNCOLLECTABLE) + if (state->debug & DEBUG_UNCOLLECTABLE) debug_cycle("uncollectable", FROM_GC(gc)); } - if (_PyRuntime.gc.debug & DEBUG_STATS) { + if (state->debug & DEBUG_STATS) { _PyTime_t t2 = _PyTime_GetMonotonicClock(); if (m == 0 && n == 0) @@ -1121,7 +1121,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, * reachable list of garbage. The programmer has to deal with * this if they insist on creating this type of structure. */ - handle_legacy_finalizers(&finalizers, old); + handle_legacy_finalizers(state, &finalizers, old); validate_list(old, 0); /* Clear free list only during the collection of the highest @@ -1143,16 +1143,21 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, } /* Update stats */ - if (n_collected) + if (n_collected) { *n_collected = m; - if (n_uncollectable) + } + if (n_uncollectable) { *n_uncollectable = n; + } + + struct gc_generation_stats *stats = &state->generation_stats[generation]; stats->collections++; stats->collected += m; stats->uncollectable += n; - if (PyDTrace_GC_DONE_ENABLED()) + if (PyDTrace_GC_DONE_ENABLED()) { PyDTrace_GC_DONE(n+m); + } assert(!PyErr_Occurred()); return n+m; @@ -1162,19 +1167,21 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, * is starting or stopping */ static void -invoke_gc_callback(const char *phase, int generation, - Py_ssize_t collected, Py_ssize_t uncollectable) +invoke_gc_callback(struct _gc_runtime_state *state, const char *phase, + int generation, Py_ssize_t collected, + Py_ssize_t uncollectable) { - Py_ssize_t i; - PyObject *info = NULL; - assert(!PyErr_Occurred()); + /* we may get called very early */ - if (_PyRuntime.gc.callbacks == NULL) + if (state->callbacks == NULL) { return; + } + /* The local variable cannot be rebound, check it for sanity */ - assert(PyList_CheckExact(_PyRuntime.gc.callbacks)); - if (PyList_GET_SIZE(_PyRuntime.gc.callbacks) != 0) { + assert(PyList_CheckExact(state->callbacks)); + PyObject *info = NULL; + if (PyList_GET_SIZE(state->callbacks) != 0) { info = Py_BuildValue("{sisnsn}", "generation", generation, "collected", collected, @@ -1184,8 +1191,8 @@ invoke_gc_callback(const char *phase, int generation, return; } } - for (i=0; icallbacks); i++) { + PyObject *r, *cb = PyList_GET_ITEM(state->callbacks, i); Py_INCREF(cb); /* make sure cb doesn't go away */ r = PyObject_CallFunction(cb, "sO", phase, info); if (r == NULL) { @@ -1204,36 +1211,34 @@ invoke_gc_callback(const char *phase, int generation, * progress callbacks. */ static Py_ssize_t -collect_with_callback(int generation) +collect_with_callback(struct _gc_runtime_state *state, int generation) { - Py_ssize_t result, collected, uncollectable; assert(!PyErr_Occurred()); - invoke_gc_callback("start", generation, 0, 0); - result = collect(generation, &collected, &uncollectable, 0); - invoke_gc_callback("stop", generation, collected, uncollectable); + Py_ssize_t result, collected, uncollectable; + invoke_gc_callback(state, "start", generation, 0, 0); + result = collect(state, generation, &collected, &uncollectable, 0); + invoke_gc_callback(state, "stop", generation, collected, uncollectable); assert(!PyErr_Occurred()); return result; } static Py_ssize_t -collect_generations(void) +collect_generations(struct _gc_runtime_state *state) { - int i; - Py_ssize_t n = 0; - /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ - for (i = NUM_GENERATIONS-1; i >= 0; i--) { - if (_PyRuntime.gc.generations[i].count > _PyRuntime.gc.generations[i].threshold) { + Py_ssize_t n = 0; + for (int i = NUM_GENERATIONS-1; i >= 0; i--) { + if (state->generations[i].count > state->generations[i].threshold) { /* Avoid quadratic performance degradation in number of tracked objects. See comments at the beginning of this file, and issue #4074. */ if (i == NUM_GENERATIONS - 1 - && _PyRuntime.gc.long_lived_pending < _PyRuntime.gc.long_lived_total / 4) + && state->long_lived_pending < state->long_lived_total / 4) continue; - n = collect_with_callback(i); + n = collect_with_callback(state, i); break; } } @@ -1301,21 +1306,23 @@ static Py_ssize_t gc_collect_impl(PyObject *module, int generation) /*[clinic end generated code: output=b697e633043233c7 input=40720128b682d879]*/ { - Py_ssize_t n; if (generation < 0 || generation >= NUM_GENERATIONS) { PyErr_SetString(PyExc_ValueError, "invalid generation"); return -1; } - if (_PyRuntime.gc.collecting) - n = 0; /* already collecting, don't do anything */ - else { - _PyRuntime.gc.collecting = 1; - n = collect_with_callback(generation); - _PyRuntime.gc.collecting = 0; + struct _gc_runtime_state *state = &_PyRuntime.gc; + Py_ssize_t n; + if (state->collecting) { + /* already collecting, don't do anything */ + n = 0; + } + else { + state->collecting = 1; + n = collect_with_callback(state, generation); + state->collecting = 0; } - return n; } @@ -1366,19 +1373,18 @@ PyDoc_STRVAR(gc_set_thresh__doc__, "collection.\n"); static PyObject * -gc_set_thresh(PyObject *self, PyObject *args) +gc_set_threshold(PyObject *self, PyObject *args) { - int i; + struct _gc_runtime_state *state = &_PyRuntime.gc; if (!PyArg_ParseTuple(args, "i|ii:set_threshold", - &_PyRuntime.gc.generations[0].threshold, - &_PyRuntime.gc.generations[1].threshold, - &_PyRuntime.gc.generations[2].threshold)) + &state->generations[0].threshold, + &state->generations[1].threshold, + &state->generations[2].threshold)) return NULL; - for (i = 2; i < NUM_GENERATIONS; i++) { + for (int i = 3; i < NUM_GENERATIONS; i++) { /* generations higher than 2 get the same threshold */ - _PyRuntime.gc.generations[i].threshold = _PyRuntime.gc.generations[2].threshold; + state->generations[i].threshold = state->generations[2].threshold; } - Py_RETURN_NONE; } @@ -1392,10 +1398,11 @@ static PyObject * gc_get_threshold_impl(PyObject *module) /*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ { + struct _gc_runtime_state *state = &_PyRuntime.gc; return Py_BuildValue("(iii)", - _PyRuntime.gc.generations[0].threshold, - _PyRuntime.gc.generations[1].threshold, - _PyRuntime.gc.generations[2].threshold); + state->generations[0].threshold, + state->generations[1].threshold, + state->generations[2].threshold); } /*[clinic input] @@ -1408,10 +1415,11 @@ static PyObject * gc_get_count_impl(PyObject *module) /*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ { + struct _gc_runtime_state *state = &_PyRuntime.gc; return Py_BuildValue("(iii)", - _PyRuntime.gc.generations[0].count, - _PyRuntime.gc.generations[1].count, - _PyRuntime.gc.generations[2].count); + state->generations[0].count, + state->generations[1].count, + state->generations[2].count); } static int @@ -1454,8 +1462,9 @@ gc_get_referrers(PyObject *self, PyObject *args) PyObject *result = PyList_New(0); if (!result) return NULL; + struct _gc_runtime_state *state = &_PyRuntime.gc; for (i = 0; i < NUM_GENERATIONS; i++) { - if (!(gc_referrers_for(args, GEN_HEAD(i), result))) { + if (!(gc_referrers_for(args, GEN_HEAD(state, i), result))) { Py_DECREF(result); return NULL; } @@ -1517,6 +1526,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) { int i; PyObject* result; + struct _gc_runtime_state *state = &_PyRuntime.gc; result = PyList_New(0); if (result == NULL) { @@ -1524,7 +1534,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) } /* If generation is passed, we extract only that generation */ - if (generation != -1) { + if (generation != -1) { if (generation >= NUM_GENERATIONS) { PyErr_Format(PyExc_ValueError, "generation parameter must be less than the number of " @@ -1539,7 +1549,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) goto error; } - if (append_objects(result, GEN_HEAD(generation))) { + if (append_objects(result, GEN_HEAD(state, generation))) { goto error; } @@ -1548,7 +1558,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) /* If generation is not passed or None, get all objects from all generations */ for (i = 0; i < NUM_GENERATIONS; i++) { - if (append_objects(result, GEN_HEAD(i))) { + if (append_objects(result, GEN_HEAD(state, i))) { goto error; } } @@ -1570,16 +1580,16 @@ gc_get_stats_impl(PyObject *module) /*[clinic end generated code: output=a8ab1d8a5d26f3ab input=1ef4ed9d17b1a470]*/ { int i; - PyObject *result; struct gc_generation_stats stats[NUM_GENERATIONS], *st; /* To get consistent values despite allocations while constructing the result list, we use a snapshot of the running stats. */ + struct _gc_runtime_state *state = &_PyRuntime.gc; for (i = 0; i < NUM_GENERATIONS; i++) { - stats[i] = _PyRuntime.gc.generation_stats[i]; + stats[i] = state->generation_stats[i]; } - result = PyList_New(0); + PyObject *result = PyList_New(0); if (result == NULL) return NULL; @@ -1646,9 +1656,10 @@ static PyObject * gc_freeze_impl(PyObject *module) /*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ { + struct _gc_runtime_state *state = &_PyRuntime.gc; for (int i = 0; i < NUM_GENERATIONS; ++i) { - gc_list_merge(GEN_HEAD(i), &_PyRuntime.gc.permanent_generation.head); - _PyRuntime.gc.generations[i].count = 0; + gc_list_merge(GEN_HEAD(state, i), &state->permanent_generation.head); + state->generations[i].count = 0; } Py_RETURN_NONE; } @@ -1665,7 +1676,8 @@ static PyObject * gc_unfreeze_impl(PyObject *module) /*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ { - gc_list_merge(&_PyRuntime.gc.permanent_generation.head, GEN_HEAD(NUM_GENERATIONS-1)); + struct _gc_runtime_state *state = &_PyRuntime.gc; + gc_list_merge(&state->permanent_generation.head, GEN_HEAD(state, NUM_GENERATIONS-1)); Py_RETURN_NONE; } @@ -1711,7 +1723,7 @@ static PyMethodDef GcMethods[] = { GC_SET_DEBUG_METHODDEF GC_GET_DEBUG_METHODDEF GC_GET_COUNT_METHODDEF - {"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__}, + {"set_threshold", gc_set_threshold, METH_VARARGS, gc_set_thresh__doc__}, GC_GET_THRESHOLD_METHODDEF GC_COLLECT_METHODDEF GC_GET_OBJECTS_METHODDEF @@ -1746,25 +1758,27 @@ PyInit_gc(void) m = PyModule_Create(&gcmodule); - if (m == NULL) + if (m == NULL) { return NULL; + } - if (_PyRuntime.gc.garbage == NULL) { - _PyRuntime.gc.garbage = PyList_New(0); - if (_PyRuntime.gc.garbage == NULL) + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (state->garbage == NULL) { + state->garbage = PyList_New(0); + if (state->garbage == NULL) return NULL; } - Py_INCREF(_PyRuntime.gc.garbage); - if (PyModule_AddObject(m, "garbage", _PyRuntime.gc.garbage) < 0) + Py_INCREF(state->garbage); + if (PyModule_AddObject(m, "garbage", state->garbage) < 0) return NULL; - if (_PyRuntime.gc.callbacks == NULL) { - _PyRuntime.gc.callbacks = PyList_New(0); - if (_PyRuntime.gc.callbacks == NULL) + if (state->callbacks == NULL) { + state->callbacks = PyList_New(0); + if (state->callbacks == NULL) return NULL; } - Py_INCREF(_PyRuntime.gc.callbacks); - if (PyModule_AddObject(m, "callbacks", _PyRuntime.gc.callbacks) < 0) + Py_INCREF(state->callbacks); + if (PyModule_AddObject(m, "callbacks", state->callbacks) < 0) return NULL; #define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL @@ -1781,17 +1795,23 @@ PyInit_gc(void) Py_ssize_t PyGC_Collect(void) { - Py_ssize_t n; + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (!state->enabled) { + return 0; + } - if (_PyRuntime.gc.collecting) - n = 0; /* already collecting, don't do anything */ + Py_ssize_t n; + if (state->collecting) { + /* already collecting, don't do anything */ + n = 0; + } else { PyObject *exc, *value, *tb; - _PyRuntime.gc.collecting = 1; + state->collecting = 1; PyErr_Fetch(&exc, &value, &tb); - n = collect_with_callback(NUM_GENERATIONS - 1); + n = collect_with_callback(state, NUM_GENERATIONS - 1); PyErr_Restore(exc, value, tb); - _PyRuntime.gc.collecting = 0; + state->collecting = 0; } return n; @@ -1800,41 +1820,42 @@ PyGC_Collect(void) Py_ssize_t _PyGC_CollectIfEnabled(void) { - if (!_PyRuntime.gc.enabled) - return 0; - return PyGC_Collect(); } Py_ssize_t _PyGC_CollectNoFail(void) { + assert(!PyErr_Occurred()); + + struct _gc_runtime_state *state = &_PyRuntime.gc; Py_ssize_t n; - assert(!PyErr_Occurred()); /* Ideally, this function is only called on interpreter shutdown, and therefore not recursively. Unfortunately, when there are daemon threads, a daemon thread can start a cyclic garbage collection during interpreter shutdown (and then never finish it). See http://bugs.python.org/issue8713#msg195178 for an example. */ - if (_PyRuntime.gc.collecting) + if (state->collecting) { n = 0; + } else { - _PyRuntime.gc.collecting = 1; - n = collect(NUM_GENERATIONS - 1, NULL, NULL, 1); - _PyRuntime.gc.collecting = 0; + state->collecting = 1; + n = collect(state, NUM_GENERATIONS - 1, NULL, NULL, 1); + state->collecting = 0; } return n; } void -_PyGC_DumpShutdownStats(void) +_PyGC_DumpShutdownStats(_PyRuntimeState *runtime) { - if (!(_PyRuntime.gc.debug & DEBUG_SAVEALL) - && _PyRuntime.gc.garbage != NULL && PyList_GET_SIZE(_PyRuntime.gc.garbage) > 0) { + struct _gc_runtime_state *state = &runtime->gc; + if (!(state->debug & DEBUG_SAVEALL) + && state->garbage != NULL && PyList_GET_SIZE(state->garbage) > 0) { const char *message; - if (_PyRuntime.gc.debug & DEBUG_UNCOLLECTABLE) + if (state->debug & DEBUG_UNCOLLECTABLE) message = "gc: %zd uncollectable objects at " \ "shutdown"; else @@ -1845,13 +1866,13 @@ _PyGC_DumpShutdownStats(void) already. */ if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, "gc", NULL, message, - PyList_GET_SIZE(_PyRuntime.gc.garbage))) + PyList_GET_SIZE(state->garbage))) PyErr_WriteUnraisable(NULL); - if (_PyRuntime.gc.debug & DEBUG_UNCOLLECTABLE) { + if (state->debug & DEBUG_UNCOLLECTABLE) { PyObject *repr = NULL, *bytes = NULL; - repr = PyObject_Repr(_PyRuntime.gc.garbage); + repr = PyObject_Repr(state->garbage); if (!repr || !(bytes = PyUnicode_EncodeFSDefault(repr))) - PyErr_WriteUnraisable(_PyRuntime.gc.garbage); + PyErr_WriteUnraisable(state->garbage); else { PySys_WriteStderr( " %s\n", @@ -1865,9 +1886,11 @@ _PyGC_DumpShutdownStats(void) } void -_PyGC_Fini(void) +_PyGC_Fini(_PyRuntimeState *runtime) { - Py_CLEAR(_PyRuntime.gc.callbacks); + struct _gc_runtime_state *state = &runtime->gc; + Py_CLEAR(state->garbage); + Py_CLEAR(state->callbacks); } /* for debugging */ @@ -1907,6 +1930,7 @@ PyObject_GC_UnTrack(void *op_raw) static PyObject * _PyObject_GC_Alloc(int use_calloc, size_t basicsize) { + struct _gc_runtime_state *state = &_PyRuntime.gc; PyObject *op; PyGC_Head *g; size_t size; @@ -1922,15 +1946,15 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) assert(((uintptr_t)g & 3) == 0); // g must be aligned 4bytes boundary g->_gc_next = 0; g->_gc_prev = 0; - _PyRuntime.gc.generations[0].count++; /* number of allocated GC objects */ - if (_PyRuntime.gc.generations[0].count > _PyRuntime.gc.generations[0].threshold && - _PyRuntime.gc.enabled && - _PyRuntime.gc.generations[0].threshold && - !_PyRuntime.gc.collecting && + state->generations[0].count++; /* number of allocated GC objects */ + if (state->generations[0].count > state->generations[0].threshold && + state->enabled && + state->generations[0].threshold && + !state->collecting && !PyErr_Occurred()) { - _PyRuntime.gc.collecting = 1; - collect_generations(); - _PyRuntime.gc.collecting = 0; + state->collecting = 1; + collect_generations(state); + state->collecting = 0; } op = FROM_GC(g); return op; @@ -1999,8 +2023,9 @@ PyObject_GC_Del(void *op) if (_PyObject_GC_IS_TRACKED(op)) { gc_list_remove(g); } - if (_PyRuntime.gc.generations[0].count > 0) { - _PyRuntime.gc.generations[0].count--; + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (state->generations[0].count > 0) { + state->generations[0].count--; } PyObject_FREE(g); } diff --git a/Modules/getpath.c b/Modules/getpath.c index dd188c61289..3991ad719c1 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -114,10 +114,10 @@ extern "C" { #define DECODE_LOCALE_ERR(NAME, LEN) \ ((LEN) == (size_t)-2) \ - ? _Py_INIT_USER_ERR("cannot decode " NAME) \ + ? _Py_INIT_ERR("cannot decode " NAME) \ : _Py_INIT_NO_MEMORY() -#define PATHLEN_ERR() _Py_INIT_USER_ERR("path configuration: path too long") +#define PATHLEN_ERR() _Py_INIT_ERR("path configuration: path too long") typedef struct { wchar_t *path_env; /* PATH environment variable */ diff --git a/Modules/hashtable.c b/Modules/hashtable.c index e6f8daf7966..4a36a1e71cd 100644 --- a/Modules/hashtable.c +++ b/Modules/hashtable.c @@ -240,7 +240,7 @@ _Py_hashtable_print_stats(_Py_hashtable_t *ht) } printf("hash table %p: entries=%" PY_FORMAT_SIZE_T "u/%" PY_FORMAT_SIZE_T "u (%.0f%%), ", - ht, ht->entries, ht->num_buckets, load * 100.0); + (void *)ht, ht->entries, ht->num_buckets, load * 100.0); if (nchains) printf("avg_chain_len=%.1f, ", (double)total_chain_len / nchains); printf("max_chain_len=%" PY_FORMAT_SIZE_T "u, %" PY_FORMAT_SIZE_T "u KiB\n", diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 536f7fa6253..103029d251e 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -4089,6 +4089,7 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, lz = (countobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_XDECREF(long_cnt); + Py_DECREF(long_step); return NULL; } lz->cnt = cnt; diff --git a/Modules/main.c b/Modules/main.c index 57cf862a30b..e117ef29e54 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -31,306 +31,10 @@ extern "C" { #endif -/* --- PyMainInterpreter ------------------------------------------ */ - -void -_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config) -{ - Py_CLEAR(config->argv); - Py_CLEAR(config->executable); - Py_CLEAR(config->prefix); - Py_CLEAR(config->base_prefix); - Py_CLEAR(config->exec_prefix); - Py_CLEAR(config->base_exec_prefix); - Py_CLEAR(config->warnoptions); - Py_CLEAR(config->xoptions); - Py_CLEAR(config->module_search_path); - Py_CLEAR(config->pycache_prefix); -} - - -static int -mainconfig_add_xoption(PyObject *opts, const wchar_t *s) -{ - PyObject *name, *value; - - const wchar_t *name_end = wcschr(s, L'='); - if (!name_end) { - name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); - } - else { - name = PyUnicode_FromWideChar(s, name_end - s); - value = PyUnicode_FromWideChar(name_end + 1, -1); - } - if (name == NULL || value == NULL) { - goto error; - } - if (PyDict_SetItem(opts, name, value) < 0) { - goto error; - } - Py_DECREF(name); - Py_DECREF(value); - return 0; - -error: - Py_XDECREF(name); - Py_XDECREF(value); - return -1; -} - - -static PyObject* -mainconfig_create_xoptions_dict(const _PyCoreConfig *config) -{ - Py_ssize_t nxoption = config->xoptions.length; - wchar_t * const * xoptions = config->xoptions.items; - PyObject *dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - - for (Py_ssize_t i=0; i < nxoption; i++) { - const wchar_t *option = xoptions[i]; - if (mainconfig_add_xoption(dict, option) < 0) { - Py_DECREF(dict); - return NULL; - } - } - - return dict; -} - - -static PyObject* -mainconfig_copy_attr(PyObject *obj) -{ - if (PyUnicode_Check(obj)) { - Py_INCREF(obj); - return obj; - } - else if (PyList_Check(obj)) { - return PyList_GetSlice(obj, 0, Py_SIZE(obj)); - } - else if (PyDict_Check(obj)) { - /* The dict type is used for xoptions. Make the assumption that keys - and values are immutables */ - return PyDict_Copy(obj); - } - else { - PyErr_Format(PyExc_TypeError, - "cannot copy config attribute of type %.200s", - Py_TYPE(obj)->tp_name); - return NULL; - } -} - - -int -_PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, - const _PyMainInterpreterConfig *config2) -{ - _PyMainInterpreterConfig_Clear(config); - -#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR -#define COPY_OBJ_ATTR(ATTR) \ - do { \ - if (config2->ATTR != NULL) { \ - config->ATTR = mainconfig_copy_attr(config2->ATTR); \ - if (config->ATTR == NULL) { \ - return -1; \ - } \ - } \ - } while (0) - - COPY_ATTR(install_signal_handlers); - COPY_OBJ_ATTR(argv); - COPY_OBJ_ATTR(executable); - COPY_OBJ_ATTR(prefix); - COPY_OBJ_ATTR(base_prefix); - COPY_OBJ_ATTR(exec_prefix); - COPY_OBJ_ATTR(base_exec_prefix); - COPY_OBJ_ATTR(warnoptions); - COPY_OBJ_ATTR(xoptions); - COPY_OBJ_ATTR(module_search_path); - COPY_OBJ_ATTR(pycache_prefix); -#undef COPY_ATTR -#undef COPY_OBJ_ATTR - return 0; -} - - -PyObject* -_PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config) -{ - PyObject *dict, *obj; - int res; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define SET_ITEM_INT(ATTR) \ - do { \ - obj = PyLong_FromLong(config->ATTR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - res = PyDict_SetItemString(dict, #ATTR, obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) - -#define SET_ITEM_OBJ(ATTR) \ - do { \ - obj = config->ATTR; \ - if (obj == NULL) { \ - obj = Py_None; \ - } \ - res = PyDict_SetItemString(dict, #ATTR, obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) - - SET_ITEM_INT(install_signal_handlers); - SET_ITEM_OBJ(argv); - SET_ITEM_OBJ(executable); - SET_ITEM_OBJ(prefix); - SET_ITEM_OBJ(base_prefix); - SET_ITEM_OBJ(exec_prefix); - SET_ITEM_OBJ(base_exec_prefix); - SET_ITEM_OBJ(warnoptions); - SET_ITEM_OBJ(xoptions); - SET_ITEM_OBJ(module_search_path); - SET_ITEM_OBJ(pycache_prefix); - - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef SET_ITEM_OBJ -} - - -_PyInitError -_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, - const _PyCoreConfig *config) -{ - if (main_config->install_signal_handlers < 0) { - main_config->install_signal_handlers = config->install_signal_handlers; - } - - if (main_config->xoptions == NULL) { - main_config->xoptions = mainconfig_create_xoptions_dict(config); - if (main_config->xoptions == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - -#define COPY_WSTR(ATTR) \ - do { \ - if (main_config->ATTR == NULL && config->ATTR != NULL) { \ - main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \ - if (main_config->ATTR == NULL) { \ - return _Py_INIT_NO_MEMORY(); \ - } \ - } \ - } while (0) -#define COPY_WSTRLIST(ATTR, LIST) \ - do { \ - if (ATTR == NULL) { \ - ATTR = _PyWstrList_AsList(LIST); \ - if (ATTR == NULL) { \ - return _Py_INIT_NO_MEMORY(); \ - } \ - } \ - } while (0) - - COPY_WSTRLIST(main_config->warnoptions, &config->warnoptions); - COPY_WSTRLIST(main_config->argv, &config->argv); - - if (config->_install_importlib) { - COPY_WSTR(executable); - COPY_WSTR(prefix); - COPY_WSTR(base_prefix); - COPY_WSTR(exec_prefix); - COPY_WSTR(base_exec_prefix); - - COPY_WSTRLIST(main_config->module_search_path, - &config->module_search_paths); - - if (config->pycache_prefix != NULL) { - COPY_WSTR(pycache_prefix); - } else { - main_config->pycache_prefix = NULL; - } - - } - - return _Py_INIT_OK(); -#undef COPY_WSTR -#undef COPY_WSTRLIST -} - - /* --- pymain_init() ---------------------------------------------- */ static _PyInitError -pymain_init_preconfig(_PyPreConfig *config, const _PyArgv *args) -{ - _PyInitError err = _PyPreConfig_ReadFromArgv(config, args); - if (_Py_INIT_FAILED(err)) { - return err; - } - - return _Py_PreInitializeFromPreConfig(config); -} - - -static _PyInitError -pymain_init_coreconfig(_PyCoreConfig *config, const _PyArgv *args, - const _PyPreConfig *preconfig, - PyInterpreterState **interp_p) -{ - _PyInitError err = _PyCoreConfig_ReadFromArgv(config, args, preconfig); - if (_Py_INIT_FAILED(err)) { - return err; - } - - _PyCoreConfig_Write(config); - - return _Py_InitializeCore(interp_p, config); -} - - -static _PyInitError -pymain_init_python_main(PyInterpreterState *interp) -{ - _PyInitError err; - - _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT; - err = _PyMainInterpreterConfig_Read(&main_config, &interp->core_config); - if (!_Py_INIT_FAILED(err)) { - err = _Py_InitializeMainInterpreter(interp, &main_config); - } - _PyMainInterpreterConfig_Clear(&main_config); - - if (_Py_INIT_FAILED(err)) { - return err; - } - return _Py_INIT_OK(); -} - - -static _PyInitError -pymain_init(const _PyArgv *args, PyInterpreterState **interp_p) +pymain_init(const _PyArgv *args) { _PyInitError err; @@ -348,33 +52,24 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p) fedisableexcept(FE_OVERFLOW); #endif - _PyPreConfig local_preconfig = _PyPreConfig_INIT; - _PyPreConfig *preconfig = &local_preconfig; - - _PyCoreConfig local_config = _PyCoreConfig_INIT; - _PyCoreConfig *config = &local_config; - - err = pymain_init_preconfig(preconfig, args); + _PyPreConfig preconfig = _PyPreConfig_INIT; + /* Set to -1 to enable them depending on the LC_CTYPE locale and the + environment variables (PYTHONUTF8 and PYTHONCOERCECLOCALE) */ + preconfig.coerce_c_locale = -1; + preconfig.utf8_mode = -1; + err = _Py_PreInitializeFromPyArgv(&preconfig, args); if (_Py_INIT_FAILED(err)) { - goto done; + return err; } - err = pymain_init_coreconfig(config, args, preconfig, interp_p); - if (_Py_INIT_FAILED(err)) { - goto done; + /* pass NULL as the config: config is read from command line arguments, + environment variables, configuration files */ + if (args->use_bytes_argv) { + return _Py_InitializeFromArgs(NULL, args->argc, args->bytes_argv); } - - err = pymain_init_python_main(*interp_p); - if (_Py_INIT_FAILED(err)) { - goto done; + else { + return _Py_InitializeFromWideArgs(NULL, args->argc, args->wchar_argv); } - - err = _Py_INIT_OK(); - -done: - _PyPreConfig_Clear(preconfig); - _PyCoreConfig_Clear(config); - return err; } @@ -478,7 +173,7 @@ pymain_header(const _PyCoreConfig *config) static void pymain_import_readline(const _PyCoreConfig *config) { - if (config->preconfig.isolated) { + if (config->isolated) { return; } if (!config->inspect && RUN_CODE(config)) { @@ -581,7 +276,7 @@ static int pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf) { const wchar_t *filename = config->run_filename; - FILE *fp = _Py_wfopen(filename, L"r"); + FILE *fp = _Py_wfopen(filename, L"rb"); if (fp == NULL) { char *cfilename_buffer; const char *cfilename; @@ -650,7 +345,7 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf) static void pymain_run_startup(_PyCoreConfig *config, PyCompilerFlags *cf) { - const char *startup = _PyCoreConfig_GetEnv(config, "PYTHONSTARTUP"); + const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP"); if (startup == NULL) { return; } @@ -730,7 +425,7 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode) { /* Check this environment variable at the end, to give programs the opportunity to set it from Python. */ - if (!Py_InspectFlag && _PyCoreConfig_GetEnv(config, "PYTHONINSPECT")) { + if (!Py_InspectFlag && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) { Py_InspectFlag = 1; config->inspect = 1; } @@ -749,9 +444,12 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode) static _PyInitError -pymain_run_python(PyInterpreterState *interp, int *exitcode) +pymain_run_python(int *exitcode) { _PyInitError err; + + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + /* pymain_run_stdin() modify the config */ _PyCoreConfig *config = &interp->core_config; PyObject *main_importer_path = NULL; @@ -770,7 +468,7 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode) goto done; } } - else if (!config->preconfig.isolated) { + else if (!config->isolated) { PyObject *path0 = NULL; if (_PyPathConfig_ComputeSysPath0(&config->argv, &path0)) { if (path0 == NULL) { @@ -862,21 +560,27 @@ exit_sigint(void) } -static int -pymain_main(_PyArgv *args) +static void _Py_NO_RETURN +pymain_exit_error(_PyInitError err) { - _PyInitError err; - - PyInterpreterState *interp; - err = pymain_init(args, &interp); - if (_Py_INIT_FAILED(err)) { - goto exit_init_error; + if (_Py_INIT_IS_EXIT(err)) { + /* If it's an error rather than a regular exit, leave Python runtime + alive: _Py_ExitInitError() uses the current exception and use + sys.stdout in this case. */ + pymain_free(); } + _Py_ExitInitError(err); +} + +int +_Py_RunMain(void) +{ int exitcode = 0; - err = pymain_run_python(interp, &exitcode); + + _PyInitError err = pymain_run_python(&exitcode); if (_Py_INIT_FAILED(err)) { - goto exit_init_error; + pymain_exit_error(err); } if (Py_FinalizeEx() < 0) { @@ -892,10 +596,18 @@ pymain_main(_PyArgv *args) } return exitcode; +} -exit_init_error: - pymain_free(); - _Py_ExitInitError(err); + +static int +pymain_main(_PyArgv *args) +{ + _PyInitError err = pymain_init(args); + if (_Py_INIT_FAILED(err)) { + pymain_exit_error(err); + } + + return _Py_RunMain(); } diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index fd330b5fbe0..0f681622f28 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -24,10 +24,6 @@ * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations * look like "NOTE(...)". * - * To debug parser errors like - * "parser.ParserError: Expected node type 12, got 333." - * decode symbol numbers using the automatically-generated files - * Lib/symbol.h and Include/token.h. */ #include "Python.h" /* general Python API */ @@ -648,7 +644,6 @@ validate_node(node *tree) { int type = TYPE(tree); int nch = NCH(tree); - dfa *nt_dfa; state *dfa_state; int pos, arc; @@ -658,7 +653,7 @@ validate_node(node *tree) PyErr_Format(parser_error, "Unrecognized node type %d.", TYPE(tree)); return 0; } - nt_dfa = &_PyParser_Grammar.g_dfa[type]; + const dfa *nt_dfa = &_PyParser_Grammar.g_dfa[type]; REQ(tree, nt_dfa->d_type); /* Run the DFA for this nonterminal. */ @@ -666,6 +661,13 @@ validate_node(node *tree) for (pos = 0; pos < nch; ++pos) { node *ch = CHILD(tree, pos); int ch_type = TYPE(ch); + if ((ch_type >= NT_OFFSET + _PyParser_Grammar.g_ndfas) + || (ISTERMINAL(ch_type) && (ch_type >= N_TOKENS)) + || (ch_type < 0) + ) { + PyErr_Format(parser_error, "Unrecognized node type %d.", ch_type); + return 0; + } if (ch_type == suite && TYPE(tree) == funcdef) { /* This is the opposite hack of what we do in parser.c (search for func_body_suite), except we don't ever @@ -700,8 +702,10 @@ validate_node(node *tree) const char *expected_str = _PyParser_Grammar.g_ll.ll_label[a_label].lb_str; if (ISNONTERMINAL(next_type)) { - PyErr_Format(parser_error, "Expected node type %d, got %d.", - next_type, ch_type); + PyErr_Format(parser_error, "Expected %s, got %s.", + _PyParser_Grammar.g_dfa[next_type - NT_OFFSET].d_name, + ISTERMINAL(ch_type) ? _PyParser_TokenNames[ch_type] : + _PyParser_Grammar.g_dfa[ch_type - NT_OFFSET].d_name); } else if (expected_str != NULL) { PyErr_Format(parser_error, "Illegal terminal: expected '%s'.", diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 3f760183575..221f7101b21 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -284,10 +284,7 @@ extern char *ctermid_r(char *); #include #include /* for ShellExecute() */ #include /* for UNLEN */ -#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */ #define HAVE_SYMLINK -static int win32_can_symlink = 0; -#endif #endif /* _MSC_VER */ #ifndef MAXPATHLEN @@ -424,12 +421,13 @@ PyOS_AfterFork_Parent(void) void PyOS_AfterFork_Child(void) { - _PyGILState_Reinit(); - _PyInterpreterState_DeleteExceptMain(); + _PyRuntimeState *runtime = &_PyRuntime; + _PyGILState_Reinit(runtime); + _PyInterpreterState_DeleteExceptMain(runtime); PyEval_ReInitThreads(); _PyImport_ReInitLock(); _PySignal_AfterFork(); - _PyRuntimeState_ReInitThreads(); + _PyRuntimeState_ReInitThreads(runtime); run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0); } @@ -1261,7 +1259,8 @@ _Py_Sigset_Converter(PyObject *obj, void *addr) long signum; int overflow; - if (sigemptyset(mask)) { + // The extra parens suppress the unreachable-code warning with clang on MacOS + if (sigemptyset(mask) < (0)) { /* Probably only if mask == NULL. */ PyErr_SetFromErrno(PyExc_OSError); return 0; @@ -1442,17 +1441,23 @@ win32_error(const char* function, const char* filename) } static PyObject * -win32_error_object(const char* function, PyObject* filename) +win32_error_object_err(const char* function, PyObject* filename, DWORD err) { /* XXX - see win32_error for comments on 'function' */ - errno = GetLastError(); if (filename) return PyErr_SetExcFromWindowsErrWithFilenameObject( PyExc_OSError, - errno, + err, filename); else - return PyErr_SetFromWindowsErr(errno); + return PyErr_SetFromWindowsErr(err); +} + +static PyObject * +win32_error_object(const char* function, PyObject* filename) +{ + errno = GetLastError(); + return win32_error_object_err(function, filename, errno); } #endif /* MS_WINDOWS */ @@ -7749,26 +7754,6 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd) #if defined(MS_WINDOWS) -/* Grab CreateSymbolicLinkW dynamically from kernel32 */ -static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL; - -static int -check_CreateSymbolicLink(void) -{ - HINSTANCE hKernel32; - /* only recheck */ - if (Py_CreateSymbolicLinkW) - return 1; - - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, - "CreateSymbolicLinkW"); - Py_END_ALLOW_THREADS - - return Py_CreateSymbolicLinkW != NULL; -} - /* Remove the last portion of the path - return 0 on success */ static int _dirnameW(WCHAR *path) @@ -7872,33 +7857,57 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, { #ifdef MS_WINDOWS DWORD result; + DWORD flags = 0; + + /* Assumed true, set to false if detected to not be available. */ + static int windows_has_symlink_unprivileged_flag = TRUE; #else int result; #endif #ifdef MS_WINDOWS - if (!check_CreateSymbolicLink()) { - PyErr_SetString(PyExc_NotImplementedError, - "CreateSymbolicLink functions not found"); - return NULL; - } - if (!win32_can_symlink) { - PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); - return NULL; - } -#endif -#ifdef MS_WINDOWS + if (windows_has_symlink_unprivileged_flag) { + /* Allow non-admin symlinks if system allows it. */ + flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; + } Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH - /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirW(src->wide, dst->wide); - result = Py_CreateSymbolicLinkW(dst->wide, src->wide, - target_is_directory); + /* if src is a directory, ensure flags==1 (target_is_directory bit) */ + if (target_is_directory || _check_dirW(src->wide, dst->wide)) { + flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; + } + + result = CreateSymbolicLinkW(dst->wide, src->wide, flags); _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS + if (windows_has_symlink_unprivileged_flag && !result && + ERROR_INVALID_PARAMETER == GetLastError()) { + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + /* This error might be caused by + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported. + Try again, and update windows_has_symlink_unprivileged_flag if we + are successful this time. + + NOTE: There is a risk of a race condition here if there are other + conditions than the flag causing ERROR_INVALID_PARAMETER, and + another process (or thread) changes that condition in between our + calls to CreateSymbolicLink. + */ + flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); + result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (result || ERROR_INVALID_PARAMETER != GetLastError()) { + windows_has_symlink_unprivileged_flag = FALSE; + } + } + if (!result) return path_error2(src, dst); @@ -13161,6 +13170,113 @@ os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) } #endif /* HAVE_GETRANDOM_SYSCALL */ +#ifdef MS_WINDOWS +/* bpo-36085: Helper functions for managing DLL search directories + * on win32 + */ + +typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory); +typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie); + +/*[clinic input] +os._add_dll_directory + + path: path_t + +Add a path to the DLL search path. + +This search path is used when resolving dependencies for imported +extension modules (the module itself is resolved through sys.path), +and also by ctypes. + +Returns an opaque value that may be passed to os.remove_dll_directory +to remove this directory from the search path. +[clinic start generated code]*/ + +static PyObject * +os__add_dll_directory_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/ +{ + HMODULE hKernel32; + PAddDllDirectory AddDllDirectory; + DLL_DIRECTORY_COOKIE cookie = 0; + DWORD err = 0; + + /* For Windows 7, we have to load this. As this will be a fairly + infrequent operation, just do it each time. Kernel32 is always + loaded. */ + Py_BEGIN_ALLOW_THREADS + if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || + !(AddDllDirectory = (PAddDllDirectory)GetProcAddress( + hKernel32, "AddDllDirectory")) || + !(cookie = (*AddDllDirectory)(path->wide))) { + err = GetLastError(); + } + Py_END_ALLOW_THREADS + + if (err) { + return win32_error_object_err("add_dll_directory", + path->object, err); + } + + return PyCapsule_New(cookie, "DLL directory cookie", NULL); +} + +/*[clinic input] +os._remove_dll_directory + + cookie: object + +Removes a path from the DLL search path. + +The parameter is an opaque value that was returned from +os.add_dll_directory. You can only remove directories that you added +yourself. +[clinic start generated code]*/ + +static PyObject * +os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) +/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/ +{ + HMODULE hKernel32; + PRemoveDllDirectory RemoveDllDirectory; + DLL_DIRECTORY_COOKIE cookieValue; + DWORD err = 0; + + if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) { + PyErr_SetString(PyExc_TypeError, + "Provided cookie was not returned from os.add_dll_directory"); + return NULL; + } + + cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer( + cookie, "DLL directory cookie"); + + /* For Windows 7, we have to load this. As this will be a fairly + infrequent operation, just do it each time. Kernel32 is always + loaded. */ + Py_BEGIN_ALLOW_THREADS + if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || + !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress( + hKernel32, "RemoveDllDirectory")) || + !(*RemoveDllDirectory)(cookieValue)) { + err = GetLastError(); + } + Py_END_ALLOW_THREADS + + if (err) { + return win32_error_object_err("remove_dll_directory", + NULL, err); + } + + if (PyCapsule_SetName(cookie, NULL)) { + return NULL; + } + + Py_RETURN_NONE; +} + +#endif static PyMethodDef posix_methods[] = { @@ -13349,38 +13465,13 @@ static PyMethodDef posix_methods[] = { OS_SCANDIR_METHODDEF OS_FSPATH_METHODDEF OS_GETRANDOM_METHODDEF +#ifdef MS_WINDOWS + OS__ADD_DLL_DIRECTORY_METHODDEF + OS__REMOVE_DLL_DIRECTORY_METHODDEF +#endif {NULL, NULL} /* Sentinel */ }; - -#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) -static int -enable_symlink() -{ - HANDLE tok; - TOKEN_PRIVILEGES tok_priv; - LUID luid; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) - return 0; - - if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid)) - return 0; - - tok_priv.PrivilegeCount = 1; - tok_priv.Privileges[0].Luid = luid; - tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv, - sizeof(TOKEN_PRIVILEGES), - (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) - return 0; - - /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */ - return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1; -} -#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ - static int all_ins(PyObject *m) { @@ -13826,6 +13917,14 @@ all_ins(PyObject *m) if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; #endif +#ifdef MS_WINDOWS + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1; +#endif + return 0; } @@ -13980,10 +14079,6 @@ INITFUNC(void) PyObject *list; const char * const *trace; -#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) - win32_can_symlink = enable_symlink(); -#endif - m = PyModule_Create(&posixmodule); if (m == NULL) return NULL; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 4590017c170..8c5a0d044ab 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1350,17 +1350,15 @@ PyInit__signal(void) d = PyModule_GetDict(m); x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); - if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0) + if (PyModule_AddObject(m, "SIG_DFL", x)) goto finally; x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); - if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0) + if (PyModule_AddObject(m, "SIG_IGN", x)) goto finally; - x = PyLong_FromLong((long)NSIG); - if (!x || PyDict_SetItemString(d, "NSIG", x) < 0) + if (PyModule_AddIntMacro(m, NSIG)) goto finally; - Py_DECREF(x); #ifdef SIG_BLOCK if (PyModule_AddIntMacro(m, SIG_BLOCK)) @@ -1569,8 +1567,8 @@ PyInit__signal(void) #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) ItimerError = PyErr_NewException("signal.ItimerError", PyExc_OSError, NULL); - if (ItimerError != NULL) - PyDict_SetItemString(d, "ItimerError", ItimerError); + if (PyModule_AddObject(m, "ItimerError", ItimerError)) + goto finally; #endif #ifdef CTRL_C_EVENT diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index b48f8a9c309..c024542fe70 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -309,6 +309,40 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include # endif +/* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ +#ifdef MS_WINDOWS +#define IPPROTO_ICMP IPPROTO_ICMP +#define IPPROTO_IGMP IPPROTO_IGMP +#define IPPROTO_GGP IPPROTO_GGP +#define IPPROTO_TCP IPPROTO_TCP +#define IPPROTO_PUP IPPROTO_PUP +#define IPPROTO_UDP IPPROTO_UDP +#define IPPROTO_IDP IPPROTO_IDP +#define IPPROTO_ND IPPROTO_ND +#define IPPROTO_RAW IPPROTO_RAW +#define IPPROTO_MAX IPPROTO_MAX +#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS +#define IPPROTO_IPV4 IPPROTO_IPV4 +#define IPPROTO_IPV6 IPPROTO_IPV6 +#define IPPROTO_ROUTING IPPROTO_ROUTING +#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT +#define IPPROTO_ESP IPPROTO_ESP +#define IPPROTO_AH IPPROTO_AH +#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 +#define IPPROTO_NONE IPPROTO_NONE +#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS +#define IPPROTO_EGP IPPROTO_EGP +#define IPPROTO_PIM IPPROTO_PIM +#define IPPROTO_ICLFXBM IPPROTO_ICLFXBM // WinSock2 only +#define IPPROTO_ST IPPROTO_ST // WinSock2 only +#define IPPROTO_CBT IPPROTO_CBT // WinSock2 only +#define IPPROTO_IGP IPPROTO_IGP // WinSock2 only +#define IPPROTO_RDP IPPROTO_RDP // WinSock2 only +#define IPPROTO_PGM IPPROTO_PGM // WinSock2 only +#define IPPROTO_L2TP IPPROTO_L2TP // WinSock2 only +#define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only +#endif /* MS_WINDOWS */ + /* Provides the IsWindows7SP1OrGreater() function */ #include @@ -356,7 +390,7 @@ remove_unusable_flags(PyObject *m) for (int i=0; i 2037 */ - if ((buf.tm_year < 2) || (buf.tm_year > 137)) { - /* Issue #19748: On AIX, mktime() doesn't report overflow error for - * timestamp < -2^31 or timestamp > 2**31-1. */ + +#if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64)) + /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970 + to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below, + it is possible to support years in range [1902; 2037] */ + if (tm.tm_year < 2 || tm.tm_year > 137) { + /* bpo-19748: On AIX, mktime() does not report overflow error + for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the + same issue when working in 32 bit mode. */ PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } - year = buf.tm_year; - /* year < 1970 - adjust buf.tm_year into legal range */ - while (buf.tm_year < 70) { - buf.tm_year += 4; +#endif + +#ifdef _AIX + /* bpo-34373: AIX mktime() has an integer overflow for years in range + [1902; 1969]. Workaround the issue by using a year greater or equal than + 1970 (tm_year >= 70): mktime() behaves correctly in that case + (ex: properly report errors). tm_year and tm_wday are adjusted after + mktime() call. */ + int orig_tm_year = tm.tm_year; + int delta_days = 0; + while (tm.tm_year < 70) { + /* Use 4 years to account properly leap years */ + tm.tm_year += 4; delta_days -= (366 + (365 * 3)); } - - buf.tm_wday = -1; - clk = mktime(&buf); - buf.tm_year = year; - - if ((buf.tm_wday != -1) && delta_days) - buf.tm_wday = (buf.tm_wday + delta_days) % 7; - - tt = clk + (delta_days * (24 * 3600)); #endif + + tm.tm_wday = -1; /* sentinel; original value ignored */ + tt = mktime(&tm); + /* Return value of -1 does not necessarily mean an error, but tm_wday * cannot remain set to -1 if mktime succeeded. */ if (tt == (time_t)(-1) /* Return value of -1 does not necessarily mean an error, but * tm_wday cannot remain set to -1 if mktime succeeded. */ - && buf.tm_wday == -1) + && tm.tm_wday == -1) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } + +#ifdef _AIX + if (delta_days != 0) { + tm.tm_year = orig_tm_year; + if (tm.tm_wday != -1) { + tm.tm_wday = (tm.tm_wday + delta_days) % 7; + } + tt += delta_days * (24 * 3600); + } +#endif + return PyFloat_FromDouble((double)tt); } diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 9ceab1b3db4..7fdbf332ee7 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1029,7 +1029,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, int offset; int i; int word; - unsigned char* w; + const unsigned char* w; if (code >= 0x110000) return 0; diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index 11c7dc87244..66f81e311e2 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -699,7 +699,7 @@ static const char *decomp_prefix[] = { }; /* index tables for the database records */ #define SHIFT 7 -static unsigned short index1[] = { +static const unsigned short index1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, @@ -1322,7 +1322,7 @@ static unsigned short index1[] = { 121, 260, }; -static unsigned short index2[] = { +static const unsigned short index2[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, @@ -3260,7 +3260,7 @@ static unsigned short index2[] = { }; /* decomposition data */ -static unsigned int decomp_data[] = { +static const unsigned int decomp_data[] = { 0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514, 32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52, 772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512, @@ -4328,7 +4328,7 @@ static unsigned int decomp_data[] = { /* index tables for the decomposition data */ #define DECOMP_SHIFT 7 -static unsigned char decomp_index1[] = { +static const unsigned char decomp_index1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 29, 30, 31, 32, 33, 34, @@ -4695,7 +4695,7 @@ static unsigned char decomp_index1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -static unsigned short decomp_index2[] = { +static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5512,7 +5512,7 @@ static unsigned short decomp_index2[] = { /* NFC pairs */ #define COMP_SHIFT 2 -static unsigned short comp_index[] = { +static const unsigned short comp_index[] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 0, 13, 0, 0, @@ -5772,7 +5772,7 @@ static unsigned short comp_index[] = { 656, }; -static unsigned int comp_data[] = { +static const unsigned int comp_data[] = { 0, 0, 0, 0, 0, 0, 0, 8814, 0, 8800, 0, 0, 0, 0, 0, 8815, 0, 0, 192, 193, 194, 195, 256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, 0, 7680, 0, 0, 260, 0, 0, 0, 0, 0, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, @@ -5982,7 +5982,7 @@ static const change_record change_records_3_2_0[] = { { 255, 19, 255, 255, 255, -1 }, { 1, 255, 255, 0, 255, 0 }, }; -static unsigned char changes_3_2_0_index[] = { +static const unsigned char changes_3_2_0_index[] = { 0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 2, 2, 2, 38, 39, 2, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, @@ -6356,7 +6356,7 @@ static unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; -static unsigned char changes_3_2_0_data[] = { +static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index 8fa87a02cd2..372616966aa 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -3,7 +3,7 @@ #define NAME_MAXLEN 256 /* lexicon */ -static unsigned char lexicon[] = { +static const unsigned char lexicon[] = { 76, 69, 84, 84, 69, 210, 83, 73, 71, 206, 87, 73, 84, 200, 83, 77, 65, 76, 204, 83, 89, 76, 76, 65, 66, 76, 197, 67, 65, 80, 73, 84, 65, 204, 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 76, 65, 84, 73, 206, 65, 82, 65, @@ -6442,7 +6442,7 @@ static unsigned char lexicon[] = { 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, 72, 65, 76, 128, }; -static unsigned int lexicon_offset[] = { +static const unsigned int lexicon_offset[] = { 0, 0, 6, 10, 14, 19, 27, 34, 44, 49, 55, 64, 66, 69, 81, 89, 102, 108, 113, 118, 124, 129, 137, 146, 157, 162, 167, 170, 174, 183, 189, 195, 201, 206, 214, 221, 229, 171, 232, 241, 242, 250, 256, 261, 266, 273, @@ -8012,7 +8012,7 @@ static unsigned int lexicon_offset[] = { /* code->name phrasebook */ #define phrasebook_shift 7 #define phrasebook_short 194 -static unsigned char phrasebook[] = { +static const unsigned char phrasebook[] = { 0, 205, 148, 236, 89, 78, 211, 61, 78, 31, 55, 239, 9, 55, 213, 44, 55, 251, 110, 251, 29, 50, 213, 139, 53, 213, 139, 250, 178, 98, 55, 244, 158, 231, 5, 234, 216, 204, 226, 205, 177, 17, 195, 79, 17, 100, 17, 102, @@ -19073,7 +19073,7 @@ static unsigned char phrasebook[] = { 73, 241, 124, 152, 154, }; -static unsigned short phrasebook_offset1[] = { +static const unsigned short phrasebook_offset1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, @@ -19696,7 +19696,7 @@ static unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, }; -static unsigned int phrasebook_offset2[] = { +static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 31, 33, 35, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72, @@ -23496,7 +23496,7 @@ static unsigned int phrasebook_offset2[] = { }; /* name->code dictionary */ -static unsigned int code_hash[] = { +static const unsigned int code_hash[] = { 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, 12064, 0, 129548, 194597, 69850, 65842, 0, 0, 0, 78159, 68476, 72392, 1373, 0, 0, 5816, 0, 0, 4231, 0, 0, 4233, 4234, 4232, 68885, 70351, 0, diff --git a/Modules/winreparse.h b/Modules/winreparse.h index 28049c9af90..f06f701f999 100644 --- a/Modules/winreparse.h +++ b/Modules/winreparse.h @@ -45,6 +45,11 @@ typedef struct { FIELD_OFFSET(_Py_REPARSE_DATA_BUFFER, GenericReparseBuffer) #define _Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) +// Defined in WinBase.h in 'recent' versions of Windows 10 SDK +#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2 +#endif + #ifdef __cplusplus } #endif diff --git a/Objects/boolobject.c b/Objects/boolobject.c index b92fafe620c..508ea61f180 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -147,7 +147,7 @@ PyTypeObject PyBool_Type = { 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - bool_repr, /* tp_str */ + 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/Objects/call.c b/Objects/call.c index d52e7e26aeb..68f9e879fa7 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -320,11 +320,11 @@ _PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { /* Fast paths */ - if (argdefs == NULL && co->co_argcount == nargs) { + if (argdefs == NULL && co->co_argcount + co->co_posonlyargcount == nargs) { return function_code_fastcall(co, args, nargs, globals); } else if (nargs == 0 && argdefs != NULL - && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { + && co->co_argcount + co->co_posonlyargcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ args = _PyTuple_ITEMS(argdefs); @@ -406,11 +406,11 @@ _PyFunction_FastCallKeywords(PyObject *func, PyObject *const *stack, if (co->co_kwonlyargcount == 0 && nkwargs == 0 && (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { + if (argdefs == NULL && co->co_argcount + co->co_posonlyargcount== nargs) { return function_code_fastcall(co, stack, nargs, globals); } else if (nargs == 0 && argdefs != NULL - && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { + && co->co_argcount + co->co_posonlyargcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ stack = _PyTuple_ITEMS(argdefs); diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index 713781ce880..b87244d8734 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -116,6 +116,63 @@ exit: return return_value; } +PyDoc_STRVAR(dict_pop__doc__, +"pop($self, key, default=None, /)\n" +"--\n" +"\n" +"Remove specified key and return the corresponding value.\n" +"\n" +"If key is not found, default is returned if given, otherwise KeyError is raised"); + +#define DICT_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__}, + +static PyObject * +dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value); + +static PyObject * +dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { + goto exit; + } + key = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = dict_pop_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(dict_popitem__doc__, +"popitem($self, /)\n" +"--\n" +"\n" +"Remove and return a (key, value) pair as a 2-tuple.\n" +"\n" +"Pairs are returned in LIFO (last-in, first-out) order.\n" +"Raises KeyError if the dict is empty."); + +#define DICT_POPITEM_METHODDEF \ + {"popitem", (PyCFunction)dict_popitem, METH_NOARGS, dict_popitem__doc__}, + +static PyObject * +dict_popitem_impl(PyDictObject *self); + +static PyObject * +dict_popitem(PyDictObject *self, PyObject *Py_UNUSED(ignored)) +{ + return dict_popitem_impl(self); +} + PyDoc_STRVAR(dict___reversed____doc__, "__reversed__($self, /)\n" "--\n" @@ -133,4 +190,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=12c21ce3552d9617 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0fd5cafc61a51d3c input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 09182d61c24..62d7c5d329f 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -96,7 +96,7 @@ intern_string_constants(PyObject *tuple) PyCodeObject * -PyCode_New(int argcount, int kwonlyargcount, +PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, @@ -108,8 +108,8 @@ PyCode_New(int argcount, int kwonlyargcount, Py_ssize_t i, n_cellvars, n_varnames, total_args; /* Check argument types */ - if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || - code == NULL || !PyBytes_Check(code) || + if (argcount < 0 || posonlyargcount < 0 || kwonlyargcount < 0 || + nlocals < 0 || code == NULL || !PyBytes_Check(code) || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || varnames == NULL || !PyTuple_Check(varnames) || @@ -141,10 +141,12 @@ PyCode_New(int argcount, int kwonlyargcount, } n_varnames = PyTuple_GET_SIZE(varnames); - if (argcount <= n_varnames && kwonlyargcount <= n_varnames) { + if (posonlyargcount + argcount <= n_varnames + && kwonlyargcount <= n_varnames) { /* Never overflows. */ - total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount + - ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); + total_args = (Py_ssize_t)posonlyargcount + (Py_ssize_t)argcount + + (Py_ssize_t)kwonlyargcount + + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); } else { total_args = n_varnames + 1; @@ -193,6 +195,7 @@ PyCode_New(int argcount, int kwonlyargcount, return NULL; } co->co_argcount = argcount; + co->co_posonlyargcount = posonlyargcount; co->co_kwonlyargcount = kwonlyargcount; co->co_nlocals = nlocals; co->co_stacksize = stacksize; @@ -249,6 +252,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) goto failed; result = PyCode_New(0, /* argcount */ + 0, /* posonlyargcount */ 0, /* kwonlyargcount */ 0, /* nlocals */ 0, /* stacksize */ @@ -274,21 +278,22 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) #define OFF(x) offsetof(PyCodeObject, x) static PyMemberDef code_memberlist[] = { - {"co_argcount", T_INT, OFF(co_argcount), READONLY}, - {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, - {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, - {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, - {"co_flags", T_INT, OFF(co_flags), READONLY}, - {"co_code", T_OBJECT, OFF(co_code), READONLY}, - {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, - {"co_names", T_OBJECT, OFF(co_names), READONLY}, - {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, - {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, - {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, - {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, - {"co_name", T_OBJECT, OFF(co_name), READONLY}, - {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, - {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, + {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, + {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, + {"co_flags", T_INT, OFF(co_flags), READONLY}, + {"co_code", T_OBJECT, OFF(co_code), READONLY}, + {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, + {"co_names", T_OBJECT, OFF(co_names), READONLY}, + {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, + {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, + {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, + {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, + {"co_name", T_OBJECT, OFF(co_name), READONLY}, + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, + {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, {NULL} /* Sentinel */ }; @@ -335,9 +340,9 @@ validate_and_copy_tuple(PyObject *tup) } PyDoc_STRVAR(code_doc, -"code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\ - constants, names, varnames, filename, name, firstlineno,\n\ - lnotab[, freevars[, cellvars]])\n\ +"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n\ + flags, codestring, constants, names, varnames, filename, name,\n\ + firstlineno, lnotab[, freevars[, cellvars]])\n\ \n\ Create a code object. Not for the faint of heart."); @@ -345,6 +350,7 @@ static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kw) { int argcount; + int posonlyargcount; int kwonlyargcount; int nlocals; int stacksize; @@ -361,8 +367,8 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) int firstlineno; PyObject *lnotab; - if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code", - &argcount, &kwonlyargcount, + if (!PyArg_ParseTuple(args, "iiiiiiSO!O!O!UUiS|O!O!:code", + &argcount, &posonlyargcount, &kwonlyargcount, &nlocals, &stacksize, &flags, &code, &PyTuple_Type, &consts, @@ -381,6 +387,13 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) goto cleanup; } + if (posonlyargcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: posonlyargcount must not be negative"); + goto cleanup; + } + if (kwonlyargcount < 0) { PyErr_SetString( PyExc_ValueError, @@ -413,7 +426,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (ourcellvars == NULL) goto cleanup; - co = (PyObject *)PyCode_New(argcount, kwonlyargcount, + co = (PyObject *)PyCode_New(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, ournames, ourvarnames, ourfreevars, ourcellvars, filename, @@ -645,9 +658,11 @@ code_richcompare(PyObject *self, PyObject *other, int op) cp = (PyCodeObject *)other; eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); - if (eq <= 0) goto unequal; + if (!eq) goto unequal; eq = co->co_argcount == cp->co_argcount; if (!eq) goto unequal; + eq = co->co_posonlyargcount == cp->co_posonlyargcount; + if (!eq) goto unequal; eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; if (!eq) goto unequal; eq = co->co_nlocals == cp->co_nlocals; @@ -720,7 +735,7 @@ code_hash(PyCodeObject *co) h6 = PyObject_Hash(co->co_cellvars); if (h6 == -1) return -1; h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ - co->co_argcount ^ co->co_kwonlyargcount ^ + co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ co->co_nlocals ^ co->co_flags; if (h == -1) h = -2; return h; diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 6e3d47b62d1..cae2bf11dc9 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1129,7 +1129,7 @@ PyTypeObject PyComplex_Type = { 0, /* tp_as_mapping */ (hashfunc)complex_hash, /* tp_hash */ 0, /* tp_call */ - (reprfunc)complex_repr, /* tp_str */ + 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 22546a563a5..0fe9a441b82 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -78,8 +78,8 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) } if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for '%s' objects " - "doesn't apply to '%s' object", + "descriptor '%V' for '%.100s' objects " + "doesn't apply to a '%.100s' object", descr_name((PyDescrObject *)descr), "?", descr->d_type->tp_name, obj->ob_type->tp_name); @@ -99,7 +99,7 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) else { /* Wot - no type?! */ PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%s' " + "descriptor '%V' for type '%.100s' " "needs either an object or a type", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name); @@ -108,8 +108,8 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) } if (!PyType_Check(type)) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%s' " - "needs a type, not a '%s' as arg 2", + "descriptor '%V' for type '%.100s' " + "needs a type, not a '%.100s' as arg 2", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, type->ob_type->tp_name); @@ -117,8 +117,8 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) } if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%s' " - "doesn't apply to type '%s'", + "descriptor '%V' requires a subtype of '%.100s' " + "but received '%.100s'", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, ((PyTypeObject *)type)->tp_name); @@ -181,7 +181,7 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%V' for '%.100s' objects " - "doesn't apply to '%.100s' object", + "doesn't apply to a '%.100s' object", descr_name(descr), "?", descr->d_type->tp_name, obj->ob_type->tp_name); @@ -239,9 +239,8 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' " - "requires a '%.100s' object " - "but received a '%.100s'", + "descriptor '%V' for '%.100s' objects " + "doesn't apply to a '%.100s' object", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); @@ -278,9 +277,8 @@ _PyMethodDescr_FastCallKeywords(PyObject *descrobj, if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' " - "requires a '%.100s' object " - "but received a '%.100s'", + "descriptor '%V' for '%.100s' objects " + "doesn't apply to a '%.100s' object", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); @@ -315,20 +313,18 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, if (!PyType_Check(self)) { PyErr_Format(PyExc_TypeError, "descriptor '%V' requires a type " - "but received a '%.100s'", + "but received a '%.100s' instance", descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); return NULL; } if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, - "descriptor '%V' " - "requires a subtype of '%.100s' " - "but received '%.100s", + "descriptor '%V' requires a subtype of '%.100s' " + "but received '%.100s'", descr_name((PyDescrObject *)descr), "?", PyDescr_TYPE(descr)->tp_name, - self->ob_type->tp_name); + ((PyTypeObject*)self)->tp_name); return NULL; } diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e2603e190b6..9b5c0a3be9a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -449,77 +449,77 @@ static PyObject *empty_values[1] = { NULL }; /* Uncomment to check the dict content in _PyDict_CheckConsistency() */ /* #define DEBUG_PYDICT */ +#ifdef DEBUG_PYDICT +# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1)) +#else +# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 0)) +#endif -#ifndef NDEBUG -static int -_PyDict_CheckConsistency(PyDictObject *mp) + +int +_PyDict_CheckConsistency(PyObject *op, int check_content) { -#define ASSERT(expr) _PyObject_ASSERT((PyObject *)mp, (expr)) + _PyObject_ASSERT(op, PyDict_Check(op)); + PyDictObject *mp = (PyDictObject *)op; PyDictKeysObject *keys = mp->ma_keys; int splitted = _PyDict_HasSplitTable(mp); Py_ssize_t usable = USABLE_FRACTION(keys->dk_size); -#ifdef DEBUG_PYDICT - PyDictKeyEntry *entries = DK_ENTRIES(keys); - Py_ssize_t i; -#endif - ASSERT(0 <= mp->ma_used && mp->ma_used <= usable); - ASSERT(IS_POWER_OF_2(keys->dk_size)); - ASSERT(0 <= keys->dk_usable - && keys->dk_usable <= usable); - ASSERT(0 <= keys->dk_nentries - && keys->dk_nentries <= usable); - ASSERT(keys->dk_usable + keys->dk_nentries <= usable); + _PyObject_ASSERT(op, 0 <= mp->ma_used && mp->ma_used <= usable); + _PyObject_ASSERT(op, IS_POWER_OF_2(keys->dk_size)); + _PyObject_ASSERT(op, 0 <= keys->dk_usable && keys->dk_usable <= usable); + _PyObject_ASSERT(op, 0 <= keys->dk_nentries && keys->dk_nentries <= usable); + _PyObject_ASSERT(op, keys->dk_usable + keys->dk_nentries <= usable); if (!splitted) { /* combined table */ - ASSERT(keys->dk_refcnt == 1); + _PyObject_ASSERT(op, keys->dk_refcnt == 1); } -#ifdef DEBUG_PYDICT - for (i=0; i < keys->dk_size; i++) { - Py_ssize_t ix = dictkeys_get_index(keys, i); - ASSERT(DKIX_DUMMY <= ix && ix <= usable); - } + if (check_content) { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + Py_ssize_t i; - for (i=0; i < usable; i++) { - PyDictKeyEntry *entry = &entries[i]; - PyObject *key = entry->me_key; + for (i=0; i < keys->dk_size; i++) { + Py_ssize_t ix = dictkeys_get_index(keys, i); + _PyObject_ASSERT(op, DKIX_DUMMY <= ix && ix <= usable); + } - if (key != NULL) { - if (PyUnicode_CheckExact(key)) { - Py_hash_t hash = ((PyASCIIObject *)key)->hash; - ASSERT(hash != -1); - ASSERT(entry->me_hash == hash); + for (i=0; i < usable; i++) { + PyDictKeyEntry *entry = &entries[i]; + PyObject *key = entry->me_key; + + if (key != NULL) { + if (PyUnicode_CheckExact(key)) { + Py_hash_t hash = ((PyASCIIObject *)key)->hash; + _PyObject_ASSERT(op, hash != -1); + _PyObject_ASSERT(op, entry->me_hash == hash); + } + else { + /* test_dict fails if PyObject_Hash() is called again */ + _PyObject_ASSERT(op, entry->me_hash != -1); + } + if (!splitted) { + _PyObject_ASSERT(op, entry->me_value != NULL); + } } - else { - /* test_dict fails if PyObject_Hash() is called again */ - ASSERT(entry->me_hash != -1); - } - if (!splitted) { - ASSERT(entry->me_value != NULL); + + if (splitted) { + _PyObject_ASSERT(op, entry->me_value == NULL); } } if (splitted) { - ASSERT(entry->me_value == NULL); + /* splitted table */ + for (i=0; i < mp->ma_used; i++) { + _PyObject_ASSERT(op, mp->ma_values[i] != NULL); + } } } - if (splitted) { - /* splitted table */ - for (i=0; i < mp->ma_used; i++) { - ASSERT(mp->ma_values[i] != NULL); - } - } -#endif - return 1; - -#undef ASSERT } -#endif static PyDictKeysObject *new_keys_object(Py_ssize_t size) @@ -614,7 +614,7 @@ new_dict(PyDictKeysObject *keys, PyObject **values) mp->ma_values = values; mp->ma_used = 0; mp->ma_version_tag = DICT_NEXT_VERSION(); - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); return (PyObject *)mp; } @@ -675,7 +675,7 @@ clone_combined_dict(PyDictObject *orig) return NULL; } new->ma_used = orig->ma_used; - assert(_PyDict_CheckConsistency(new)); + ASSERT_CONSISTENT(new); if (_PyObject_GC_IS_TRACKED(orig)) { /* Maintain tracking. */ _PyObject_GC_TRACK(new); @@ -1075,7 +1075,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); return 0; } @@ -1094,7 +1094,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) mp->ma_version_tag = DICT_NEXT_VERSION(); Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); Py_DECREF(key); return 0; @@ -1582,7 +1582,7 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, Py_DECREF(old_key); Py_DECREF(old_value); - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); return 0; } @@ -1722,7 +1722,7 @@ PyDict_Clear(PyObject *op) assert(oldkeys->dk_refcnt == 1); dictkeys_decref(oldkeys); } - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); } /* Internal version of PyDict_Next that returns a hash value in addition @@ -1852,7 +1852,7 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d ep->me_value = NULL; Py_DECREF(old_key); - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); return old_value; } @@ -2147,7 +2147,7 @@ dict_keys(PyDictObject *mp) PyObject *v; Py_ssize_t i, j; PyDictKeyEntry *ep; - Py_ssize_t size, n, offset; + Py_ssize_t n, offset; PyObject **value_ptr; again: @@ -2163,7 +2163,6 @@ dict_keys(PyDictObject *mp) goto again; } ep = DK_ENTRIES(mp->ma_keys); - size = mp->ma_keys->dk_nentries; if (mp->ma_values) { value_ptr = mp->ma_values; offset = sizeof(PyObject *); @@ -2172,7 +2171,7 @@ dict_keys(PyDictObject *mp) value_ptr = &ep[0].me_value; offset = sizeof(PyDictKeyEntry); } - for (i = 0, j = 0; i < size; i++) { + for (i = 0, j = 0; j < n; i++) { if (*value_ptr != NULL) { PyObject *key = ep[i].me_key; Py_INCREF(key); @@ -2191,7 +2190,7 @@ dict_values(PyDictObject *mp) PyObject *v; Py_ssize_t i, j; PyDictKeyEntry *ep; - Py_ssize_t size, n, offset; + Py_ssize_t n, offset; PyObject **value_ptr; again: @@ -2207,7 +2206,6 @@ dict_values(PyDictObject *mp) goto again; } ep = DK_ENTRIES(mp->ma_keys); - size = mp->ma_keys->dk_nentries; if (mp->ma_values) { value_ptr = mp->ma_values; offset = sizeof(PyObject *); @@ -2216,7 +2214,7 @@ dict_values(PyDictObject *mp) value_ptr = &ep[0].me_value; offset = sizeof(PyDictKeyEntry); } - for (i = 0, j = 0; i < size; i++) { + for (i = 0, j = 0; j < n; i++) { PyObject *value = *value_ptr; value_ptr = (PyObject **)(((char *)value_ptr) + offset); if (value != NULL) { @@ -2234,7 +2232,7 @@ dict_items(PyDictObject *mp) { PyObject *v; Py_ssize_t i, j, n; - Py_ssize_t size, offset; + Py_ssize_t offset; PyObject *item, *key; PyDictKeyEntry *ep; PyObject **value_ptr; @@ -2265,7 +2263,6 @@ dict_items(PyDictObject *mp) } /* Nothing we do below makes any function calls. */ ep = DK_ENTRIES(mp->ma_keys); - size = mp->ma_keys->dk_nentries; if (mp->ma_values) { value_ptr = mp->ma_values; offset = sizeof(PyObject *); @@ -2274,7 +2271,7 @@ dict_items(PyDictObject *mp) value_ptr = &ep[0].me_value; offset = sizeof(PyDictKeyEntry); } - for (i = 0, j = 0; i < size; i++) { + for (i = 0, j = 0; j < n; i++) { PyObject *value = *value_ptr; value_ptr = (PyObject **)(((char *)value_ptr) + offset); if (value != NULL) { @@ -2437,7 +2434,7 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) } i = 0; - assert(_PyDict_CheckConsistency((PyDictObject *)d)); + ASSERT_CONSISTENT(d); goto Return; Fail: Py_XDECREF(item); @@ -2589,7 +2586,7 @@ dict_merge(PyObject *a, PyObject *b, int override) /* Iterator completed, via error */ return -1; } - assert(_PyDict_CheckConsistency((PyDictObject *)a)); + ASSERT_CONSISTENT(a); return 0; } @@ -2953,7 +2950,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) mp->ma_version_tag = DICT_NEXT_VERSION(); } - assert(_PyDict_CheckConsistency(mp)); + ASSERT_CONSISTENT(mp); return value; } @@ -2988,19 +2985,37 @@ dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } +/*[clinic input] +dict.pop + + key: object + default: object = NULL + / + +Remove specified key and return the corresponding value. + +If key is not found, default is returned if given, otherwise KeyError is raised +[clinic start generated code]*/ + static PyObject * -dict_pop(PyDictObject *mp, PyObject *args) +dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value) +/*[clinic end generated code: output=3abb47b89f24c21c input=016f6a000e4e633b]*/ { - PyObject *key, *deflt = NULL; - - if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt)) - return NULL; - - return _PyDict_Pop((PyObject*)mp, key, deflt); + return _PyDict_Pop((PyObject*)self, key, default_value); } +/*[clinic input] +dict.popitem + +Remove and return a (key, value) pair as a 2-tuple. + +Pairs are returned in LIFO (last-in, first-out) order. +Raises KeyError if the dict is empty. +[clinic start generated code]*/ + static PyObject * -dict_popitem(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) +dict_popitem_impl(PyDictObject *self) +/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/ { Py_ssize_t i, j; PyDictKeyEntry *ep0, *ep; @@ -3018,44 +3033,43 @@ dict_popitem(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) res = PyTuple_New(2); if (res == NULL) return NULL; - if (mp->ma_used == 0) { + if (self->ma_used == 0) { Py_DECREF(res); - PyErr_SetString(PyExc_KeyError, - "popitem(): dictionary is empty"); + PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty"); return NULL; } /* Convert split table to combined table */ - if (mp->ma_keys->dk_lookup == lookdict_split) { - if (dictresize(mp, DK_SIZE(mp->ma_keys))) { + if (self->ma_keys->dk_lookup == lookdict_split) { + if (dictresize(self, DK_SIZE(self->ma_keys))) { Py_DECREF(res); return NULL; } } - ENSURE_ALLOWS_DELETIONS(mp); + ENSURE_ALLOWS_DELETIONS(self); /* Pop last item */ - ep0 = DK_ENTRIES(mp->ma_keys); - i = mp->ma_keys->dk_nentries - 1; + ep0 = DK_ENTRIES(self->ma_keys); + i = self->ma_keys->dk_nentries - 1; while (i >= 0 && ep0[i].me_value == NULL) { i--; } assert(i >= 0); ep = &ep0[i]; - j = lookdict_index(mp->ma_keys, ep->me_hash, i); + j = lookdict_index(self->ma_keys, ep->me_hash, i); assert(j >= 0); - assert(dictkeys_get_index(mp->ma_keys, j) == i); - dictkeys_set_index(mp->ma_keys, j, DKIX_DUMMY); + assert(dictkeys_get_index(self->ma_keys, j) == i); + dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY); PyTuple_SET_ITEM(res, 0, ep->me_key); PyTuple_SET_ITEM(res, 1, ep->me_value); ep->me_key = NULL; ep->me_value = NULL; /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ - mp->ma_keys->dk_nentries = i; - mp->ma_used--; - mp->ma_version_tag = DICT_NEXT_VERSION(); - assert(_PyDict_CheckConsistency(mp)); + self->ma_keys->dk_nentries = i; + self->ma_used--; + self->ma_version_tag = DICT_NEXT_VERSION(); + ASSERT_CONSISTENT(self); return res; } @@ -3138,14 +3152,6 @@ PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); PyDoc_STRVAR(sizeof__doc__, "D.__sizeof__() -> size of D in memory, in bytes"); -PyDoc_STRVAR(pop__doc__, -"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\ -If key is not found, d is returned if given, otherwise KeyError is raised"); - -PyDoc_STRVAR(popitem__doc__, -"D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\ -2-tuple; but raise KeyError if D is empty."); - PyDoc_STRVAR(update__doc__, "D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n\ If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\ @@ -3178,10 +3184,8 @@ static PyMethodDef mapp_methods[] = { sizeof__doc__}, DICT_GET_METHODDEF DICT_SETDEFAULT_METHODDEF - {"pop", (PyCFunction)dict_pop, METH_VARARGS, - pop__doc__}, - {"popitem", (PyCFunction)(void(*)(void))dict_popitem, METH_NOARGS, - popitem__doc__}, + DICT_POP_METHODDEF + DICT_POPITEM_METHODDEF {"keys", dictkeys_new, METH_NOARGS, keys__doc__}, {"items", dictitems_new, METH_NOARGS, @@ -3271,7 +3275,7 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(self); return NULL; } - assert(_PyDict_CheckConsistency(d)); + ASSERT_CONSISTENT(d); return self; } @@ -3543,6 +3547,12 @@ dictiter_iternextkey(dictiterobject *di) goto fail; key = entry_ptr->me_key; } + // We found an element (key), but did not expect it + if (di->len == 0) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary keys changed during iteration"); + goto fail; + } di->di_pos = i+1; di->len--; Py_INCREF(key); @@ -3624,6 +3634,12 @@ dictiter_iternextvalue(dictiterobject *di) goto fail; value = entry_ptr->me_value; } + // We found an element, but did not expect it + if (di->len == 0) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary keys changed during iteration"); + goto fail; + } di->di_pos = i+1; di->len--; Py_INCREF(value); @@ -3707,6 +3723,12 @@ dictiter_iternextitem(dictiterobject *di) key = entry_ptr->me_key; value = entry_ptr->me_value; } + // We found an element, but did not expect it + if (di->len == 0) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary keys changed during iteration"); + goto fail; + } di->di_pos = i+1; di->len--; Py_INCREF(key); diff --git a/Objects/exceptions.c b/Objects/exceptions.c index ad2a54a2b6b..b40ecb78d45 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1765,9 +1765,9 @@ PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end) int -PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start) +PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end) { - return PyUnicodeEncodeError_GetEnd(exc, start); + return PyUnicodeEncodeError_GetEnd(exc, end); } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index b952df88072..adb9b80c271 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1923,7 +1923,7 @@ PyTypeObject PyFloat_Type = { 0, /* tp_as_mapping */ (hashfunc)float_hash, /* tp_hash */ 0, /* tp_call */ - (reprfunc)float_repr, /* tp_str */ + 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/Objects/longobject.c b/Objects/longobject.c index da697a784fa..9fb1fb02c27 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5592,7 +5592,7 @@ PyTypeObject PyLong_Type = { 0, /* tp_as_mapping */ (hashfunc)long_hash, /* tp_hash */ 0, /* tp_call */ - long_to_decimal_string, /* tp_str */ + 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/Objects/object.c b/Objects/object.c index b446d598130..cb727943cb3 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2,6 +2,7 @@ /* Generic object operations; and implementation of None */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "pycore_context.h" #include "frameobject.h" @@ -19,6 +20,28 @@ _Py_IDENTIFIER(__bytes__); _Py_IDENTIFIER(__dir__); _Py_IDENTIFIER(__isabstractmethod__); + +int +_PyObject_CheckConsistency(PyObject *op, int check_content) +{ + _PyObject_ASSERT(op, op != NULL); + _PyObject_ASSERT(op, !_PyObject_IsFreed(op)); + _PyObject_ASSERT(op, Py_REFCNT(op) >= 1); + + PyTypeObject *type = op->ob_type; + _PyObject_ASSERT(op, type != NULL); + _PyType_CheckConsistency(type); + + if (PyUnicode_Check(op)) { + _PyUnicode_CheckConsistency(op, check_content); + } + else if (PyDict_Check(op)) { + _PyDict_CheckConsistency(op, check_content); + } + return 1; +} + + #ifdef Py_REF_DEBUG Py_ssize_t _Py_RefTotal; @@ -230,6 +253,9 @@ PyObject_Init(PyObject *op, PyTypeObject *tp) return PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ Py_TYPE(op) = tp; + if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(tp); + } _Py_NewReference(op); return op; } @@ -240,9 +266,8 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) if (op == NULL) return (PyVarObject *) PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT_VAR */ - op->ob_size = size; - Py_TYPE(op) = tp; - _Py_NewReference((PyObject *)op); + Py_SIZE(op) = size; + PyObject_Init((PyObject *)op, tp); return op; } @@ -360,7 +385,7 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) universally available */ Py_BEGIN_ALLOW_THREADS fprintf(fp, "", - (long)op->ob_refcnt, op); + (long)op->ob_refcnt, (void *)op); Py_END_ALLOW_THREADS } else { @@ -413,28 +438,26 @@ _Py_BreakPoint(void) } -/* Heuristic checking if the object memory has been deallocated. - Rely on the debug hooks on Python memory allocators which fills the memory - with DEADBYTE (0xDB) when memory is deallocated. +/* Heuristic checking if the object memory is uninitialized or deallocated. + Rely on the debug hooks on Python memory allocators: + see _PyMem_IsPtrFreed(). The function can be used to prevent segmentation fault on dereferencing - pointers like 0xdbdbdbdbdbdbdbdb. Such pointer is very unlikely to be mapped - in memory. */ + pointers like 0xDDDDDDDDDDDDDDDD. */ int _PyObject_IsFreed(PyObject *op) { - uintptr_t ptr = (uintptr_t)op; - if (_PyMem_IsFreed(&ptr, sizeof(ptr))) { + if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(op->ob_type)) { return 1; } - int freed = _PyMem_IsFreed(&op->ob_type, sizeof(op->ob_type)); - /* ignore op->ob_ref: the value can have be modified + /* ignore op->ob_ref: its value can have be modified by Py_INCREF() and Py_DECREF(). */ #ifdef Py_TRACE_REFS - freed &= _PyMem_IsFreed(&op->_ob_next, sizeof(op->_ob_next)); - freed &= _PyMem_IsFreed(&op->_ob_prev, sizeof(op->_ob_prev)); + if (_PyMem_IsPtrFreed(op->_ob_next) || _PyMem_IsPtrFreed(op->_ob_prev)) { + return 1; + } #endif - return freed; + return 0; } @@ -451,7 +474,7 @@ _PyObject_Dump(PyObject* op) if (_PyObject_IsFreed(op)) { /* It seems like the object memory has been freed: don't access it to prevent a segmentation fault. */ - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); return; } @@ -476,7 +499,7 @@ _PyObject_Dump(PyObject* op) "address : %p\n", Py_TYPE(op)==NULL ? "NULL" : Py_TYPE(op)->tp_name, (long)op->ob_refcnt, - op); + (void *)op); fflush(stderr); } @@ -1021,8 +1044,10 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) } if (tp->tp_setattr != NULL) { const char *name_str = PyUnicode_AsUTF8(name); - if (name_str == NULL) + if (name_str == NULL) { + Py_DECREF(name); return -1; + } err = (*tp->tp_setattr)(v, (char *)name_str, value); Py_DECREF(name); return err; @@ -1869,7 +1894,7 @@ _Py_PrintReferences(FILE *fp) PyObject *op; fprintf(fp, "Remaining objects:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { - fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", op, op->ob_refcnt); + fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, op->ob_refcnt); if (PyObject_Print(op, fp, 0) != 0) PyErr_Clear(); putc('\n', fp); @@ -1885,7 +1910,7 @@ _Py_PrintReferenceAddresses(FILE *fp) PyObject *op; fprintf(fp, "Remaining object addresses:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) - fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", op, + fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op, op->ob_refcnt, Py_TYPE(op)->tp_name); } @@ -2136,10 +2161,16 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, else if (_PyObject_IsFreed(obj)) { /* It seems like the object memory has been freed: don't access it to prevent a segmentation fault. */ - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); + } + else if (Py_TYPE(obj) == NULL) { + fprintf(stderr, "\n"); + } + else if (_PyObject_IsFreed((PyObject *)Py_TYPE(obj))) { + fprintf(stderr, "\n", (void *)Py_TYPE(obj)); } else { - /* Diplay the traceback where the object has been allocated. + /* Display the traceback where the object has been allocated. Do it before dumping repr(obj), since repr() is more likely to crash than dumping the traceback. */ void *ptr; diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 1c2a32050f9..7cfd2896596 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1914,15 +1914,22 @@ _Py_GetAllocatedBlocks(void) /* Special bytes broadcast into debug memory blocks at appropriate times. * Strings of these are unlikely to be valid addresses, floats, ints or - * 7-bit ASCII. + * 7-bit ASCII. If modified, _PyMem_IsPtrFreed() should be updated as well. + * + * Byte patterns 0xCB, 0xBB and 0xFB have been replaced with 0xCD, 0xDD and + * 0xFD to use the same values than Windows CRT debug malloc() and free(). */ #undef CLEANBYTE #undef DEADBYTE #undef FORBIDDENBYTE -#define CLEANBYTE 0xCB /* clean (newly allocated) memory */ -#define DEADBYTE 0xDB /* dead (newly freed) memory */ -#define FORBIDDENBYTE 0xFB /* untouchable bytes at each end of a block */ +#define CLEANBYTE 0xCD /* clean (newly allocated) memory */ +#define DEADBYTE 0xDD /* dead (newly freed) memory */ +#define FORBIDDENBYTE 0xFD /* untouchable bytes at each end of a block */ +/* Uncomment this define to add the "serialno" field */ +/* #define PYMEM_DEBUG_SERIALNO */ + +#ifdef PYMEM_DEBUG_SERIALNO static size_t serialno = 0; /* incremented on each debug {m,re}alloc */ /* serialno is always incremented via calling this routine. The point is @@ -1933,9 +1940,16 @@ bumpserialno(void) { ++serialno; } +#endif #define SST SIZEOF_SIZE_T +#ifdef PYMEM_DEBUG_SERIALNO +# define PYMEM_DEBUG_EXTRA_BYTES 4 * SST +#else +# define PYMEM_DEBUG_EXTRA_BYTES 3 * SST +#endif + /* Read sizeof(size_t) bytes at p as a big-endian size_t. */ static size_t read_size_t(const void *p) @@ -1964,7 +1978,7 @@ write_size_t(void *p, size_t n) } } -/* Let S = sizeof(size_t). The debug malloc asks for 4*S extra bytes and +/* Let S = sizeof(size_t). The debug malloc asks for 4 * S extra bytes and fills them with useful stuff, here calling the underlying malloc's result p: p[0: S] @@ -1988,6 +2002,9 @@ p[2*S+n+S: 2*S+n+2*S] If "bad memory" is detected later, the serial number gives an excellent way to set a breakpoint on the next run, to capture the instant at which this block was passed out. + +If PYMEM_DEBUG_SERIALNO is not defined (default), the debug malloc only asks +for 3 * S extra bytes, and omits the last serialno field. */ static void * @@ -1997,21 +2014,24 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) uint8_t *p; /* base address of malloc'ed pad block */ uint8_t *data; /* p + 2*SST == pointer to data bytes */ uint8_t *tail; /* data + nbytes == pointer to tail pad bytes */ - size_t total; /* 2 * SST + nbytes + 2 * SST */ + size_t total; /* nbytes + PYMEM_DEBUG_EXTRA_BYTES */ - if (nbytes > (size_t)PY_SSIZE_T_MAX - 4 * SST) { + if (nbytes > (size_t)PY_SSIZE_T_MAX - PYMEM_DEBUG_EXTRA_BYTES) { /* integer overflow: can't represent total as a Py_ssize_t */ return NULL; } - total = nbytes + 4 * SST; + total = nbytes + PYMEM_DEBUG_EXTRA_BYTES; /* Layout: [SSSS IFFF CCCC...CCCC FFFF NNNN] - * ^--- p ^--- data ^--- tail + ^--- p ^--- data ^--- tail S: nbytes stored as size_t I: API identifier (1 byte) F: Forbidden bytes (size_t - 1 bytes before, size_t bytes after) C: Clean bytes used later to store actual data - N: Serial number stored as size_t */ + N: Serial number stored as size_t + + If PYMEM_DEBUG_SERIALNO is not defined (default), the last NNNN field + is omitted. */ if (use_calloc) { p = (uint8_t *)api->alloc.calloc(api->alloc.ctx, 1, total); @@ -2024,7 +2044,9 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) } data = p + 2*SST; +#ifdef PYMEM_DEBUG_SERIALNO bumpserialno(); +#endif /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */ write_size_t(p, nbytes); @@ -2038,7 +2060,9 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) /* at tail, write pad (SST bytes) and serialno (SST bytes) */ tail = data + nbytes; memset(tail, FORBIDDENBYTE, SST); +#ifdef PYMEM_DEBUG_SERIALNO write_size_t(tail + SST, serialno); +#endif return data; } @@ -2059,22 +2083,6 @@ _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) } -/* Heuristic checking if the memory has been freed. Rely on the debug hooks on - Python memory allocators which fills the memory with DEADBYTE (0xDB) when - memory is deallocated. */ -int -_PyMem_IsFreed(void *ptr, size_t size) -{ - unsigned char *bytes = ptr; - for (size_t i=0; i < size; i++) { - if (bytes[i] != DEADBYTE) { - return 0; - } - } - return 1; -} - - /* The debug free first checks the 2*SST bytes on each end for sanity (in particular, that the FORBIDDENBYTEs with the api ID are still intact). Then fills the original bytes with DEADBYTE. @@ -2094,7 +2102,7 @@ _PyMem_DebugRawFree(void *ctx, void *p) _PyMem_DebugCheckAddress(api->api_id, p); nbytes = read_size_t(q); - nbytes += 4 * SST; + nbytes += PYMEM_DEBUG_EXTRA_BYTES; memset(q, DEADBYTE, nbytes); api->alloc.free(api->alloc.ctx, q); } @@ -2114,7 +2122,6 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) uint8_t *tail; /* data + nbytes == pointer to tail pad bytes */ size_t total; /* 2 * SST + nbytes + 2 * SST */ size_t original_nbytes; - size_t block_serialno; #define ERASED_SIZE 64 uint8_t save[2*ERASED_SIZE]; /* A copy of erased bytes. */ @@ -2123,47 +2130,57 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) data = (uint8_t *)p; head = data - 2*SST; original_nbytes = read_size_t(head); - if (nbytes > (size_t)PY_SSIZE_T_MAX - 4*SST) { + if (nbytes > (size_t)PY_SSIZE_T_MAX - PYMEM_DEBUG_EXTRA_BYTES) { /* integer overflow: can't represent total as a Py_ssize_t */ return NULL; } - total = nbytes + 4*SST; + total = nbytes + PYMEM_DEBUG_EXTRA_BYTES; tail = data + original_nbytes; - block_serialno = read_size_t(tail + SST); +#ifdef PYMEM_DEBUG_SERIALNO + size_t block_serialno = read_size_t(tail + SST); +#endif /* Mark the header, the trailer, ERASED_SIZE bytes at the begin and ERASED_SIZE bytes at the end as dead and save the copy of erased bytes. */ if (original_nbytes <= sizeof(save)) { memcpy(save, data, original_nbytes); - memset(data - 2*SST, DEADBYTE, original_nbytes + 4*SST); + memset(data - 2 * SST, DEADBYTE, + original_nbytes + PYMEM_DEBUG_EXTRA_BYTES); } else { memcpy(save, data, ERASED_SIZE); - memset(head, DEADBYTE, ERASED_SIZE + 2*SST); + memset(head, DEADBYTE, ERASED_SIZE + 2 * SST); memcpy(&save[ERASED_SIZE], tail - ERASED_SIZE, ERASED_SIZE); - memset(tail - ERASED_SIZE, DEADBYTE, ERASED_SIZE + 2*SST); + memset(tail - ERASED_SIZE, DEADBYTE, + ERASED_SIZE + PYMEM_DEBUG_EXTRA_BYTES - 2 * SST); } /* Resize and add decorations. */ r = (uint8_t *)api->alloc.realloc(api->alloc.ctx, head, total); if (r == NULL) { + /* if realloc() failed: rewrite header and footer which have + just been erased */ nbytes = original_nbytes; } else { head = r; +#ifdef PYMEM_DEBUG_SERIALNO bumpserialno(); block_serialno = serialno; +#endif } + data = head + 2*SST; write_size_t(head, nbytes); head[SST] = (uint8_t)api->api_id; memset(head + SST + 1, FORBIDDENBYTE, SST-1); - data = head + 2*SST; tail = data + nbytes; memset(tail, FORBIDDENBYTE, SST); +#ifdef PYMEM_DEBUG_SERIALNO write_size_t(tail + SST, block_serialno); +#endif /* Restore saved bytes. */ if (original_nbytes <= sizeof(save)) { @@ -2183,7 +2200,7 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) } if (nbytes > original_nbytes) { - /* growing: mark new extra memory clean */ + /* growing: mark new extra memory clean */ memset(data + original_nbytes, CLEANBYTE, nbytes - original_nbytes); } @@ -2291,7 +2308,7 @@ _PyObject_DebugDumpAddress(const void *p) { const uint8_t *q = (const uint8_t *)p; const uint8_t *tail; - size_t nbytes, serial; + size_t nbytes; int i; int ok; char id; @@ -2337,7 +2354,7 @@ _PyObject_DebugDumpAddress(const void *p) } tail = q + nbytes; - fprintf(stderr, " The %d pad bytes at tail=%p are ", SST, tail); + fprintf(stderr, " The %d pad bytes at tail=%p are ", SST, (void *)tail); ok = 1; for (i = 0; i < SST; ++i) { if (tail[i] != FORBIDDENBYTE) { @@ -2360,9 +2377,11 @@ _PyObject_DebugDumpAddress(const void *p) } } - serial = read_size_t(tail + SST); +#ifdef PYMEM_DEBUG_SERIALNO + size_t serial = read_size_t(tail + SST); fprintf(stderr, " The block was made by call #%" PY_FORMAT_SIZE_T "u to debug malloc/realloc.\n", serial); +#endif if (nbytes > 0) { i = 0; @@ -2588,8 +2607,11 @@ _PyObject_DebugMallocStats(FILE *out) quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size); } fputc('\n', out); - if (_PyMem_DebugEnabled()) +#ifdef PYMEM_DEBUG_SERIALNO + if (_PyMem_DebugEnabled()) { (void)printone(out, "# times object malloc called", serialno); + } +#endif (void)printone(out, "# arenas allocated total", ntimes_arena_allocated); (void)printone(out, "# arenas reclaimed", ntimes_arena_allocated - narenas); (void)printone(out, "# arenas highwater mark", narenas_highwater); diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 4b8e5ed4cfd..ac868f6951c 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -645,7 +645,7 @@ PyDoc_STRVAR(count_doc, "rangeobject.count(value) -> integer -- return number of occurrences of value"); PyDoc_STRVAR(index_doc, -"rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n" +"rangeobject.index(value) -> integer -- return index of value.\n" "Raise ValueError if the value is not present."); static PyMethodDef range_methods[] = { diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 0abb4c8abb9..8645bc26cff 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -260,6 +260,7 @@ Py_LOCAL_INLINE(PyObject *) STRINGLIB(utf8_encoder)(PyObject *unicode, STRINGLIB_CHAR *data, Py_ssize_t size, + _Py_error_handler error_handler, const char *errors) { Py_ssize_t i; /* index into data of next input character */ @@ -268,7 +269,6 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, PyObject *error_handler_obj = NULL; PyObject *exc = NULL; PyObject *rep = NULL; - _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; #endif #if STRINGLIB_SIZEOF_CHAR == 1 const Py_ssize_t max_char_size = 2; diff --git a/Objects/structseq.c b/Objects/structseq.c index cf36fa7f97c..a5046c42cbc 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -63,12 +63,17 @@ static void structseq_dealloc(PyStructSequence *obj) { Py_ssize_t i, size; + PyTypeObject *tp; + tp = (PyTypeObject *) Py_TYPE(obj); size = REAL_SIZE(obj); for (i = 0; i < size; ++i) { Py_XDECREF(obj->ob_item[i]); } PyObject_GC_Del(obj); + if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + Py_DECREF(tp); + } } /*[clinic input] diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 403f3caaee6..eeaae1f9f78 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -131,8 +131,7 @@ skip_signature(const char *doc) return NULL; } -#ifndef NDEBUG -static int +int _PyType_CheckConsistency(PyTypeObject *type) { #define ASSERT(expr) _PyObject_ASSERT((PyObject *)type, (expr)) @@ -142,14 +141,16 @@ _PyType_CheckConsistency(PyTypeObject *type) return 1; } - ASSERT(!(type->tp_flags & Py_TPFLAGS_READYING)); - ASSERT(type->tp_mro != NULL && PyTuple_Check(type->tp_mro)); - ASSERT(type->tp_dict != NULL); - return 1; + ASSERT(!_PyObject_IsFreed((PyObject *)type)); + ASSERT(Py_REFCNT(type) >= 1); + ASSERT(PyType_Check(type)); + ASSERT(!(type->tp_flags & Py_TPFLAGS_READYING)); + ASSERT(type->tp_dict != NULL); + + return 1; #undef ASSERT } -#endif static const char * _PyType_DocWithoutSignature(const char *name, const char *internal_doc) @@ -987,9 +988,6 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) memset(obj, '\0', size); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(type); - if (type->tp_itemsize == 0) (void)PyObject_INIT(obj, type); else @@ -2897,6 +2895,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) nmembers = 0; for (slot = spec->slots; slot->slot; slot++) { if (slot->slot == Py_tp_members) { + nmembers = 0; for (memb = slot->pfunc; memb->name != NULL; memb++) { nmembers++; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8ab3943e61b..eaba5836cb1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -40,8 +40,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_coreconfig.h" #include "pycore_fileutils.h" #include "pycore_object.h" +#include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "ucnhash.h" #include "bytes_methods.h" @@ -263,6 +265,13 @@ unicode_fill(enum PyUnicode_Kind kind, void *data, Py_UCS4 value, /* Forward declaration */ static inline int _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); +static PyObject * +unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, + const char *errors); +static PyObject * +unicode_decode_utf8(const char *s, Py_ssize_t size, + _Py_error_handler error_handler, const char *errors, + Py_ssize_t *consumed); /* List of static strings. */ static _Py_Identifier *static_strings = NULL; @@ -387,6 +396,35 @@ _Py_GetErrorHandler(const char *errors) return _Py_ERROR_OTHER; } + +static _Py_error_handler +get_error_handler_wide(const wchar_t *errors) +{ + if (errors == NULL || wcscmp(errors, L"strict") == 0) { + return _Py_ERROR_STRICT; + } + if (wcscmp(errors, L"surrogateescape") == 0) { + return _Py_ERROR_SURROGATEESCAPE; + } + if (wcscmp(errors, L"replace") == 0) { + return _Py_ERROR_REPLACE; + } + if (wcscmp(errors, L"ignore") == 0) { + return _Py_ERROR_IGNORE; + } + if (wcscmp(errors, L"backslashreplace") == 0) { + return _Py_ERROR_BACKSLASHREPLACE; + } + if (wcscmp(errors, L"surrogatepass") == 0) { + return _Py_ERROR_SURROGATEPASS; + } + if (wcscmp(errors, L"xmlcharrefreplace") == 0) { + return _Py_ERROR_XMLCHARREFREPLACE; + } + return _Py_ERROR_OTHER; +} + + /* The max unicode value is always 0x10FFFF while using the PEP-393 API. This function is kept for backward compatibility with the old API. */ Py_UNICODE @@ -401,23 +439,20 @@ PyUnicode_GetMax(void) #endif } -#ifdef Py_DEBUG int _PyUnicode_CheckConsistency(PyObject *op, int check_content) { -#define ASSERT(expr) _PyObject_ASSERT(op, (expr)) - PyASCIIObject *ascii; unsigned int kind; - ASSERT(PyUnicode_Check(op)); + _PyObject_ASSERT(op, PyUnicode_Check(op)); ascii = (PyASCIIObject *)op; kind = ascii->state.kind; if (ascii->state.ascii == 1 && ascii->state.compact == 1) { - ASSERT(kind == PyUnicode_1BYTE_KIND); - ASSERT(ascii->state.ready == 1); + _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND); + _PyObject_ASSERT(op, ascii->state.ready == 1); } else { PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; @@ -425,41 +460,41 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) if (ascii->state.compact == 1) { data = compact + 1; - ASSERT(kind == PyUnicode_1BYTE_KIND - || kind == PyUnicode_2BYTE_KIND - || kind == PyUnicode_4BYTE_KIND); - ASSERT(ascii->state.ascii == 0); - ASSERT(ascii->state.ready == 1); - ASSERT (compact->utf8 != data); + _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + _PyObject_ASSERT(op, ascii->state.ascii == 0); + _PyObject_ASSERT(op, ascii->state.ready == 1); + _PyObject_ASSERT(op, compact->utf8 != data); } else { PyUnicodeObject *unicode = (PyUnicodeObject *)op; data = unicode->data.any; if (kind == PyUnicode_WCHAR_KIND) { - ASSERT(ascii->length == 0); - ASSERT(ascii->hash == -1); - ASSERT(ascii->state.compact == 0); - ASSERT(ascii->state.ascii == 0); - ASSERT(ascii->state.ready == 0); - ASSERT(ascii->state.interned == SSTATE_NOT_INTERNED); - ASSERT(ascii->wstr != NULL); - ASSERT(data == NULL); - ASSERT(compact->utf8 == NULL); + _PyObject_ASSERT(op, ascii->length == 0); + _PyObject_ASSERT(op, ascii->hash == -1); + _PyObject_ASSERT(op, ascii->state.compact == 0); + _PyObject_ASSERT(op, ascii->state.ascii == 0); + _PyObject_ASSERT(op, ascii->state.ready == 0); + _PyObject_ASSERT(op, ascii->state.interned == SSTATE_NOT_INTERNED); + _PyObject_ASSERT(op, ascii->wstr != NULL); + _PyObject_ASSERT(op, data == NULL); + _PyObject_ASSERT(op, compact->utf8 == NULL); } else { - ASSERT(kind == PyUnicode_1BYTE_KIND - || kind == PyUnicode_2BYTE_KIND - || kind == PyUnicode_4BYTE_KIND); - ASSERT(ascii->state.compact == 0); - ASSERT(ascii->state.ready == 1); - ASSERT(data != NULL); + _PyObject_ASSERT(op, kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + _PyObject_ASSERT(op, ascii->state.compact == 0); + _PyObject_ASSERT(op, ascii->state.ready == 1); + _PyObject_ASSERT(op, data != NULL); if (ascii->state.ascii) { - ASSERT (compact->utf8 == data); - ASSERT (compact->utf8_length == ascii->length); + _PyObject_ASSERT(op, compact->utf8 == data); + _PyObject_ASSERT(op, compact->utf8_length == ascii->length); } else - ASSERT (compact->utf8 != data); + _PyObject_ASSERT(op, compact->utf8 != data); } } if (kind != PyUnicode_WCHAR_KIND) { @@ -471,20 +506,20 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #endif ) { - ASSERT(ascii->wstr == data); - ASSERT(compact->wstr_length == ascii->length); + _PyObject_ASSERT(op, ascii->wstr == data); + _PyObject_ASSERT(op, compact->wstr_length == ascii->length); } else - ASSERT(ascii->wstr != data); + _PyObject_ASSERT(op, ascii->wstr != data); } if (compact->utf8 == NULL) - ASSERT(compact->utf8_length == 0); + _PyObject_ASSERT(op, compact->utf8_length == 0); if (ascii->wstr == NULL) - ASSERT(compact->wstr_length == 0); + _PyObject_ASSERT(op, compact->wstr_length == 0); } - /* check that the best kind is used */ - if (check_content && kind != PyUnicode_WCHAR_KIND) - { + + /* check that the best kind is used: O(n) operation */ + if (check_content && kind != PyUnicode_WCHAR_KIND) { Py_ssize_t i; Py_UCS4 maxchar = 0; void *data; @@ -499,27 +534,25 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) } if (kind == PyUnicode_1BYTE_KIND) { if (ascii->state.ascii == 0) { - ASSERT(maxchar >= 128); - ASSERT(maxchar <= 255); + _PyObject_ASSERT(op, maxchar >= 128); + _PyObject_ASSERT(op, maxchar <= 255); } else - ASSERT(maxchar < 128); + _PyObject_ASSERT(op, maxchar < 128); } else if (kind == PyUnicode_2BYTE_KIND) { - ASSERT(maxchar >= 0x100); - ASSERT(maxchar <= 0xFFFF); + _PyObject_ASSERT(op, maxchar >= 0x100); + _PyObject_ASSERT(op, maxchar <= 0xFFFF); } else { - ASSERT(maxchar >= 0x10000); - ASSERT(maxchar <= MAX_UNICODE); + _PyObject_ASSERT(op, maxchar >= 0x10000); + _PyObject_ASSERT(op, maxchar <= MAX_UNICODE); } - ASSERT(PyUnicode_READ(kind, data, ascii->length) == 0); + _PyObject_ASSERT(op, PyUnicode_READ(kind, data, ascii->length) == 0); } return 1; - -#undef ASSERT } -#endif + static PyObject* unicode_result_wchar(PyObject *unicode) @@ -1218,7 +1251,7 @@ void *_PyUnicode_compact_data(void *unicode_raw) { } void *_PyUnicode_data(void *unicode_raw) { PyObject *unicode = _PyObject_CAST(unicode_raw); - printf("obj %p\n", unicode); + printf("obj %p\n", (void*)unicode); printf("compact %d\n", PyUnicode_IS_COMPACT(unicode)); printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode)); printf("ascii op %p\n", ((void*)((PyASCIIObject*)(unicode) + 1))); @@ -1249,14 +1282,14 @@ _PyUnicode_Dump(PyObject *op) if (ascii->wstr == data) printf("shared "); - printf("wstr=%p", ascii->wstr); + printf("wstr=%p", (void *)ascii->wstr); if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { printf(" (%" PY_FORMAT_SIZE_T "u), ", compact->wstr_length); if (!ascii->state.compact && compact->utf8 == unicode->data.any) printf("shared "); printf("utf8=%p (%" PY_FORMAT_SIZE_T "u)", - compact->utf8, compact->utf8_length); + (void *)compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); } @@ -3449,11 +3482,9 @@ PyUnicode_AsEncodedObject(PyObject *unicode, static PyObject * -unicode_encode_locale(PyObject *unicode, const char *errors, +unicode_encode_locale(PyObject *unicode, _Py_error_handler error_handler, int current_locale) { - _Py_error_handler error_handler = _Py_GetErrorHandler(errors); - Py_ssize_t wlen; wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &wlen); if (wstr == NULL) { @@ -3503,30 +3534,44 @@ unicode_encode_locale(PyObject *unicode, const char *errors, PyObject * PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) { - return unicode_encode_locale(unicode, errors, 1); + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + return unicode_encode_locale(unicode, error_handler, 1); } PyObject * PyUnicode_EncodeFSDefault(PyObject *unicode) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; -#if defined(__APPLE__) - return _PyUnicode_AsUTF8String(unicode, config->filesystem_errors); +#ifdef _Py_FORCE_UTF8_FS_ENCODING + if (interp->fs_codec.encoding) { + return unicode_encode_utf8(unicode, + interp->fs_codec.error_handler, + interp->fs_codec.errors); + } + else { + const _PyCoreConfig *config = &interp->core_config; + _Py_error_handler errors; + errors = get_error_handler_wide(config->filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); + return unicode_encode_utf8(unicode, errors, NULL); + } #else /* Bootstrap check: if the filesystem codec is implemented in Python, we cannot use it to encode and decode filenames before it is loaded. Load the Python codec requires to encode at least its own filename. Use the C implementation of the locale codec until the codec registry is initialized and the Python codec is loaded. See initfsencoding(). */ - if (interp->fscodec_initialized) { + if (interp->fs_codec.encoding) { return PyUnicode_AsEncodedString(unicode, - config->filesystem_encoding, - config->filesystem_errors); + interp->fs_codec.encoding, + interp->fs_codec.errors); } else { - return unicode_encode_locale(unicode, - config->filesystem_errors, 0); + const _PyCoreConfig *config = &interp->core_config; + _Py_error_handler errors; + errors = get_error_handler_wide(config->filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); + return unicode_encode_locale(unicode, errors, 0); } #endif } @@ -3667,11 +3712,9 @@ PyUnicode_AsEncodedUnicode(PyObject *unicode, } static PyObject* -unicode_decode_locale(const char *str, Py_ssize_t len, const char *errors, - int current_locale) +unicode_decode_locale(const char *str, Py_ssize_t len, + _Py_error_handler errors, int current_locale) { - _Py_error_handler error_handler = _Py_GetErrorHandler(errors); - if (str[len] != '\0' || (size_t)len != strlen(str)) { PyErr_SetString(PyExc_ValueError, "embedded null byte"); return NULL; @@ -3681,7 +3724,7 @@ unicode_decode_locale(const char *str, Py_ssize_t len, const char *errors, size_t wlen; const char *reason; int res = _Py_DecodeLocaleEx(str, &wstr, &wlen, &reason, - current_locale, error_handler); + current_locale, errors); if (res != 0) { if (res == -2) { PyObject *exc; @@ -3713,14 +3756,16 @@ PyObject* PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, const char *errors) { - return unicode_decode_locale(str, len, errors, 1); + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + return unicode_decode_locale(str, len, error_handler, 1); } PyObject* PyUnicode_DecodeLocale(const char *str, const char *errors) { Py_ssize_t size = (Py_ssize_t)strlen(str); - return unicode_decode_locale(str, size, errors, 1); + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + return unicode_decode_locale(str, size, error_handler, 1); } @@ -3734,23 +3779,36 @@ PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; -#if defined(__APPLE__) - return PyUnicode_DecodeUTF8Stateful(s, size, config->filesystem_errors, NULL); +#ifdef _Py_FORCE_UTF8_FS_ENCODING + if (interp->fs_codec.encoding) { + return unicode_decode_utf8(s, size, + interp->fs_codec.error_handler, + interp->fs_codec.errors, + NULL); + } + else { + const _PyCoreConfig *config = &interp->core_config; + _Py_error_handler errors; + errors = get_error_handler_wide(config->filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); + return unicode_decode_utf8(s, size, errors, NULL, NULL); + } #else /* Bootstrap check: if the filesystem codec is implemented in Python, we cannot use it to encode and decode filenames before it is loaded. Load the Python codec requires to encode at least its own filename. Use the C implementation of the locale codec until the codec registry is initialized and the Python codec is loaded. See initfsencoding(). */ - if (interp->fscodec_initialized) { + if (interp->fs_codec.encoding) { return PyUnicode_Decode(s, size, - config->filesystem_encoding, - config->filesystem_errors); + interp->fs_codec.encoding, + interp->fs_codec.errors); } else { - return unicode_decode_locale(s, size, - config->filesystem_errors, 0); + const _PyCoreConfig *config = &interp->core_config; + _Py_error_handler errors; + errors = get_error_handler_wide(config->filesystem_errors); + return unicode_decode_locale(s, size, errors, 0); } #endif } @@ -4814,11 +4872,10 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) return p - start; } -PyObject * -PyUnicode_DecodeUTF8Stateful(const char *s, - Py_ssize_t size, - const char *errors, - Py_ssize_t *consumed) +static PyObject * +unicode_decode_utf8(const char *s, Py_ssize_t size, + _Py_error_handler error_handler, const char *errors, + Py_ssize_t *consumed) { _PyUnicodeWriter writer; const char *starts = s; @@ -4829,7 +4886,6 @@ PyUnicode_DecodeUTF8Stateful(const char *s, const char *errmsg = ""; PyObject *error_handler_obj = NULL; PyObject *exc = NULL; - _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; if (size == 0) { if (consumed) @@ -4883,6 +4939,9 @@ PyUnicode_DecodeUTF8Stateful(const char *s, case 2: case 3: case 4: + if (s == end || consumed) { + goto End; + } errmsg = "invalid continuation byte"; startinpos = s - starts; endinpos = startinpos + ch - 1; @@ -4949,6 +5008,16 @@ PyUnicode_DecodeUTF8Stateful(const char *s, } +PyObject * +PyUnicode_DecodeUTF8Stateful(const char *s, + Py_ssize_t size, + const char *errors, + Py_ssize_t *consumed) +{ + return unicode_decode_utf8(s, size, _Py_ERROR_UNKNOWN, errors, consumed); +} + + /* UTF-8 decoder: use surrogateescape error handler if 'surrogateescape' is non-zero, use strict error handler otherwise. @@ -5232,8 +5301,9 @@ _Py_EncodeUTF8Ex(const wchar_t *text, char **str, size_t *error_pos, maximum possible needed (4 result bytes per Unicode character), and return the excess memory at the end. */ -PyObject * -_PyUnicode_AsUTF8String(PyObject *unicode, const char *errors) +static PyObject * +unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, + const char *errors) { enum PyUnicode_Kind kind; void *data; @@ -5261,14 +5331,21 @@ _PyUnicode_AsUTF8String(PyObject *unicode, const char *errors) case PyUnicode_1BYTE_KIND: /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ assert(!PyUnicode_IS_ASCII(unicode)); - return ucs1lib_utf8_encoder(unicode, data, size, errors); + return ucs1lib_utf8_encoder(unicode, data, size, error_handler, errors); case PyUnicode_2BYTE_KIND: - return ucs2lib_utf8_encoder(unicode, data, size, errors); + return ucs2lib_utf8_encoder(unicode, data, size, error_handler, errors); case PyUnicode_4BYTE_KIND: - return ucs4lib_utf8_encoder(unicode, data, size, errors); + return ucs4lib_utf8_encoder(unicode, data, size, error_handler, errors); } } +PyObject * +_PyUnicode_AsUTF8String(PyObject *unicode, const char *errors) +{ + return unicode_encode_utf8(unicode, _Py_ERROR_UNKNOWN, errors); +} + + PyObject * PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, @@ -9672,7 +9749,7 @@ do_capitalize(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *ma Py_UCS4 c, mapped[3]; c = PyUnicode_READ(kind, data, 0); - n_res = _PyUnicode_ToUpperFull(c, mapped); + n_res = _PyUnicode_ToTitleFull(c, mapped); for (j = 0; j < n_res; j++) { *maxchar = Py_MAX(*maxchar, mapped[j]); res[k++] = mapped[j]; @@ -15576,6 +15653,188 @@ PyUnicode_AsUnicodeCopy(PyObject *unicode) } +static int +encode_wstr_utf8(wchar_t *wstr, char **str, const char *name) +{ + int res; + res = _Py_EncodeUTF8Ex(wstr, str, NULL, NULL, 1, _Py_ERROR_STRICT); + if (res == -2) { + PyErr_Format(PyExc_RuntimeWarning, "cannot decode %s", name); + return -1; + } + if (res < 0) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + + +static int +config_get_codec_name(wchar_t **config_encoding) +{ + char *encoding; + if (encode_wstr_utf8(*config_encoding, &encoding, "stdio_encoding") < 0) { + return -1; + } + + PyObject *name_obj = NULL; + PyObject *codec = _PyCodec_Lookup(encoding); + PyMem_RawFree(encoding); + + if (!codec) + goto error; + + name_obj = PyObject_GetAttrString(codec, "name"); + Py_CLEAR(codec); + if (!name_obj) { + goto error; + } + + wchar_t *wname = PyUnicode_AsWideCharString(name_obj, NULL); + Py_DECREF(name_obj); + if (wname == NULL) { + goto error; + } + + wchar_t *raw_wname = _PyMem_RawWcsdup(wname); + if (raw_wname == NULL) { + PyMem_Free(wname); + PyErr_NoMemory(); + goto error; + } + + PyMem_RawFree(*config_encoding); + *config_encoding = raw_wname; + + PyMem_Free(wname); + return 0; + +error: + Py_XDECREF(codec); + Py_XDECREF(name_obj); + return -1; +} + + +static _PyInitError +init_stdio_encoding(PyInterpreterState *interp) +{ + /* Update the stdio encoding to the normalized Python codec name. */ + _PyCoreConfig *config = &interp->core_config; + if (config_get_codec_name(&config->stdio_encoding) < 0) { + return _Py_INIT_ERR("failed to get the Python codec name " + "of the stdio encoding"); + } + return _Py_INIT_OK(); +} + + +static int +init_fs_codec(PyInterpreterState *interp) +{ + _PyCoreConfig *config = &interp->core_config; + + _Py_error_handler error_handler; + error_handler = get_error_handler_wide(config->filesystem_errors); + if (error_handler == _Py_ERROR_UNKNOWN) { + PyErr_SetString(PyExc_RuntimeError, "unknow filesystem error handler"); + return -1; + } + + char *encoding, *errors; + if (encode_wstr_utf8(config->filesystem_encoding, + &encoding, + "filesystem_encoding") < 0) { + return -1; + } + + if (encode_wstr_utf8(config->filesystem_errors, + &errors, + "filesystem_errors") < 0) { + PyMem_RawFree(encoding); + return -1; + } + + PyMem_RawFree(interp->fs_codec.encoding); + interp->fs_codec.encoding = encoding; + PyMem_RawFree(interp->fs_codec.errors); + interp->fs_codec.errors = errors; + interp->fs_codec.error_handler = error_handler; + + /* At this point, PyUnicode_EncodeFSDefault() and + PyUnicode_DecodeFSDefault() can now use the Python codec rather than + the C implementation of the filesystem encoding. */ + + /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors + global configuration variables. */ + if (_Py_SetFileSystemEncoding(interp->fs_codec.encoding, + interp->fs_codec.errors) < 0) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + + +static _PyInitError +init_fs_encoding(PyInterpreterState *interp) +{ + /* Update the filesystem encoding to the normalized Python codec name. + For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii" + (Python codec name). */ + _PyCoreConfig *config = &interp->core_config; + if (config_get_codec_name(&config->filesystem_encoding) < 0) { + return _Py_INIT_ERR("failed to get the Python codec " + "of the filesystem encoding"); + } + + if (init_fs_codec(interp) < 0) { + return _Py_INIT_ERR("cannot initialize filesystem codec"); + } + return _Py_INIT_OK(); +} + + +_PyInitError +_PyUnicode_InitEncodings(PyInterpreterState *interp) +{ + _PyInitError err = init_fs_encoding(interp); + if (_Py_INIT_FAILED(err)) { + return err; + } + + return init_stdio_encoding(interp); +} + + +#ifdef MS_WINDOWS +int +_PyUnicode_EnableLegacyWindowsFSEncoding(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + _PyCoreConfig *config = &interp->core_config; + + /* Set the filesystem encoding to mbcs/replace (PEP 529) */ + wchar_t *encoding = _PyMem_RawWcsdup(L"mbcs"); + wchar_t *errors = _PyMem_RawWcsdup(L"replace"); + if (encoding == NULL || errors == NULL) { + PyMem_RawFree(encoding); + PyMem_RawFree(errors); + PyErr_NoMemory(); + return -1; + } + + PyMem_RawFree(config->filesystem_encoding); + config->filesystem_encoding = encoding; + PyMem_RawFree(config->filesystem_errors); + config->filesystem_errors = errors; + + return init_fs_codec(interp); +} +#endif + + void _PyUnicode_Fini(void) { @@ -15599,6 +15858,12 @@ _PyUnicode_Fini(void) } _PyUnicode_ClearStaticStrings(); (void)PyUnicode_ClearFreeList(); + + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + PyMem_RawFree(interp->fs_codec.encoding); + interp->fs_codec.encoding = NULL; + PyMem_RawFree(interp->fs_codec.errors); + interp->fs_codec.errors = NULL; } diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index e64b5059342..957bd4c6212 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -1750,7 +1750,7 @@ const Py_UCS4 _PyUnicode_ExtendedCase[] = { /* type indexes */ #define SHIFT 7 -static unsigned short index1[] = { +static const unsigned short index1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, @@ -2359,7 +2359,7 @@ static unsigned short index1[] = { 126, 126, 126, 126, 126, 126, 126, 269, }; -static unsigned short index2[] = { +static const unsigned short index2[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2, 4, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 9227aa688f4..ff6d92254f7 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -525,6 +525,8 @@ WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd) WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor) WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr) WRAP_UNARY(proxy_index, PyNumber_Index) +WRAP_BINARY(proxy_matmul, PyNumber_MatrixMultiply) +WRAP_BINARY(proxy_imatmul, PyNumber_InPlaceMatrixMultiply) static int proxy_bool(PyWeakReference *proxy) @@ -642,6 +644,8 @@ static PyNumberMethods proxy_as_number = { proxy_ifloor_div, /*nb_inplace_floor_divide*/ proxy_itrue_div, /*nb_inplace_true_divide*/ proxy_index, /*nb_index*/ + proxy_matmul, /*nb_matrix_multiply*/ + proxy_imatmul, /*nb_inplace_matrix_multiply*/ }; static PySequenceMethods proxy_as_sequence = { diff --git a/PC/bdist_wininst/bdist_wininst.vcxproj b/PC/bdist_wininst/bdist_wininst.vcxproj index 70bfb9c9337..d2f1bb75e30 100644 --- a/PC/bdist_wininst/bdist_wininst.vcxproj +++ b/PC/bdist_wininst/bdist_wininst.vcxproj @@ -1,6 +1,10 @@  + + Debug + ARM + Debug Win32 @@ -9,6 +13,10 @@ Debug x64 + + PGInstrument + ARM + PGInstrument Win32 @@ -17,6 +25,10 @@ PGInstrument x64 + + PGUpdate + ARM + PGUpdate Win32 @@ -25,6 +37,10 @@ PGUpdate x64 + + Release + ARM + Release Win32 diff --git a/PC/launcher.c b/PC/launcher.c index 0f5003a8370..ed5ead329e4 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -1139,7 +1139,7 @@ static PYC_MAGIC magic_values[] = { { 3320, 3351, L"3.5" }, { 3360, 3379, L"3.6" }, { 3390, 3399, L"3.7" }, - { 3400, 3409, L"3.8" }, + { 3400, 3410, L"3.8" }, { 0 } }; diff --git a/PC/layout/main.py b/PC/layout/main.py index 910085c01bb..624033e721b 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -52,7 +52,7 @@ EXCLUDE_FROM_COMPILE = FileNameSet("badsyntax_*", "bad_*") EXCLUDE_FROM_CATALOG = FileSuffixSet(".exe", ".pyd", ".dll") -REQUIRED_DLLS = FileStemSet("libcrypto*", "libssl*") +REQUIRED_DLLS = FileStemSet("libcrypto*", "libssl*", "libffi*") LIB2TO3_GRAMMAR_FILES = FileNameSet("Grammar.txt", "PatternGrammar.txt") @@ -66,6 +66,18 @@ TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") +def copy_if_modified(src, dest): + try: + dest_stat = os.stat(dest) + except FileNotFoundError: + do_copy = True + else: + src_stat = os.stat(src) + do_copy = (src_stat.st_mtime != dest_stat.st_mtime or + src_stat.st_size != dest_stat.st_size) + + if do_copy: + shutil.copy2(src, dest) def get_lib_layout(ns): def _c(f): @@ -426,7 +438,7 @@ def copy_files(files, ns): need_compile.append((dest, ns.copy / dest)) else: (ns.temp / "Lib" / dest).parent.mkdir(parents=True, exist_ok=True) - shutil.copy2(src, ns.temp / "Lib" / dest) + copy_if_modified(src, ns.temp / "Lib" / dest) need_compile.append((dest, ns.temp / "Lib" / dest)) if src not in EXCLUDE_FROM_CATALOG: @@ -436,7 +448,7 @@ def copy_files(files, ns): log_debug("Copy {} -> {}", src, ns.copy / dest) (ns.copy / dest).parent.mkdir(parents=True, exist_ok=True) try: - shutil.copy2(src, ns.copy / dest) + copy_if_modified(src, ns.copy / dest) except shutil.SameFileError: pass diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index c5dda70c7ef..49a35fa1f04 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -159,21 +159,20 @@ def public(f): "SysVersion": VER_DOT, "Version": "{}.{}.{}".format(VER_MAJOR, VER_MINOR, VER_MICRO), "InstallPath": { - # I have no idea why the trailing spaces are needed, but they seem to be needed. - "": "[{AppVPackageRoot}][ ]", - "ExecutablePath": "[{AppVPackageRoot}]python.exe[ ]", - "WindowedExecutablePath": "[{AppVPackageRoot}]pythonw.exe[ ]", + "": "[{AppVPackageRoot}]", + "ExecutablePath": "[{AppVPackageRoot}]\\python.exe", + "WindowedExecutablePath": "[{AppVPackageRoot}]\\pythonw.exe", }, "Help": { "Main Python Documentation": { "_condition": lambda ns: ns.include_chm, - "": "[{{AppVPackageRoot}}]Doc\\{}[ ]".format( + "": "[{{AppVPackageRoot}}]\\Doc\\{}".format( PYTHON_CHM_NAME ), }, "Local Python Documentation": { "_condition": lambda ns: ns.include_html_doc, - "": "[{AppVPackageRoot}]Doc\\html\\index.html[ ]", + "": "[{AppVPackageRoot}]\\Doc\\html\\index.html", }, "Online Python Documentation": { "": "https://docs.python.org/{}".format(VER_DOT) @@ -181,7 +180,7 @@ def public(f): }, "Idle": { "_condition": lambda ns: ns.include_idle, - "": "[{AppVPackageRoot}]Lib\\idlelib\\idle.pyw[ ]", + "": "[{AppVPackageRoot}]\\Lib\\idlelib\\idle.pyw", }, } } diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index 76d9e34e1f4..00f05667ebb 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -53,7 +53,19 @@ def public(f): }, "nuget": { "help": "nuget package", - "options": ["stable", "pip", "distutils", "dev", "props"], + "options": [ + "dev", + "tools", + "pip", + "stable", + "distutils", + "venv", + "props" + ], + }, + "iot": { + "help": "Windows IoT Core", + "options": ["stable", "pip"], }, "default": { "help": "development kit package", diff --git a/PC/winreg.c b/PC/winreg.c index ae0c292b717..5469fcba044 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -521,7 +521,7 @@ fixupMultiSZ(wchar_t **str, wchar_t *data, int len) Q = data + len; for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) { str[i] = P; - for(; *P != '\0'; P++) + for (; P < Q && *P != '\0'; P++) ; } } @@ -1614,7 +1614,7 @@ winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, } Py_BEGIN_ALLOW_THREADS - rc = RegSetValueW(key, sub_key, REG_SZ, value, value_length+1); + rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1)); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); diff --git a/PCbuild/_ctypes.vcxproj b/PCbuild/_ctypes.vcxproj index d4c9f87b6fe..a265427a656 100644 --- a/PCbuild/_ctypes.vcxproj +++ b/PCbuild/_ctypes.vcxproj @@ -70,6 +70,7 @@ + @@ -77,7 +78,7 @@ - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) + FFI_BUILDING;%(PreprocessorDefinitions) /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) @@ -86,32 +87,14 @@ - - - - - - - 4267;%(DisableSpecificWarnings) - - - true - - - - - true - ml64 /nologo /c /Zi /Fo "$(IntDir)win64.obj" "%(FullPath)" - $(IntDir)win64.obj;%(Outputs) - @@ -122,4 +105,4 @@ - \ No newline at end of file + diff --git a/PCbuild/_ctypes.vcxproj.filters b/PCbuild/_ctypes.vcxproj.filters index 83d7a7b67ab..3123286347a 100644 --- a/PCbuild/_ctypes.vcxproj.filters +++ b/PCbuild/_ctypes.vcxproj.filters @@ -15,18 +15,6 @@ Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - @@ -41,25 +29,14 @@ Source Files - - Source Files - Source Files - - Source Files - Source Files - - Source Files - - - Source Files - + \ No newline at end of file diff --git a/PCbuild/_freeze_importlib.vcxproj b/PCbuild/_freeze_importlib.vcxproj index 998fba6bb54..76885d8b354 100644 --- a/PCbuild/_freeze_importlib.vcxproj +++ b/PCbuild/_freeze_importlib.vcxproj @@ -125,9 +125,9 @@ - - + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + ARM + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + ARM + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + {900342D7-516A-4469-B1AD-59A66E49A25F} + _testinternalcapi + Win32Proj + false + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + diff --git a/PCbuild/_testinternalcapi.vcxproj.filters b/PCbuild/_testinternalcapi.vcxproj.filters new file mode 100644 index 00000000000..4644f230be1 --- /dev/null +++ b/PCbuild/_testinternalcapi.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + {136fc5eb-7fe4-4486-8c6d-b49f37a00199} + + + + + Source Files + + + diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 759aa5221b4..cd0c07abbf3 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -41,7 +41,7 @@ echo. echo.Available arguments: echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate echo. Set the configuration (default: Release) -echo. -p x64 ^| Win32 +echo. -p x64 ^| Win32 ^| ARM echo. Set the platform (default: Win32) echo. -t Build ^| Rebuild ^| Clean ^| CleanAll echo. Set the target manually diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index cbeb5a19b55..b82b6e6588e 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -2,19 +2,22 @@ setlocal rem Simple script to fetch source for external libraries -if "%PCBUILD%"=="" (set PCBUILD=%~dp0) -if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%PCBUILD%\..\externals) +if NOT DEFINED PCBUILD (set PCBUILD=%~dp0) +if NOT DEFINED EXTERNALS_DIR (set EXTERNALS_DIR=%PCBUILD%\..\externals) set DO_FETCH=true set DO_CLEAN=false +set IncludeLibffiSrc=false set IncludeTkinterSrc=false set IncludeSSLSrc=false :CheckOpts if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts if "%~1"=="--no-openssl" (set IncludeSSL=false) & shift & goto CheckOpts +if "%~1"=="--no-libffi" (set IncludeLibffi=false) & shift & goto CheckOpts if "%~1"=="--tkinter-src" (set IncludeTkinterSrc=true) & shift & goto CheckOpts if "%~1"=="--openssl-src" (set IncludeSSLSrc=true) & shift & goto CheckOpts +if "%~1"=="--libffi-src" (set IncludeLibffiSrc=true) & shift & goto CheckOpts if "%~1"=="--python" (set PYTHON=%2) & shift & shift & goto CheckOpts if "%~1"=="--organization" (set ORG=%2) & shift & shift & goto CheckOpts if "%~1"=="-c" (set DO_CLEAN=true) & shift & goto CheckOpts @@ -49,6 +52,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.6 +if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0-rc0-r1 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.0j set libraries=%libraries% sqlite-3.21.0.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 @@ -72,6 +76,7 @@ for %%e in (%libraries%) do ( echo.Fetching external binaries... set binaries= +if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.0j if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/libffi.props b/PCbuild/libffi.props new file mode 100644 index 00000000000..975c4a0d355 --- /dev/null +++ b/PCbuild/libffi.props @@ -0,0 +1,21 @@ + + + + + $(libffiIncludeDir);%(AdditionalIncludeDirectories) + + + $(libffiOutDir);%(AdditionalLibraryDirectories) + libffi-7.lib;%(AdditionalDependencies) + + + + <_LIBFFIDLL Include="$(libffiOutDir)\libffi-7.dll" /> + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index 574c4f02913..d16ddef89f6 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -62,13 +62,13 @@ - + false - + diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 1bbfd180df1..66be9ac7a4a 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -37,6 +37,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testinternalcapi", "_testinternalcapi.vcxproj", "{900342D7-516A-4469-B1AD-59A66E49A25F}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" @@ -238,6 +240,7 @@ Global {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.ActiveCfg = Debug|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.Build.0 = Debug|ARM {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 @@ -255,6 +258,7 @@ Global {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.ActiveCfg = Release|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.Build.0 = Release|ARM {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 @@ -593,16 +597,16 @@ Global {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|ARM.ActiveCfg = Debug|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|ARM.ActiveCfg = Debug|ARM {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|ARM.ActiveCfg = PGInstrument|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|ARM.ActiveCfg = PGUpdate|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|ARM.ActiveCfg = Release|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|ARM.ActiveCfg = Release|ARM {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64 {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.ActiveCfg = Debug|ARM @@ -892,6 +896,7 @@ Global {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.ActiveCfg = Release|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.Build.0 = Release|ARM {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64 diff --git a/PCbuild/prepare_libffi.bat b/PCbuild/prepare_libffi.bat new file mode 100644 index 00000000000..307739d874a --- /dev/null +++ b/PCbuild/prepare_libffi.bat @@ -0,0 +1,180 @@ +@echo off +goto :Run + +:Usage +echo. +echo Before running prepare_libffi.bat +echo LIBFFI_SOURCE environment variable must be set to the location of +echo of python-source-deps clone of libffi branch +echo VCVARSALL must be set to location of vcvarsall.bat +echo cygwin must be installed (see below) +echo SH environment variable must be set to the location of sh.exe +echo. +echo Tested with cygwin-x86 from https://www.cygwin.com/install.html +echo Select http://mirrors.kernel.org as the download site +echo Include the following cygwin packages in cygwin configuration: +echo make, autoconf, automake, libtool, dejagnu +echo. +echo NOTE: dejagnu is only required for running tests. +echo set LIBFFI_TEST=1 to run tests (optional) +echo. +echo Based on https://github.com/libffi/libffi/blob/master/.appveyor.yml +echo. +echo. +echo.Available flags: +echo. -x64 build for x64 +echo. -x86 build for x86 +echo. -arm32 build for arm32 +echo. -? this help +echo. --install-cygwin install cygwin to c:\cygwin +exit /b 127 + +:Run + +set BUILD_X64= +set BUILD_X86= +set BUILD_ARM32= +set INSTALL_CYGWIN= + +:CheckOpts +if "%1"=="" goto :CheckOptsDone +if /I "%1"=="-x64" (set BUILD_X64=1) & shift & goto :CheckOpts +if /I "%1"=="-x86" (set BUILD_X86=1) & shift & goto :CheckOpts +if /I "%1"=="-arm32" (set BUILD_ARM32=1) & shift & goto :CheckOpts +if /I "%1"=="-?" goto :Usage +if /I "%1"=="--install-cygwin" (set INSTALL_CYGWIN=1) & shift & goto :CheckOpts +goto :Usage + +:CheckOptsDone + +if NOT DEFINED BUILD_X64 if NOT DEFINED BUILD_X86 if NOT DEFINED BUILD_ARM32 ( + set BUILD_X64=1 + set BUILD_X86=1 + set BUILD_ARM32=1 +) + +if "%INSTALL_CYGWIN%"=="1" call :InstallCygwin + +setlocal +if NOT DEFINED SH if exist c:\cygwin\bin\sh.exe set SH=c:\cygwin\bin\sh.exe + +if NOT DEFINED VCVARSALL ( + if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ( + set VCVARSALL="C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" + ) +) +if ^%VCVARSALL:~0,1% NEQ ^" SET VCVARSALL="%VCVARSALL%" + +if NOT DEFINED LIBFFI_SOURCE echo.&&echo ERROR LIBFFI_SOURCE environment variable not set && goto :Usage +if NOT DEFINED SH echo ERROR SH environment variable not set && goto :Usage + +if not exist %SH% echo ERROR %SH% does not exist && goto :Usage +if not exist %LIBFFI_SOURCE% echo ERROR %LIBFFI_SOURCE% does not exist && goto :Usage + +set OLDPWD=%LIBFFI_SOURCE% +pushd %LIBFFI_SOURCE% + +%SH% --login -lc "cygcheck -dc cygwin" +set GET_MSVCC=%SH% -lc "cd $OLDPWD; export MSVCC=`/usr/bin/find $PWD -name msvcc.sh`; echo ${MSVCC};" +FOR /F "usebackq delims==" %%i IN (`%GET_MSVCC%`) do @set MSVCC=%%i + +echo. +echo VCVARSALL : %VCVARSALL% +echo SH : %SH% +echo LIBFFI_SOURCE: %LIBFFI_SOURCE% +echo MSVCC : %MSVCC% +echo. + +if not exist Makefile.in (%SH% -lc "(cd $LIBFFI_SOURCE; ./autogen.sh;)") + +if "%BUILD_X64%"=="1" call :BuildOne x64 x86_64-w64-cygwin x86_64-w64-cygwin +if "%BUILD_X86%"=="1" call :BuildOne x86 i686-pc-cygwin i686-pc-cygwin +if "%BUILD_ARM32%"=="1" call :BuildOne x86_arm i686-pc-cygwin arm-w32-cygwin + +popd +endlocal +exit /b 0 +REM all done + + +REM this subroutine is called once for each architecture +:BuildOne + +setlocal + +REM Initialize variables +set VCVARS_PLATFORM=%1 +set BUILD=%2 +set HOST=%3 +set ASSEMBLER= +set SRC_ARCHITECTURE=x86 + +if NOT DEFINED VCVARS_PLATFORM echo ERROR bad VCVARS_PLATFORM&&exit /b 123 + +if /I "%VCVARS_PLATFORM%" EQU "x64" ( + set ARCH=amd64 + set ARTIFACTS=%LIBFFI_SOURCE%\x86_64-w64-cygwin + set ASSEMBLER=-m64 + set SRC_ARCHITECTURE=x86 +) +if /I "%VCVARS_PLATFORM%" EQU "x86" ( + set ARCH=win32 + set ARTIFACTS=%LIBFFI_SOURCE%\i686-pc-cygwin + set ASSEMBLER= + set SRC_ARCHITECTURE=x86 +) +if /I "%VCVARS_PLATFORM%" EQU "x86_arm" ( + set ARCH=arm32 + set ARTIFACTS=%LIBFFI_SOURCE%\arm-w32-cygwin + set ASSEMBLER=-marm + set SRC_ARCHITECTURE=ARM +) + +if NOT DEFINED LIBFFI_OUT set LIBFFI_OUT=%~dp0\..\externals\libffi +set _LIBFFI_OUT=%LIBFFI_OUT%\%ARCH% + +echo get VS build environment +call %VCVARSALL% %VCVARS_PLATFORM% + +echo clean %_LIBFFI_OUT% +if exist %_LIBFFI_OUT% (rd %_LIBFFI_OUT% /s/q) + +echo Configure the build to generate fficonfig.h and ffi.h +%SH% -lc "(cd $OLDPWD; ./configure CC='%MSVCC% %ASSEMBLER%' CXX='%MSVCC% %ASSEMBLER%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)" + +echo Building libffi +%SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)" + +REM Tests are not needed to produce artifacts +if "%LIBFFI_TEST%" EQU "1" ( + echo "Running tests..." + %SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp `find $PWD -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)" +) else ( + echo "Not running tests" +) + + +echo copying files to %_LIBFFI_OUT% +if not exist %_LIBFFI_OUT%\include (md %_LIBFFI_OUT%\include) +copy %ARTIFACTS%\.libs\libffi-7.dll %_LIBFFI_OUT% +copy %ARTIFACTS%\.libs\libffi-7.lib %_LIBFFI_OUT% +copy %ARTIFACTS%\fficonfig.h %_LIBFFI_OUT%\include +copy %ARTIFACTS%\include\*.h %_LIBFFI_OUT%\include + +endlocal +exit /b + +:InstallCygwin +setlocal + +if NOT DEFINED CYG_ROOT (set CYG_ROOT=c:/cygwin) +if NOT DEFINED CYG_CACHE (set CYG_CACHE=C:/cygwin/var/cache/setup) +if NOT DEFINED CYG_MIRROR (set CYG_MIRROR=http://mirrors.kernel.org/sourceware/cygwin/) + +powershell -c "md $env:CYG_ROOT -ErrorAction SilentlyContinue" +powershell -c "$setup = $env:CYG_ROOT+'/setup.exe'; if (!(Test-Path $setup)){invoke-webrequest https://cygwin.com/setup-x86.exe -outfile $setup} +%CYG_ROOT%/setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P make -P autoconf -P automake -P libtool -P dejagnu + +endlocal +exit /b + diff --git a/PCbuild/python.props b/PCbuild/python.props index 3a0ddceda66..52bc99e0560 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -53,6 +53,9 @@ $(ExternalsDir)sqlite-3.21.0.0\ $(ExternalsDir)bzip2-1.0.6\ $(ExternalsDir)xz-5.2.2\ + $(ExternalsDir)libffi\ + $(ExternalsDir)libffi\$(ArchName)\ + $(libffiOutDir)include $(ExternalsDir)openssl-1.1.0j\ $(ExternalsDir)openssl-bin-1.1.0j\$(ArchName)\ $(opensslOutDir)include diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index c9ff2f88d8e..5c5a720ba0c 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -86,7 +86,7 @@ /Zm200 %(AdditionalOptions) $(PySourcePath)Python;%(AdditionalIncludeDirectories) $(zlibDir);%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions) + _USRDLL;Py_BUILD_CORE;Py_BUILD_CORE_BUILTIN;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions) _Py_HAVE_ZLIB;%(PreprocessorDefinitions) @@ -117,6 +117,7 @@ + @@ -175,7 +176,6 @@ - diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 5dfa193f048..91346465679 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -102,6 +102,9 @@ Include + + Include + Include @@ -267,9 +270,6 @@ Include - - Include - Include diff --git a/Parser/Python.asdl b/Parser/Python.asdl index c32b65a52fe..668d3c93809 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -111,8 +111,8 @@ module Python excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body) attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) - arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, - arg? kwarg, expr* defaults) + arguments = (arg* args, arg* posonlyargs, arg? vararg, arg* kwonlyargs, + expr* kw_defaults, arg? kwarg, expr* defaults) arg = (identifier arg, expr? annotation, string? type_comment) attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) diff --git a/Parser/acceler.c b/Parser/acceler.c index 9b14263b461..e515833e1dd 100644 --- a/Parser/acceler.c +++ b/Parser/acceler.c @@ -10,22 +10,21 @@ are not part of the static data structure written on graminit.[ch] by the parser generator. */ -#include "pgenheaders.h" +#include "Python.h" #include "grammar.h" #include "node.h" #include "token.h" #include "parser.h" /* Forward references */ -static void fixdfa(grammar *, dfa *); +static void fixdfa(grammar *, const dfa *); static void fixstate(grammar *, state *); void PyGrammar_AddAccelerators(grammar *g) { - dfa *d; int i; - d = g->g_dfa; + const dfa *d = g->g_dfa; for (i = g->g_ndfas; --i >= 0; d++) fixdfa(g, d); g->g_accel = 1; @@ -34,10 +33,9 @@ PyGrammar_AddAccelerators(grammar *g) void PyGrammar_RemoveAccelerators(grammar *g) { - dfa *d; int i; g->g_accel = 0; - d = g->g_dfa; + const dfa *d = g->g_dfa; for (i = g->g_ndfas; --i >= 0; d++) { state *s; int j; @@ -51,7 +49,7 @@ PyGrammar_RemoveAccelerators(grammar *g) } static void -fixdfa(grammar *g, dfa *d) +fixdfa(grammar *g, const dfa *d) { state *s; int j; @@ -63,7 +61,7 @@ fixdfa(grammar *g, dfa *d) static void fixstate(grammar *g, state *s) { - arc *a; + const arc *a; int k; int *accel; int nl = g->g_ll.ll_nlabels; @@ -78,14 +76,14 @@ fixstate(grammar *g, state *s) a = s->s_arc; for (k = s->s_narcs; --k >= 0; a++) { int lbl = a->a_lbl; - label *l = &g->g_ll.ll_label[lbl]; + const label *l = &g->g_ll.ll_label[lbl]; int type = l->lb_type; if (a->a_arrow >= (1 << 7)) { printf("XXX too many states!\n"); continue; } if (ISNONTERMINAL(type)) { - dfa *d1 = PyGrammar_FindDFA(g, type); + const dfa *d1 = PyGrammar_FindDFA(g, type); int ibit; if (type - NT_OFFSET >= (1 << 7)) { printf("XXX too high nonterminal number!\n"); diff --git a/Parser/grammar1.c b/Parser/grammar1.c index 9c323911ab2..e0b8fbb8b82 100644 --- a/Parser/grammar1.c +++ b/Parser/grammar1.c @@ -2,18 +2,16 @@ /* Grammar subroutines needed by parser */ #include "Python.h" -#include "pgenheaders.h" #include "grammar.h" #include "token.h" /* Return the DFA for the given type */ -dfa * +const dfa * PyGrammar_FindDFA(grammar *g, int type) { - dfa *d; /* Massive speed-up */ - d = &g->g_dfa[type - NT_OFFSET]; + const dfa *d = &g->g_dfa[type - NT_OFFSET]; assert(d->d_type == type); return d; } diff --git a/Parser/listnode.c b/Parser/listnode.c index 71300ae908a..8f1a1163b63 100644 --- a/Parser/listnode.c +++ b/Parser/listnode.c @@ -1,7 +1,7 @@ /* List a node on a file */ -#include "pgenheaders.h" +#include "Python.h" #include "token.h" #include "node.h" diff --git a/Parser/parser.c b/Parser/parser.c index fa4a8f011ff..227b9184f47 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -6,7 +6,6 @@ /* XXX To do: error recovery */ #include "Python.h" -#include "pgenheaders.h" #include "token.h" #include "grammar.h" #include "node.h" @@ -36,7 +35,7 @@ s_reset(stack *s) #define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK]) static int -s_push(stack *s, dfa *d, node *parent) +s_push(stack *s, const dfa *d, node *parent) { stackentry *top; if (s->s_top == s->s_base) { @@ -120,7 +119,7 @@ shift(stack *s, int type, char *str, int newstate, int lineno, int col_offset, } static int -push(stack *s, int type, dfa *d, int newstate, int lineno, int col_offset, +push(stack *s, int type, const dfa *d, int newstate, int lineno, int col_offset, int end_lineno, int end_col_offset) { int err; @@ -145,7 +144,7 @@ classify(parser_state *ps, int type, const char *str) int n = g->g_ll.ll_nlabels; if (type == NAME) { - label *l = g->g_ll.ll_label; + const label *l = g->g_ll.ll_label; int i; for (i = n; i > 0; i--, l++) { if (l->lb_type != NAME || l->lb_str == NULL || @@ -169,7 +168,7 @@ classify(parser_state *ps, int type, const char *str) } { - label *l = g->g_ll.ll_label; + const label *l = g->g_ll.ll_label; int i; for (i = n; i > 0; i--, l++) { if (l->lb_type == type && l->lb_str == NULL) { @@ -247,7 +246,7 @@ PyParser_AddToken(parser_state *ps, int type, char *str, /* Loop until the token is shifted or an error occurred */ for (;;) { /* Fetch the current dfa and state */ - dfa *d = ps->p_stack.s_top->s_dfa; + const dfa *d = ps->p_stack.s_top->s_dfa; state *s = &d->d_state[ps->p_stack.s_top->s_state]; D(printf(" DFA '%s', state %d:", @@ -261,7 +260,6 @@ PyParser_AddToken(parser_state *ps, int type, char *str, /* Push non-terminal */ int nt = (x >> 8) + NT_OFFSET; int arrow = x & ((1<<7)-1); - dfa *d1; if (nt == func_body_suite && !(ps->p_flags & PyCF_TYPE_COMMENTS)) { /* When parsing type comments is not requested, we can provide better errors about bad indentation @@ -269,7 +267,7 @@ PyParser_AddToken(parser_state *ps, int type, char *str, D(printf(" [switch func_body_suite to suite]")); nt = suite; } - d1 = PyGrammar_FindDFA( + const dfa *d1 = PyGrammar_FindDFA( ps->p_grammar, nt); if ((err = push(&ps->p_stack, nt, d1, arrow, lineno, col_offset, diff --git a/Parser/parser.h b/Parser/parser.h index aee1c86cb04..b16075e7f29 100644 --- a/Parser/parser.h +++ b/Parser/parser.h @@ -11,7 +11,7 @@ extern "C" { typedef struct { int s_state; /* State in current DFA */ - dfa *s_dfa; /* Current DFA */ + const dfa *s_dfa; /* Current DFA */ struct _node *s_parent; /* Where to add next node */ } stackentry; @@ -38,6 +38,11 @@ int PyParser_AddToken(parser_state *ps, int type, char *str, int *expected_ret); void PyGrammar_AddAccelerators(grammar *g); + +#define showtree _Py_showtree +#define printtree _Py_printtree +#define dumptree _Py_dumptree + #ifdef __cplusplus } #endif diff --git a/Parser/parsetok.c b/Parser/parsetok.c index ba33a9a0586..31be0ebbde2 100644 --- a/Parser/parsetok.c +++ b/Parser/parsetok.c @@ -1,7 +1,7 @@ /* Parser-tokenizer link implementation */ -#include "pgenheaders.h" +#include "Python.h" #include "tokenizer.h" #include "node.h" #include "grammar.h" diff --git a/Parser/pgen/grammar.py b/Parser/pgen/grammar.py index 340bf64f6d2..5cd652426b4 100644 --- a/Parser/pgen/grammar.py +++ b/Parser/pgen/grammar.py @@ -61,7 +61,6 @@ def produce_graminit_h(self, writer): def produce_graminit_c(self, writer): writer("/* Generated by Parser/pgen */\n\n") - writer('#include "pgenheaders.h"\n') writer('#include "grammar.h"\n') writer("grammar _PyParser_Grammar;\n") @@ -77,7 +76,7 @@ def produce_graminit_c(self, writer): def print_labels(self, writer): writer( - "static label labels[{n_labels}] = {{\n".format(n_labels=len(self.labels)) + "static const label labels[{n_labels}] = {{\n".format(n_labels=len(self.labels)) ) for label, name in self.labels: label_name = '"{}"'.format(name) if name is not None else 0 @@ -90,7 +89,7 @@ def print_labels(self, writer): def print_dfas(self, writer): self.print_states(writer) - writer("static dfa dfas[{}] = {{\n".format(len(self.dfas))) + writer("static const dfa dfas[{}] = {{\n".format(len(self.dfas))) for dfaindex, dfa_elem in enumerate(self.dfas.items()): symbol, (dfa, first_sets) = dfa_elem writer( @@ -132,7 +131,7 @@ def print_arcs(self, write, dfaindex, states): for stateindex, state in enumerate(states): narcs = len(state) write( - "static arc arcs_{dfa_index}_{state_index}[{n_arcs}] = {{\n".format( + "static const arc arcs_{dfa_index}_{state_index}[{n_arcs}] = {{\n".format( dfa_index=dfaindex, state_index=stateindex, n_arcs=narcs ) ) diff --git a/Parser/pgen/keywordgen.py b/Parser/pgen/keywordgen.py new file mode 100644 index 00000000000..eeb3ef739fa --- /dev/null +++ b/Parser/pgen/keywordgen.py @@ -0,0 +1,60 @@ +"""Generate Lib/keyword.py from the Grammar and Tokens files using pgen""" + +import argparse + +from .pgen import ParserGenerator + +TEMPLATE = r''' +"""Keywords (from "Grammar/Grammar") + +This file is automatically generated; please don't muck it up! + +To update the symbols in this file, 'cd' to the top directory of +the python source tree and run: + + python3 -m Parser.pgen.keywordgen Grammar/Grammar \ + Grammar/Tokens \ + Lib/keyword.py + +Alternatively, you can run 'make regen-keyword'. +""" + +__all__ = ["iskeyword", "kwlist"] + +kwlist = [ + {keywords} +] + +iskeyword = frozenset(kwlist).__contains__ +'''.lstrip() + +EXTRA_KEYWORDS = ["async", "await"] + + +def main(): + parser = argparse.ArgumentParser(description="Generate the Lib/keywords.py " + "file from the grammar.") + parser.add_argument( + "grammar", type=str, help="The file with the grammar definition in EBNF format" + ) + parser.add_argument( + "tokens", type=str, help="The file with the token definitions" + ) + parser.add_argument( + "keyword_file", + type=argparse.FileType('w'), + help="The path to write the keyword definitions", + ) + args = parser.parse_args() + p = ParserGenerator(args.grammar, args.tokens) + grammar = p.make_grammar() + + with args.keyword_file as thefile: + all_keywords = sorted(list(grammar.keywords) + EXTRA_KEYWORDS) + + keywords = ",\n ".join(map(repr, all_keywords)) + thefile.write(TEMPLATE.format(keywords=keywords)) + + +if __name__ == "__main__": + main() diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index ad054975689..e8068f26807 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -2,7 +2,6 @@ /* Tokenizer implementation */ #include "Python.h" -#include "pgenheaders.h" #include #include @@ -963,7 +962,6 @@ tok_nextc(struct tok_state *tok) newbuf = (char *)PyMem_REALLOC(newbuf, newsize); if (newbuf == NULL) { - PyMem_FREE(tok->buf); tok->done = E_NOMEM; tok->cur = tok->inp; return EOF; diff --git a/Parser/tokenizer.h b/Parser/tokenizer.h index 06c7a14b70b..92669bfd8a1 100644 --- a/Parser/tokenizer.h +++ b/Parser/tokenizer.h @@ -80,6 +80,8 @@ extern struct tok_state *PyTokenizer_FromFile(FILE *, const char*, extern void PyTokenizer_Free(struct tok_state *); extern int PyTokenizer_Get(struct tok_state *, char **, char **); +#define tok_dump _Py_tok_dump + #ifdef __cplusplus } #endif diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index e6c51a4a1df..4b2ed70de97 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -77,7 +77,7 @@ main(int argc, char *argv[]) text[text_size] = '\0'; _PyCoreConfig config = _PyCoreConfig_INIT; - config.preconfig.use_environment = 0; + config.use_environment = 0; config.user_site_directory = 0; config.site_import = 0; config.program_name = L"./_freeze_importlib"; @@ -127,7 +127,7 @@ main(int argc, char *argv[]) size_t i, end = Py_MIN(n + 16, data_size); fprintf(outfile, " "); for (i = n; i < end; i++) { - fprintf(outfile, "%d,", (unsigned int) data[i]); + fprintf(outfile, "%u,", (unsigned int) data[i]); } fprintf(outfile, "\n"); } diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 7c143f1ef38..b12594799bf 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -298,77 +298,13 @@ static int test_initialize_pymain(void) } -static int -dump_config_impl(void) -{ - PyObject *config = NULL; - PyObject *dict = NULL; - - config = PyDict_New(); - if (config == NULL) { - goto error; - } - - /* global config */ - dict = _Py_GetGlobalVariablesAsDict(); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(config, "global_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - /* core config */ - PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp); - dict = _PyCoreConfig_AsDict(core_config); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(config, "core_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - /* main config */ - const _PyMainInterpreterConfig *main_config = _PyInterpreterState_GetMainConfig(interp); - dict = _PyMainInterpreterConfig_AsDict(main_config); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(config, "main_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - PyObject *json = PyImport_ImportModule("json"); - PyObject *res = PyObject_CallMethod(json, "dumps", "O", config); - Py_DECREF(json); - Py_CLEAR(config); - if (res == NULL) { - goto error; - } - - PySys_FormatStdout("%S\n", res); - Py_DECREF(res); - - return 0; - -error: - Py_XDECREF(config); - Py_XDECREF(dict); - return -1; -} - - static void dump_config(void) { - if (dump_config_impl() < 0) { - fprintf(stderr, "failed to dump the configuration:\n"); - PyErr_Print(); - } + (void) PyRun_SimpleStringFlags( + "import _testinternalcapi, json; " + "print(json.dumps(_testinternalcapi.get_configs()))", + 0); } @@ -418,8 +354,6 @@ static int test_init_global_config(void) putenv("PYTHONUNBUFFERED="); Py_UnbufferedStdioFlag = 1; - Py_FrozenFlag = 1; - /* FIXME: test Py_LegacyWindowsFSEncodingFlag */ /* FIXME: test Py_LegacyWindowsStdioFlag */ @@ -432,6 +366,22 @@ static int test_init_global_config(void) static int test_init_from_config(void) { + _PyInitError err; + + _PyPreConfig preconfig = _PyPreConfig_INIT; + + putenv("PYTHONMALLOC=malloc_debug"); + preconfig.allocator = "malloc"; + + putenv("PYTHONUTF8=0"); + Py_UTF8Mode = 0; + preconfig.utf8_mode = 1; + + err = _Py_PreInitialize(&preconfig); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + /* Test _Py_InitializeFromConfig() */ _PyCoreConfig config = _PyCoreConfig_INIT; config.install_signal_handlers = 0; @@ -442,9 +392,6 @@ static int test_init_from_config(void) config.use_hash_seed = 1; config.hash_seed = 123; - putenv("PYTHONMALLOC=malloc_debug"); - config.preconfig.allocator = "malloc"; - /* dev_mode=1 is tested in test_init_dev_mode() */ putenv("PYTHONFAULTHANDLER="); @@ -463,21 +410,17 @@ static int test_init_from_config(void) putenv("PYTHONMALLOCSTATS=0"); config.malloc_stats = 1; - /* FIXME: test coerce_c_locale and coerce_c_locale_warn */ - - putenv("PYTHONUTF8=0"); - Py_UTF8Mode = 0; - config.preconfig.utf8_mode = 1; - putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); config.pycache_prefix = L"conf_pycache_prefix"; Py_SetProgramName(L"./globalvar"); config.program_name = L"./conf_program_name"; - static wchar_t* argv[2] = { + static wchar_t* argv[] = { + L"python3", L"-c", L"pass", + L"arg2", }; config.argv.length = Py_ARRAY_LENGTH(argv); config.argv.items = argv; @@ -492,8 +435,7 @@ static int test_init_from_config(void) config.xoptions.length = Py_ARRAY_LENGTH(xoptions); config.xoptions.items = xoptions; - static wchar_t* warnoptions[2] = { - L"default", + static wchar_t* warnoptions[1] = { L"error::ResourceWarning", }; config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions); @@ -544,20 +486,16 @@ static int test_init_from_config(void) Force it to 0 through the config. */ config.legacy_windows_stdio = 0; #endif - config.stdio_encoding = "iso8859-1"; - config.stdio_errors = "replace"; + config.stdio_encoding = L"iso8859-1"; + config.stdio_errors = L"replace"; putenv("PYTHONNOUSERSITE="); Py_NoUserSiteDirectory = 0; config.user_site_directory = 0; - config._check_hash_pycs_mode = "always"; + config.check_hash_pycs_mode = L"always"; - Py_FrozenFlag = 0; - config._frozen = 1; - - _PyInitError err = _Py_InitializeFromConfig(&config); - /* Don't call _PyCoreConfig_Clear() since all strings are static */ + err = _Py_InitializeFromConfig(&config); if (_Py_INIT_FAILED(err)) { _Py_ExitInitError(err); } @@ -642,20 +580,79 @@ static int test_init_env_dev_mode_alloc(void) static int test_init_isolated(void) { + _PyInitError err; + /* Test _PyCoreConfig.isolated=1 */ _PyCoreConfig config = _PyCoreConfig_INIT; Py_IsolatedFlag = 0; - config.preconfig.isolated = 1; + config.isolated = 1; - /* Set coerce_c_locale and utf8_mode to not depend on the locale */ - config.preconfig.coerce_c_locale = 0; - config.preconfig.utf8_mode = 0; /* Use path starting with "./" avoids a search along the PATH */ config.program_name = L"./_testembed"; test_init_env_dev_mode_putenvs(); - _PyInitError err = _Py_InitializeFromConfig(&config); + err = _Py_InitializeFromConfig(&config); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + dump_config(); + Py_Finalize(); + return 0; +} + + +/* _PyPreConfig.isolated=1, _PyCoreConfig.isolated=0 */ +static int test_preinit_isolated1(void) +{ + _PyInitError err; + + _PyPreConfig preconfig = _PyPreConfig_INIT; + preconfig.isolated = 1; + + err = _Py_PreInitialize(&preconfig); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + + _PyCoreConfig config = _PyCoreConfig_INIT; + config.program_name = L"./_testembed"; + + test_init_env_dev_mode_putenvs(); + err = _Py_InitializeFromConfig(&config); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + dump_config(); + Py_Finalize(); + return 0; +} + + +/* _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 */ +static int test_preinit_isolated2(void) +{ + _PyInitError err; + + _PyPreConfig preconfig = _PyPreConfig_INIT; + preconfig.isolated = 0; + + err = _Py_PreInitialize(&preconfig); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + + /* Test _PyCoreConfig.isolated=1 */ + _PyCoreConfig config = _PyCoreConfig_INIT; + + Py_IsolatedFlag = 0; + config.isolated = 1; + + /* Use path starting with "./" avoids a search along the PATH */ + config.program_name = L"./_testembed"; + + test_init_env_dev_mode_putenvs(); + err = _Py_InitializeFromConfig(&config); if (_Py_INIT_FAILED(err)) { _Py_ExitInitError(err); } @@ -670,7 +667,7 @@ static int test_init_dev_mode(void) _PyCoreConfig config = _PyCoreConfig_INIT; putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); - config.preconfig.dev_mode = 1; + config.dev_mode = 1; config.program_name = L"./_testembed"; _PyInitError err = _Py_InitializeFromConfig(&config); if (_Py_INIT_FAILED(err)) { @@ -682,6 +679,27 @@ static int test_init_dev_mode(void) } +static int test_run_main(void) +{ + _PyCoreConfig config = _PyCoreConfig_INIT; + + wchar_t *argv[] = {L"python3", L"-c", + (L"import sys; " + L"print(f'_Py_RunMain(): sys.argv={sys.argv}')"), + L"arg2"}; + config.argv.length = Py_ARRAY_LENGTH(argv); + config.argv.items = argv; + config.program_name = L"./python3"; + + _PyInitError err = _Py_InitializeFromConfig(&config); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + + return _Py_RunMain(); +} + + /* ********************************************************* * List of test cases and the function that implements it. * @@ -716,6 +734,9 @@ static struct TestCase TestCases[] = { { "init_env_dev_mode_alloc", test_init_env_dev_mode_alloc }, { "init_dev_mode", test_init_dev_mode }, { "init_isolated", test_init_isolated }, + { "preinit_isolated1", test_preinit_isolated1 }, + { "preinit_isolated2", test_preinit_isolated2 }, + { "run_main", test_run_main }, { NULL, NULL } }; diff --git a/Python/Python-ast.c b/Python/Python-ast.c index d0416eb639c..6c8488f8fe6 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -469,6 +469,7 @@ static char *ExceptHandler_fields[]={ }; static PyTypeObject *arguments_type; static PyObject* ast2obj_arguments(void*); +_Py_IDENTIFIER(posonlyargs); _Py_IDENTIFIER(vararg); _Py_IDENTIFIER(kwonlyargs); _Py_IDENTIFIER(kw_defaults); @@ -476,6 +477,7 @@ _Py_IDENTIFIER(kwarg); _Py_IDENTIFIER(defaults); static char *arguments_fields[]={ "args", + "posonlyargs", "vararg", "kwonlyargs", "kw_defaults", @@ -1141,7 +1143,7 @@ static int init_types(void) ExceptHandler_type = make_type("ExceptHandler", excepthandler_type, ExceptHandler_fields, 3); if (!ExceptHandler_type) return 0; - arguments_type = make_type("arguments", &AST_type, arguments_fields, 6); + arguments_type = make_type("arguments", &AST_type, arguments_fields, 7); if (!arguments_type) return 0; if (!add_attributes(arguments_type, NULL, 0)) return 0; arg_type = make_type("arg", &AST_type, arg_fields, 3); @@ -2569,14 +2571,16 @@ ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int } arguments_ty -arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq * - kw_defaults, arg_ty kwarg, asdl_seq * defaults, PyArena *arena) +arguments(asdl_seq * args, asdl_seq * posonlyargs, arg_ty vararg, asdl_seq * + kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * + defaults, PyArena *arena) { arguments_ty p; p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->args = args; + p->posonlyargs = posonlyargs; p->vararg = vararg; p->kwonlyargs = kwonlyargs; p->kw_defaults = kw_defaults; @@ -3954,6 +3958,11 @@ ast2obj_arguments(void* _o) if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_list(o->posonlyargs, ast2obj_arg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_posonlyargs, value) == -1) + goto failed; + Py_DECREF(value); value = ast2obj_arg(o->vararg); if (!value) goto failed; if (_PyObject_SetAttrId(result, &PyId_vararg, value) == -1) @@ -8267,6 +8276,7 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) { PyObject* tmp = NULL; asdl_seq* args; + asdl_seq* posonlyargs; arg_ty vararg; asdl_seq* kwonlyargs; asdl_seq* kw_defaults; @@ -8303,6 +8313,36 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) } Py_CLEAR(tmp); } + if (_PyObject_LookupAttrId(obj, &PyId_posonlyargs, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + posonlyargs = _Py_asdl_seq_new(len, arena); + if (posonlyargs == NULL) goto failed; + for (i = 0; i < len; i++) { + arg_ty val; + res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(posonlyargs, i, val); + } + Py_CLEAR(tmp); + } if (_PyObject_LookupAttrId(obj, &PyId_vararg, &tmp) < 0) { return 1; } @@ -8419,8 +8459,8 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) } Py_CLEAR(tmp); } - *out = arguments(args, vararg, kwonlyargs, kw_defaults, kwarg, defaults, - arena); + *out = arguments(args, posonlyargs, vararg, kwonlyargs, kw_defaults, kwarg, + defaults, arena); return 0; failed: Py_XDECREF(tmp); diff --git a/Python/_warnings.c b/Python/_warnings.c index 33b46151158..388b2995408 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1259,35 +1259,46 @@ _PyWarnings_Init(void) if (m == NULL) return NULL; - if (_PyRuntime.warnings.filters == NULL) { - _PyRuntime.warnings.filters = init_filters(); - if (_PyRuntime.warnings.filters == NULL) + struct _warnings_runtime_state *state = &_PyRuntime.warnings; + if (state->filters == NULL) { + state->filters = init_filters(); + if (state->filters == NULL) return NULL; } - Py_INCREF(_PyRuntime.warnings.filters); - if (PyModule_AddObject(m, "filters", _PyRuntime.warnings.filters) < 0) + Py_INCREF(state->filters); + if (PyModule_AddObject(m, "filters", state->filters) < 0) return NULL; - if (_PyRuntime.warnings.once_registry == NULL) { - _PyRuntime.warnings.once_registry = PyDict_New(); - if (_PyRuntime.warnings.once_registry == NULL) + if (state->once_registry == NULL) { + state->once_registry = PyDict_New(); + if (state->once_registry == NULL) return NULL; } - Py_INCREF(_PyRuntime.warnings.once_registry); + Py_INCREF(state->once_registry); if (PyModule_AddObject(m, "_onceregistry", - _PyRuntime.warnings.once_registry) < 0) + state->once_registry) < 0) return NULL; - if (_PyRuntime.warnings.default_action == NULL) { - _PyRuntime.warnings.default_action = PyUnicode_FromString("default"); - if (_PyRuntime.warnings.default_action == NULL) + if (state->default_action == NULL) { + state->default_action = PyUnicode_FromString("default"); + if (state->default_action == NULL) return NULL; } - Py_INCREF(_PyRuntime.warnings.default_action); + Py_INCREF(state->default_action); if (PyModule_AddObject(m, "_defaultaction", - _PyRuntime.warnings.default_action) < 0) + state->default_action) < 0) return NULL; - _PyRuntime.warnings.filters_version = 0; + state->filters_version = 0; return m; } + + +void +_PyWarnings_Fini(_PyRuntimeState *runtime) +{ + struct _warnings_runtime_state *state = &runtime->warnings; + Py_CLEAR(state->filters); + Py_CLEAR(state->once_registry); + Py_CLEAR(state->default_action); +} diff --git a/Python/ast.c b/Python/ast.c index e9154fecff0..4687f8178b0 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -110,8 +110,9 @@ expr_context_name(expr_context_ty ctx) static int validate_arguments(arguments_ty args) { - if (!validate_args(args->args)) + if (!validate_args(args->posonlyargs) || !validate_args(args->args)) { return 0; + } if (args->vararg && args->vararg->annotation && !validate_expr(args->vararg->annotation, Load)) { return 0; @@ -1400,7 +1401,7 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, goto error; asdl_seq_SET(kwonlyargs, j++, arg); i += 1; /* the name */ - if (TYPE(CHILD(n, i)) == COMMA) + if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) i += 1; /* the comma, if present */ break; case TYPE_COMMENT: @@ -1431,31 +1432,73 @@ ast_for_arguments(struct compiling *c, const node *n) and varargslist (lambda definition). parameters: '(' [typedargslist] ')' - typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [ - '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] - | '**' tfpdef [',']]] - | '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] - | '**' tfpdef [',']) + + The following definition for typedarglist is equivalent to this set of rules: + + arguments = argument (',' [TYPE_COMMENT] argument)* + argument = tfpdef ['=' test] + kwargs = '**' tfpdef [','] [TYPE_COMMENT] + args = '*' [tfpdef] + kwonly_kwargs = (',' [TYPE_COMMENT] argument)* (TYPE_COMMENT | [',' + [TYPE_COMMENT] [kwargs]]) + args_kwonly_kwargs = args kwonly_kwargs | kwargs + poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [',' + [TYPE_COMMENT] [args_kwonly_kwargs]]) + typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs + typedarglist = (arguments ',' [TYPE_COMMENT] '/' [',' [[TYPE_COMMENT] + typedargslist_no_posonly]])|(typedargslist_no_posonly)" + + typedargslist: ( (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* + ',' [TYPE_COMMENT] '/' [',' [ [TYPE_COMMENT] tfpdef ['=' test] ( ',' + [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' + [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' + [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] + [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* + (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | + '**' tfpdef [','] [TYPE_COMMENT]]] ) | (tfpdef ['=' test] (',' + [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' + [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' + [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] + [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* + (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | + '**' tfpdef [','] [TYPE_COMMENT])) + tfpdef: NAME [':' test] - varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ - '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] - | '**' vfpdef [',']]] - | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] - | '**' vfpdef [','] - ) + + The following definition for varargslist is equivalent to this set of rules: + + arguments = argument (',' argument )* + argument = vfpdef ['=' test] + kwargs = '**' vfpdef [','] + args = '*' [vfpdef] + kwonly_kwargs = (',' argument )* [',' [kwargs]] + args_kwonly_kwargs = args kwonly_kwargs | kwargs + poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]] + vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs + varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | + (vararglist_no_posonly) + + varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['=' + test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' + ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* + [',' ['**' vfpdef [',']]] | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef + ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef + [',']]] | '**' vfpdef [',']) + vfpdef: NAME */ - int i, j, k, nposargs = 0, nkwonlyargs = 0; + int i, j, k, l, nposonlyargs=0, nposargs = 0, nkwonlyargs = 0; int nposdefaults = 0, found_default = 0; - asdl_seq *posargs, *posdefaults, *kwonlyargs, *kwdefaults; + asdl_seq *posonlyargs, *posargs, *posdefaults, *kwonlyargs, *kwdefaults; arg_ty vararg = NULL, kwarg = NULL; arg_ty arg = NULL; node *ch; if (TYPE(n) == parameters) { if (NCH(n) == 2) /* () as argument list */ - return arguments(NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); + return arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); n = CHILD(n, 1); } assert(TYPE(n) == typedargslist || TYPE(n) == varargslist); @@ -1479,6 +1522,10 @@ ast_for_arguments(struct compiling *c, const node *n) if (TYPE(ch) == DOUBLESTAR) break; if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++; if (TYPE(ch) == EQUAL) nposdefaults++; + if (TYPE(ch) == SLASH ) { + nposonlyargs = nposargs; + nposargs = 0; + } } /* count the number of keyword only args & defaults for keyword only args */ @@ -1487,6 +1534,10 @@ ast_for_arguments(struct compiling *c, const node *n) if (TYPE(ch) == DOUBLESTAR) break; if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++; } + posonlyargs = (nposonlyargs ? _Py_asdl_seq_new(nposonlyargs, c->c_arena) : NULL); + if (!posonlyargs && nposonlyargs) { + return NULL; + } posargs = (nposargs ? _Py_asdl_seq_new(nposargs, c->c_arena) : NULL); if (!posargs && nposargs) return NULL; @@ -1512,6 +1563,7 @@ ast_for_arguments(struct compiling *c, const node *n) i = 0; j = 0; /* index for defaults */ k = 0; /* index for args */ + l = 0; /* index for posonlyargs */ while (i < NCH(n)) { ch = CHILD(n, i); switch (TYPE(ch)) { @@ -1537,11 +1589,23 @@ ast_for_arguments(struct compiling *c, const node *n) arg = ast_for_arg(c, ch); if (!arg) return NULL; - asdl_seq_SET(posargs, k++, arg); + if (l < nposonlyargs) { + asdl_seq_SET(posonlyargs, l++, arg); + } else { + asdl_seq_SET(posargs, k++, arg); + } i += 1; /* the name */ if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) i += 1; /* the comma, if present */ break; + case SLASH: + /* Advance the slash and the comma. If there are more names + * after the slash there will be a comma so we are advancing + * the correct number of nodes. If the slash is the last item, + * we will be advancing an extra token but then * i > NCH(n) + * and the enclosing while will finish correctly. */ + i += 2; + break; case STAR: if (i+1 >= NCH(n) || (i+2 == NCH(n) && (TYPE(CHILD(n, i+1)) == COMMA @@ -1599,7 +1663,7 @@ ast_for_arguments(struct compiling *c, const node *n) if (!kwarg) return NULL; i += 2; /* the double star and the name */ - if (TYPE(CHILD(n, i)) == COMMA) + if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) i += 1; /* the comma, if present */ break; case TYPE_COMMENT: @@ -1621,7 +1685,7 @@ ast_for_arguments(struct compiling *c, const node *n) return NULL; } } - return arguments(posargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena); + return arguments(posargs, posonlyargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena); } static expr_ty @@ -1909,7 +1973,7 @@ ast_for_lambdef(struct compiling *c, const node *n) expr_ty expression; if (NCH(n) == 3) { - args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); + args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); if (!args) return NULL; expression = ast_for_expr(c, CHILD(n, 2)); diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 7a2b259cbd8..047cca057b4 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2375,9 +2375,11 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) } if (PyLong_CheckExact(item)) { long b = PyLong_AsLongAndOverflow(item, &overflow); - long x = i_result + b; - if (overflow == 0 && ((x^i_result) >= 0 || (x^b) >= 0)) { - i_result = x; + if (overflow == 0 && + (i_result >= 0 ? (b <= LONG_MAX - i_result) + : (b >= LONG_MIN - i_result))) + { + i_result += b; Py_DECREF(item); continue; } diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index 35d9b7f24a9..dd752b86094 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -578,8 +578,8 @@ _Py_HashRandomization_Init(const _PyCoreConfig *config) pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */ res = pyurandom(secret, secret_size, 0, 0); if (res < 0) { - return _Py_INIT_USER_ERR("failed to get random numbers " - "to initialize Python"); + return _Py_INIT_ERR("failed to get random numbers " + "to initialize Python"); } } return _Py_INIT_OK(); diff --git a/Python/ceval.c b/Python/ceval.c index 40320bf3570..e616a3f5398 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -30,6 +30,10 @@ #define CHECKEXC 1 /* Double-check exception checking */ #endif +#if !defined(Py_BUILD_CORE) +# error "ceval.c must be build with Py_BUILD_CORE define for best performance" +#endif + /* Private API for the LOAD_METHOD opcode. */ extern int _PyObject_GetMethod(PyObject *, PyObject *, PyObject **); @@ -72,6 +76,7 @@ static PyObject * special_lookup(PyObject *, _Py_Identifier *); static int check_args_iterable(PyObject *func, PyObject *vararg); static void format_kwargs_error(PyObject *func, PyObject *kwargs); static void format_awaitable_error(PyTypeObject *, int); +static inline void exit_thread_if_finalizing(PyThreadState *); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -199,6 +204,16 @@ _PyEval_FiniThreads(void) } } +static inline void +exit_thread_if_finalizing(PyThreadState *tstate) +{ + /* _Py_Finalizing is protected by the GIL */ + if (_Py_IsFinalizing() && !_Py_CURRENTLY_FINALIZING(tstate)) { + drop_gil(tstate); + PyThread_exit_thread(); + } +} + void PyEval_AcquireLock(void) { @@ -206,6 +221,7 @@ PyEval_AcquireLock(void) if (tstate == NULL) Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); take_gil(tstate); + exit_thread_if_finalizing(tstate); } void @@ -226,6 +242,7 @@ PyEval_AcquireThread(PyThreadState *tstate) /* Check someone has called PyEval_InitThreads() to create the lock */ assert(gil_created()); take_gil(tstate); + exit_thread_if_finalizing(tstate); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError( "PyEval_AcquireThread: non-NULL old thread state"); @@ -294,12 +311,7 @@ PyEval_RestoreThread(PyThreadState *tstate) int err = errno; take_gil(tstate); - /* _Py_Finalizing is protected by the GIL */ - if (_Py_IsFinalizing() && !_Py_CURRENTLY_FINALIZING(tstate)) { - drop_gil(tstate); - PyThread_exit_thread(); - Py_UNREACHABLE(); - } + exit_thread_if_finalizing(tstate); errno = err; PyThreadState_Swap(tstate); @@ -1079,12 +1091,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) take_gil(tstate); /* Check if we should make a quick exit. */ - if (_Py_IsFinalizing() && - !_Py_CURRENTLY_FINALIZING(tstate)) - { - drop_gil(tstate); - PyThread_exit_thread(); - } + exit_thread_if_finalizing(tstate); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate"); @@ -3203,7 +3210,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } case TARGET(LOAD_METHOD): { - /* Designed to work in tamdem with CALL_METHOD. */ + /* Designed to work in tandem with CALL_METHOD. */ PyObject *name = GETITEM(names, oparg); PyObject *obj = TOP(); PyObject *meth = NULL; @@ -3686,10 +3693,10 @@ missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount, return; if (positional) { start = 0; - end = co->co_argcount - defcount; + end = co->co_posonlyargcount + co->co_argcount - defcount; } else { - start = co->co_argcount; + start = co->co_posonlyargcount + co->co_argcount; end = start + co->co_kwonlyargcount; } for (i = start; i < end; i++) { @@ -3716,23 +3723,25 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount, Py_ssize_t kwonly_given = 0; Py_ssize_t i; PyObject *sig, *kwonly_sig; + Py_ssize_t co_posonlyargcount = co->co_posonlyargcount; Py_ssize_t co_argcount = co->co_argcount; + Py_ssize_t total_positional = co_argcount + co_posonlyargcount; assert((co->co_flags & CO_VARARGS) == 0); /* Count missing keyword-only args. */ - for (i = co_argcount; i < co_argcount + co->co_kwonlyargcount; i++) { + for (i = total_positional; i < total_positional + co->co_kwonlyargcount; i++) { if (GETLOCAL(i) != NULL) { kwonly_given++; } } if (defcount) { - Py_ssize_t atleast = co_argcount - defcount; + Py_ssize_t atleast = total_positional - defcount; plural = 1; - sig = PyUnicode_FromFormat("from %zd to %zd", atleast, co_argcount); + sig = PyUnicode_FromFormat("from %zd to %zd", atleast, total_positional); } else { - plural = (co_argcount != 1); - sig = PyUnicode_FromFormat("%zd", co_argcount); + plural = (total_positional != 1); + sig = PyUnicode_FromFormat("%zd", total_positional); } if (sig == NULL) return; @@ -3764,6 +3773,67 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount, Py_DECREF(kwonly_sig); } +static int +positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount, + PyObject* const* kwnames) +{ + int posonly_conflicts = 0; + PyObject* posonly_names = PyList_New(0); + + for(int k=0; k < co->co_posonlyargcount; k++){ + PyObject* posonly_name = PyTuple_GET_ITEM(co->co_varnames, k); + + for (int k2=0; k2 0) { + if(PyList_Append(posonly_names, kwname) != 0) { + goto fail; + } + posonly_conflicts++; + } else if (cmp < 0) { + goto fail; + } + + } + } + if (posonly_conflicts) { + PyObject* comma = PyUnicode_FromString(", "); + if (comma == NULL) { + goto fail; + } + PyObject* error_names = PyUnicode_Join(comma, posonly_names); + Py_DECREF(comma); + if (error_names == NULL) { + goto fail; + } + PyErr_Format(PyExc_TypeError, + "%U() got some positional-only arguments passed" + " as keyword arguments: '%U'", + co->co_name, error_names); + Py_DECREF(error_names); + goto fail; + } + + Py_DECREF(posonly_names); + return 0; + +fail: + Py_XDECREF(posonly_names); + return 1; + +} + /* This is gonna seem *real weird*, but if you put some other code between PyEval_EvalFrame() and _PyEval_EvalFrameDefault() you will need to adjust the test in the if statements in Misc/gdbinit (pystack and pystackv). */ @@ -3783,8 +3853,8 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, PyObject **fastlocals, **freevars; PyThreadState *tstate; PyObject *x, *u; - const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; - Py_ssize_t i, n; + const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount + co->co_posonlyargcount; + Py_ssize_t i, j, n; PyObject *kwdict; if (globals == NULL) { @@ -3818,14 +3888,28 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, kwdict = NULL; } - /* Copy positional arguments into local variables */ - if (argcount > co->co_argcount) { - n = co->co_argcount; + /* Copy positional only arguments into local variables */ + if (argcount > co->co_argcount + co->co_posonlyargcount) { + n = co->co_posonlyargcount; } else { n = argcount; } - for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + x = args[j]; + Py_INCREF(x); + SETLOCAL(j, x); + } + + + /* Copy positional arguments into local variables */ + if (argcount > co->co_argcount + co->co_posonlyargcount) { + n += co->co_argcount; + } + else { + n = argcount; + } + for (i = j; i < n; i++) { x = args[i]; Py_INCREF(x); SETLOCAL(i, x); @@ -3858,7 +3942,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, /* Speed hack: do raw pointer compares. As names are normally interned this should almost always hit. */ co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; - for (j = 0; j < total_args; j++) { + for (j = co->co_posonlyargcount; j < total_args; j++) { PyObject *name = co_varnames[j]; if (name == keyword) { goto kw_found; @@ -3866,7 +3950,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, } /* Slow fallback, just in case */ - for (j = 0; j < total_args; j++) { + for (j = co->co_posonlyargcount; j < total_args; j++) { PyObject *name = co_varnames[j]; int cmp = PyObject_RichCompareBool( keyword, name, Py_EQ); if (cmp > 0) { @@ -3879,6 +3963,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, assert(j >= total_args); if (kwdict == NULL) { + + if (co->co_posonlyargcount && positional_only_passed_as_keyword(co, kwcount, kwnames)) { + goto fail; + } + PyErr_Format(PyExc_TypeError, "%U() got an unexpected keyword argument '%S'", co->co_name, keyword); @@ -3902,14 +3991,14 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, } /* Check the number of positional arguments */ - if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) { + if ((argcount > co->co_argcount + co->co_posonlyargcount) && !(co->co_flags & CO_VARARGS)) { too_many_positional(co, argcount, defcount, fastlocals); goto fail; } /* Add missing positional arguments (copy default values from defs) */ - if (argcount < co->co_argcount) { - Py_ssize_t m = co->co_argcount - defcount; + if (argcount < co->co_posonlyargcount + co->co_argcount) { + Py_ssize_t m = co->co_posonlyargcount + co->co_argcount - defcount; Py_ssize_t missing = 0; for (i = argcount; i < m; i++) { if (GETLOCAL(i) == NULL) { @@ -3936,7 +4025,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, /* Add missing keyword arguments (copy default values from kwdefs) */ if (co->co_kwonlyargcount > 0) { Py_ssize_t missing = 0; - for (i = co->co_argcount; i < total_args; i++) { + for (i = co->co_posonlyargcount + co->co_argcount; i < total_args; i++) { PyObject *name; if (GETLOCAL(i) != NULL) continue; @@ -4948,7 +5037,7 @@ import_from(PyObject *v, PyObject *name) } x = PyImport_GetModule(fullmodname); Py_DECREF(fullmodname); - if (x == NULL) { + if (x == NULL && !PyErr_Occurred()) { goto error; } Py_DECREF(pkgname); @@ -4971,7 +5060,7 @@ import_from(PyObject *v, PyObject *name) "cannot import name %R from %R (unknown location)", name, pkgname_or_unknown ); - /* NULL check for errmsg done by PyErr_SetImportError. */ + /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ PyErr_SetImportError(errmsg, pkgname, NULL); } else { @@ -4979,7 +5068,7 @@ import_from(PyObject *v, PyObject *name) "cannot import name %R from %R (%S)", name, pkgname_or_unknown, pkgpath ); - /* NULL check for errmsg done by PyErr_SetImportError. */ + /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ PyErr_SetImportError(errmsg, pkgname, pkgpath); } diff --git a/Python/compile.c b/Python/compile.c index a992e4b4653..86f2a09ffb3 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -122,6 +122,7 @@ struct compiler_unit { PyObject *u_private; /* for private name mangling */ Py_ssize_t u_argcount; /* number of arguments for block */ + Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */ Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ /* Pointer to the most recently allocated block. By following b_list members, you can reach all early allocated blocks. */ @@ -552,6 +553,7 @@ compiler_enter_scope(struct compiler *c, identifier name, memset(u, 0, sizeof(struct compiler_unit)); u->u_scope_type = scope_type; u->u_argcount = 0; + u->u_posonlyargcount = 0; u->u_kwonlyargcount = 0; u->u_ste = PySymtable_Lookup(c->c_st, key); if (!u->u_ste) { @@ -1216,7 +1218,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } // We registered o in c_const_cache. - // When o is a tuple or frozenset, we want to merge it's + // When o is a tuple or frozenset, we want to merge its // items too. if (PyTuple_CheckExact(o)) { Py_ssize_t len = PyTuple_GET_SIZE(o); @@ -1246,7 +1248,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } } else if (PyFrozenSet_CheckExact(o)) { - // *key* is tuple. And it's first item is frozenset of + // *key* is tuple. And its first item is frozenset of // constant keys. // See _PyCode_ConstantKey() for detail. assert(PyTuple_CheckExact(key)); @@ -2127,6 +2129,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) } c->u->u_argcount = asdl_seq_LEN(args->args); + c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); VISIT_SEQ_IN_SCOPE(c, stmt, body); co = assemble(c, 1); @@ -2507,6 +2510,7 @@ compiler_lambda(struct compiler *c, expr_ty e) return 0; c->u->u_argcount = asdl_seq_LEN(args->args); + c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); if (c->u->u_ste->ste_generator) { @@ -5742,7 +5746,7 @@ makecode(struct compiler *c, struct assembler *a) Py_ssize_t nlocals; int nlocals_int; int flags; - int argcount, kwonlyargcount, maxdepth; + int argcount, posonlyargcount, kwonlyargcount, maxdepth; consts = consts_dict_keys_inorder(c->u->u_consts); names = dict_keys_inorder(c->u->u_names, 0); @@ -5787,12 +5791,13 @@ makecode(struct compiler *c, struct assembler *a) } argcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); + posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int); kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); maxdepth = stackdepth(c); if (maxdepth < 0) { goto error; } - co = PyCode_New(argcount, kwonlyargcount, + co = PyCode_New(argcount, posonlyargcount, kwonlyargcount, nlocals_int, maxdepth, flags, bytecode, consts, names, varnames, freevars, cellvars, diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 540e608fb01..ac01712127a 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -131,7 +131,7 @@ int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ #endif -PyObject * +static PyObject * _Py_GetGlobalVariablesAsDict(void) { PyObject *dict, *obj; @@ -296,7 +296,7 @@ _PyWstrList_Append(_PyWstrList *list, const wchar_t *item) } -static int +int _PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2) { for (Py_ssize_t i = 0; i < list2->length; i++) { @@ -308,6 +308,18 @@ _PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2) } +static int +_PyWstrList_Find(_PyWstrList *list, const wchar_t *item) +{ + for (Py_ssize_t i = 0; i < list->length; i++) { + if (wcscmp(list->items[i], item) == 0) { + return 1; + } + } + return 0; +} + + PyObject* _PyWstrList_AsList(const _PyWstrList *list) { @@ -363,6 +375,7 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) * Py_Initialize hasn't been called yet. */ if (encoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); if (!_Py_StandardStreamEncoding) { res = -2; @@ -370,11 +383,11 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) } } if (errors) { + PyMem_RawFree(_Py_StandardStreamErrors); _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); if (!_Py_StandardStreamErrors) { - if (_Py_StandardStreamEncoding) { - PyMem_RawFree(_Py_StandardStreamEncoding); - } + PyMem_RawFree(_Py_StandardStreamEncoding); + _Py_StandardStreamEncoding = NULL; res = -3; goto done; } @@ -462,15 +475,13 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv) #define DECODE_LOCALE_ERR(NAME, LEN) \ (((LEN) == -2) \ - ? _Py_INIT_USER_ERR("cannot decode " NAME) \ + ? _Py_INIT_ERR("cannot decode " NAME) \ : _Py_INIT_NO_MEMORY()) /* Free memory allocated in config, but don't clear all attributes */ void _PyCoreConfig_Clear(_PyCoreConfig *config) { - _PyPreConfig_Clear(&config->preconfig); - #define CLEAR(ATTR) \ do { \ PyMem_RawFree(ATTR); \ @@ -505,45 +516,100 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) CLEAR(config->run_command); CLEAR(config->run_module); CLEAR(config->run_filename); + CLEAR(config->check_hash_pycs_mode); #undef CLEAR } -int -_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) +/* Copy str into *config_str (duplicate the string) */ +_PyInitError +_PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str) { - _PyCoreConfig_Clear(config); + wchar_t *str2; + if (str != NULL) { + str2 = _PyMem_RawWcsdup(str); + if (str2 == NULL) { + return _Py_INIT_NO_MEMORY(); + } + } + else { + str2 = NULL; + } + PyMem_RawFree(*config_str); + *config_str = str2; + return _Py_INIT_OK(); +} - if (_PyPreConfig_Copy(&config->preconfig, &config2->preconfig) < 0) { - return -1; + +static _PyInitError +_PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str, + const char *decode_err_msg) +{ + _PyInitError err = _Py_PreInitialize(NULL); + if (_Py_INIT_FAILED(err)) { + return err; } + wchar_t *str2; + if (str != NULL) { + size_t len; + str2 = Py_DecodeLocale(str, &len); + if (str2 == NULL) { + if (len == (size_t)-2) { + return _Py_INIT_ERR(decode_err_msg); + } + else { + return _Py_INIT_NO_MEMORY(); + } + } + } + else { + str2 = NULL; + } + PyMem_RawFree(*config_str); + *config_str = str2; + return _Py_INIT_OK(); +} + + +#define CONFIG_DECODE_LOCALE(config_str, str, NAME) \ + _PyCoreConfig_DecodeLocaleErr(config_str, str, "cannot decode " NAME) + + +/* Decode str using Py_DecodeLocale() and set the result into *config_str. + Pre-initialize Python if needed to ensure that encodings are properly + configured. */ +_PyInitError +_PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str) +{ + return CONFIG_DECODE_LOCALE(config_str, str, "string"); +} + + +_PyInitError +_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) +{ + _PyInitError err; + _PyCoreConfig_Clear(config); + #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR -#define COPY_STR_ATTR(ATTR) \ - do { \ - if (config2->ATTR != NULL) { \ - config->ATTR = _PyMem_RawStrdup(config2->ATTR); \ - if (config->ATTR == NULL) { \ - return -1; \ - } \ - } \ - } while (0) #define COPY_WSTR_ATTR(ATTR) \ do { \ - if (config2->ATTR != NULL) { \ - config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \ - if (config->ATTR == NULL) { \ - return -1; \ - } \ + err = _PyCoreConfig_SetString(&config->ATTR, config2->ATTR); \ + if (_Py_INIT_FAILED(err)) { \ + return err; \ } \ } while (0) #define COPY_WSTRLIST(LIST) \ do { \ if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \ - return -1; \ + return _Py_INIT_NO_MEMORY(); \ } \ } while (0) + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); COPY_ATTR(install_signal_handlers); COPY_ATTR(use_hash_seed); COPY_ATTR(hash_seed); @@ -588,10 +654,10 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_ATTR(quiet); COPY_ATTR(user_site_directory); COPY_ATTR(buffered_stdio); - COPY_STR_ATTR(filesystem_encoding); - COPY_STR_ATTR(filesystem_errors); - COPY_STR_ATTR(stdio_encoding); - COPY_STR_ATTR(stdio_errors); + COPY_WSTR_ATTR(filesystem_encoding); + COPY_WSTR_ATTR(filesystem_errors); + COPY_WSTR_ATTR(stdio_encoding); + COPY_WSTR_ATTR(stdio_errors); #ifdef MS_WINDOWS COPY_ATTR(legacy_windows_stdio); #endif @@ -599,77 +665,173 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_WSTR_ATTR(run_command); COPY_WSTR_ATTR(run_module); COPY_WSTR_ATTR(run_filename); - COPY_ATTR(_check_hash_pycs_mode); + COPY_WSTR_ATTR(check_hash_pycs_mode); COPY_ATTR(_frozen); #undef COPY_ATTR -#undef COPY_STR_ATTR #undef COPY_WSTR_ATTR #undef COPY_WSTRLIST - return 0; + return _Py_INIT_OK(); } -const char* +static PyObject * +_PyCoreConfig_AsDict(const _PyCoreConfig *config) +{ + PyObject *dict; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM(KEY, EXPR) \ + do { \ + PyObject *obj = (EXPR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) +#define SET_ITEM_INT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) +#define SET_ITEM_UINT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) +#define FROM_WSTRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromWideChar(STR, -1) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_WSTR(ATTR) \ + SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) +#define SET_ITEM_WSTRLIST(LIST) \ + SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST)) + + SET_ITEM_INT(isolated); + SET_ITEM_INT(use_environment); + SET_ITEM_INT(dev_mode); + SET_ITEM_INT(install_signal_handlers); + SET_ITEM_INT(use_hash_seed); + SET_ITEM_UINT(hash_seed); + SET_ITEM_INT(faulthandler); + SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(import_time); + SET_ITEM_INT(show_ref_count); + SET_ITEM_INT(show_alloc_count); + SET_ITEM_INT(dump_refs); + SET_ITEM_INT(malloc_stats); + SET_ITEM_WSTR(filesystem_encoding); + SET_ITEM_WSTR(filesystem_errors); + SET_ITEM_WSTR(pycache_prefix); + SET_ITEM_WSTR(program_name); + SET_ITEM_WSTRLIST(argv); + SET_ITEM_WSTR(program); + SET_ITEM_WSTRLIST(xoptions); + SET_ITEM_WSTRLIST(warnoptions); + SET_ITEM_WSTR(module_search_path_env); + SET_ITEM_WSTR(home); + SET_ITEM_WSTRLIST(module_search_paths); + SET_ITEM_WSTR(executable); + SET_ITEM_WSTR(prefix); + SET_ITEM_WSTR(base_prefix); + SET_ITEM_WSTR(exec_prefix); + SET_ITEM_WSTR(base_exec_prefix); +#ifdef MS_WINDOWS + SET_ITEM_WSTR(dll_path); +#endif + SET_ITEM_INT(site_import); + SET_ITEM_INT(bytes_warning); + SET_ITEM_INT(inspect); + SET_ITEM_INT(interactive); + SET_ITEM_INT(optimization_level); + SET_ITEM_INT(parser_debug); + SET_ITEM_INT(write_bytecode); + SET_ITEM_INT(verbose); + SET_ITEM_INT(quiet); + SET_ITEM_INT(user_site_directory); + SET_ITEM_INT(buffered_stdio); + SET_ITEM_WSTR(stdio_encoding); + SET_ITEM_WSTR(stdio_errors); +#ifdef MS_WINDOWS + SET_ITEM_INT(legacy_windows_stdio); +#endif + SET_ITEM_INT(skip_source_first_line); + SET_ITEM_WSTR(run_command); + SET_ITEM_WSTR(run_module); + SET_ITEM_WSTR(run_filename); + SET_ITEM_INT(_install_importlib); + SET_ITEM_WSTR(check_hash_pycs_mode); + SET_ITEM_INT(_frozen); + + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef FROM_WSTRING +#undef SET_ITEM +#undef SET_ITEM_INT +#undef SET_ITEM_UINT +#undef SET_ITEM_WSTR +#undef SET_ITEM_WSTRLIST +} + + +static const char* _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) { - return _PyPreConfig_GetEnv(&config->preconfig, name); + return _Py_GetEnv(config->use_environment, name); } -int +/* Get a copy of the environment variable as wchar_t*. + Return 0 on success, but *dest can be NULL. + Return -1 on memory allocation failure. Return -2 on decoding error. */ +static _PyInitError _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, wchar_t **dest, - wchar_t *wname, char *name) + wchar_t *wname, char *name, + const char *decode_err_msg) { - assert(config->preconfig.use_environment >= 0); + assert(*dest == NULL); + assert(config->use_environment >= 0); - if (!config->preconfig.use_environment) { + if (!config->use_environment) { *dest = NULL; - return 0; + return _Py_INIT_OK(); } #ifdef MS_WINDOWS const wchar_t *var = _wgetenv(wname); if (!var || var[0] == '\0') { *dest = NULL; - return 0; + return _Py_INIT_OK(); } - wchar_t *copy = _PyMem_RawWcsdup(var); - if (copy == NULL) { - return -1; - } - - *dest = copy; + return _PyCoreConfig_SetString(dest, var); #else const char *var = getenv(name); if (!var || var[0] == '\0') { *dest = NULL; - return 0; + return _Py_INIT_OK(); } - size_t len; - wchar_t *wvar = Py_DecodeLocale(var, &len); - if (!wvar) { - if (len == (size_t)-2) { - return -2; - } - else { - return -1; - } - } - *dest = wvar; + return _PyCoreConfig_DecodeLocaleErr(dest, var, decode_err_msg); #endif - return 0; } -void +#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \ + _PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME) + + +static void _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) { - _PyPreConfig_GetGlobalConfig(&config->preconfig); - #define COPY_FLAG(ATTR, VALUE) \ if (config->ATTR == -1) { \ config->ATTR = VALUE; \ @@ -679,6 +841,8 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) config->ATTR = !(VALUE); \ } + COPY_FLAG(isolated, Py_IsolatedFlag); + COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); COPY_FLAG(bytes_warning, Py_BytesWarningFlag); COPY_FLAG(inspect, Py_InspectFlag); COPY_FLAG(interactive, Py_InteractiveFlag); @@ -702,7 +866,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) /* Set Py_xxx global configuration variables from 'config' configuration. */ -void +static void _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) { #define COPY_FLAG(ATTR, VAR) \ @@ -714,6 +878,8 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) VAR = !config->ATTR; \ } + COPY_FLAG(isolated, Py_IsolatedFlag); + COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); COPY_FLAG(bytes_warning, Py_BytesWarningFlag); COPY_FLAG(inspect, Py_InspectFlag); COPY_FLAG(interactive, Py_InteractiveFlag); @@ -745,6 +911,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) static _PyInitError config_init_program_name(_PyCoreConfig *config) { + _PyInitError err; assert(config->program_name == NULL); /* If Py_SetProgramName() was called, use its value */ @@ -769,13 +936,11 @@ config_init_program_name(_PyCoreConfig *config) script. */ const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE"); if (p != NULL) { - size_t len; - wchar_t* program_name = Py_DecodeLocale(p, &len); - if (program_name == NULL) { - return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment " - "variable", (Py_ssize_t)len); + err = CONFIG_DECODE_LOCALE(&config->program_name, p, + "PYTHONEXECUTABLE environment variable"); + if (_Py_INIT_FAILED(err)) { + return err; } - config->program_name = program_name; return _Py_INIT_OK(); } #ifdef WITH_NEXT_FRAMEWORK @@ -785,13 +950,11 @@ config_init_program_name(_PyCoreConfig *config) /* Used by Mac/Tools/pythonw.c to forward * the argv0 of the stub executable */ - size_t len; - wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len); - if (program_name == NULL) { - return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment " - "variable", (Py_ssize_t)len); + err = CONFIG_DECODE_LOCALE(&config->program_name, pyvenv_launcher, + "__PYVENV_LAUNCHER__ environment variable"); + if (_Py_INIT_FAILED(err)) { + return err; } - config->program_name = program_name; return _Py_INIT_OK(); } } @@ -800,9 +963,9 @@ config_init_program_name(_PyCoreConfig *config) /* Use argv[0] by default, if available */ if (config->program != NULL) { - config->program_name = _PyMem_RawWcsdup(config->program); - if (config->program_name == NULL) { - return _Py_INIT_NO_MEMORY(); + err = _PyCoreConfig_SetString(&config->program_name, config->program); + if (_Py_INIT_FAILED(err)) { + return err; } return _Py_INIT_OK(); } @@ -813,9 +976,9 @@ config_init_program_name(_PyCoreConfig *config) #else const wchar_t *default_program_name = L"python3"; #endif - config->program_name = _PyMem_RawWcsdup(default_program_name); - if (config->program_name == NULL) { - return _Py_INIT_NO_MEMORY(); + err = _PyCoreConfig_SetString(&config->program_name, default_program_name); + if (_Py_INIT_FAILED(err)) { + return err; } return _Py_INIT_OK(); } @@ -828,13 +991,13 @@ config_init_executable(_PyCoreConfig *config) /* If Py_SetProgramFullPath() was called, use its value */ const wchar_t *program_full_path = _Py_path_config.program_full_path; if (program_full_path != NULL) { - config->executable = _PyMem_RawWcsdup(program_full_path); - if (config->executable == NULL) { - return _Py_INIT_NO_MEMORY(); + _PyInitError err = _PyCoreConfig_SetString(&config->executable, + program_full_path); + if (_Py_INIT_FAILED(err)) { + return err; } return _Py_INIT_OK(); } - return _Py_INIT_OK(); } @@ -849,25 +1012,20 @@ config_get_xoption(const _PyCoreConfig *config, wchar_t *name) static _PyInitError config_init_home(_PyCoreConfig *config) { - wchar_t *home; + assert(config->home == NULL); /* If Py_SetPythonHome() was called, use its value */ - home = _Py_path_config.home; + wchar_t *home = _Py_path_config.home; if (home) { - config->home = _PyMem_RawWcsdup(home); - if (config->home == NULL) { - return _Py_INIT_NO_MEMORY(); + _PyInitError err = _PyCoreConfig_SetString(&config->home, home); + if (_Py_INIT_FAILED(err)) { + return err; } return _Py_INIT_OK(); } - int res = _PyCoreConfig_GetEnvDup(config, &home, - L"PYTHONHOME", "PYTHONHOME"); - if (res < 0) { - return DECODE_LOCALE_ERR("PYTHONHOME", res); - } - config->home = home; - return _Py_INIT_OK(); + return CONFIG_GET_ENV_DUP(config, &config->home, + L"PYTHONHOME", "PYTHONHOME"); } @@ -887,8 +1045,8 @@ config_init_hash_seed(_PyCoreConfig *config) || seed > 4294967295UL || (errno == ERANGE && seed == ULONG_MAX)) { - return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" " - "or an integer in range [0; 4294967295]"); + return _Py_INIT_ERR("PYTHONHASHSEED must be \"random\" " + "or an integer in range [0; 4294967295]"); } /* Use a specific hash */ config->use_hash_seed = 1; @@ -924,34 +1082,35 @@ config_wstr_to_int(const wchar_t *wstr, int *result) static _PyInitError config_read_env_vars(_PyCoreConfig *config) { - _PyPreConfig *preconfig = &config->preconfig; + _PyInitError err; + int use_env = config->use_environment; /* Get environment variables */ - _Py_get_env_flag(preconfig, &config->parser_debug, "PYTHONDEBUG"); - _Py_get_env_flag(preconfig, &config->verbose, "PYTHONVERBOSE"); - _Py_get_env_flag(preconfig, &config->optimization_level, "PYTHONOPTIMIZE"); - _Py_get_env_flag(preconfig, &config->inspect, "PYTHONINSPECT"); + _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG"); + _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE"); + _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE"); + _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT"); int dont_write_bytecode = 0; - _Py_get_env_flag(preconfig, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE"); + _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE"); if (dont_write_bytecode) { config->write_bytecode = 0; } int no_user_site_directory = 0; - _Py_get_env_flag(preconfig, &no_user_site_directory, "PYTHONNOUSERSITE"); + _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE"); if (no_user_site_directory) { config->user_site_directory = 0; } int unbuffered_stdio = 0; - _Py_get_env_flag(preconfig, &unbuffered_stdio, "PYTHONUNBUFFERED"); + _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED"); if (unbuffered_stdio) { config->buffered_stdio = 0; } #ifdef MS_WINDOWS - _Py_get_env_flag(preconfig, &config->legacy_windows_stdio, + _Py_get_env_flag(use_env, &config->legacy_windows_stdio, "PYTHONLEGACYWINDOWSSTDIO"); #endif @@ -963,17 +1122,15 @@ config_read_env_vars(_PyCoreConfig *config) } if (config->module_search_path_env == NULL) { - wchar_t *path; - int res = _PyCoreConfig_GetEnvDup(config, &path, - L"PYTHONPATH", "PYTHONPATH"); - if (res < 0) { - return DECODE_LOCALE_ERR("PYTHONPATH", res); + err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env, + L"PYTHONPATH", "PYTHONPATH"); + if (_Py_INIT_FAILED(err)) { + return err; } - config->module_search_path_env = path; } if (config->use_hash_seed < 0) { - _PyInitError err = config_init_hash_seed(config); + err = config_init_hash_seed(config); if (_Py_INIT_FAILED(err)) { return err; } @@ -998,8 +1155,7 @@ config_init_tracemalloc(_PyCoreConfig *config) valid = 0; } if (!valid) { - return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number " - "of frames"); + return _Py_INIT_ERR("PYTHONTRACEMALLOC: invalid number of frames"); } config->tracemalloc = nframe; } @@ -1015,8 +1171,8 @@ config_init_tracemalloc(_PyCoreConfig *config) valid = 0; } if (!valid) { - return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: " - "invalid number of frames"); + return _Py_INIT_ERR("-X tracemalloc=NFRAME: " + "invalid number of frames"); } } else { @@ -1044,24 +1200,16 @@ config_init_pycache_prefix(_PyCoreConfig *config) } } else { - // -X pycache_prefix= can cancel the env var + // PYTHONPYCACHEPREFIX env var ignored + // if "-X pycache_prefix=" option is used config->pycache_prefix = NULL; } + return _Py_INIT_OK(); } - else { - wchar_t *env; - int res = _PyCoreConfig_GetEnvDup(config, &env, - L"PYTHONPYCACHEPREFIX", - "PYTHONPYCACHEPREFIX"); - if (res < 0) { - return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res); - } - if (env) { - config->pycache_prefix = env; - } - } - return _Py_INIT_OK(); + return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix, + L"PYTHONPYCACHEPREFIX", + "PYTHONPYCACHEPREFIX"); } @@ -1098,72 +1246,78 @@ config_read_complex_options(_PyCoreConfig *config) } -static const char * -get_stdio_errors(const _PyCoreConfig *config) +static const wchar_t * +config_get_stdio_errors(const _PyCoreConfig *config) { #ifndef MS_WINDOWS const char *loc = setlocale(LC_CTYPE, NULL); if (loc != NULL) { /* surrogateescape is the default in the legacy C and POSIX locales */ if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) { - return "surrogateescape"; + return L"surrogateescape"; } #ifdef PY_COERCE_C_LOCALE /* surrogateescape is the default in locale coercion target locales */ if (_Py_IsLocaleCoercionTarget(loc)) { - return "surrogateescape"; + return L"surrogateescape"; } #endif } - return "strict"; + return L"strict"; #else /* On Windows, always use surrogateescape by default */ - return "surrogateescape"; + return L"surrogateescape"; #endif } static _PyInitError -get_locale_encoding(char **locale_encoding) +config_get_locale_encoding(wchar_t **locale_encoding) { #ifdef MS_WINDOWS char encoding[20]; PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); -#elif defined(__ANDROID__) || defined(__VXWORKS__) - const char *encoding = "UTF-8"; + return _PyCoreConfig_DecodeLocale(locale_encoding, encoding); +#elif defined(_Py_FORCE_UTF8_LOCALE) + return _PyCoreConfig_SetString(locale_encoding, L"utf-8"); #else const char *encoding = nl_langinfo(CODESET); if (!encoding || encoding[0] == '\0') { - return _Py_INIT_USER_ERR("failed to get the locale encoding: " - "nl_langinfo(CODESET) failed"); + return _Py_INIT_ERR("failed to get the locale encoding: " + "nl_langinfo(CODESET) failed"); } + /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */ + return CONFIG_DECODE_LOCALE(locale_encoding, encoding, + "nl_langinfo(CODESET)"); #endif - *locale_encoding = _PyMem_RawStrdup(encoding); - if (*locale_encoding == NULL) { - return _Py_INIT_NO_MEMORY(); - } - return _Py_INIT_OK(); } static _PyInitError -config_init_stdio_encoding(_PyCoreConfig *config) +config_init_stdio_encoding(_PyCoreConfig *config, + const _PyPreConfig *preconfig) { + _PyInitError err; + /* If Py_SetStandardStreamEncoding() have been called, use these parameters. */ if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { - config->stdio_encoding = _PyMem_RawStrdup(_Py_StandardStreamEncoding); - if (config->stdio_encoding == NULL) { - return _Py_INIT_NO_MEMORY(); + err = CONFIG_DECODE_LOCALE(&config->stdio_encoding, + _Py_StandardStreamEncoding, + "_Py_StandardStreamEncoding"); + if (_Py_INIT_FAILED(err)) { + return err; } } if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { - config->stdio_errors = _PyMem_RawStrdup(_Py_StandardStreamErrors); - if (config->stdio_errors == NULL) { - return _Py_INIT_NO_MEMORY(); + err = CONFIG_DECODE_LOCALE(&config->stdio_errors, + _Py_StandardStreamErrors, + "_Py_StandardStreamErrors"); + if (_Py_INIT_FAILED(err)) { + return err; } } @@ -1179,22 +1333,24 @@ config_init_stdio_encoding(_PyCoreConfig *config) return _Py_INIT_NO_MEMORY(); } - char *err = strchr(pythonioencoding, ':'); - if (err) { - *err = '\0'; - err++; - if (!err[0]) { - err = NULL; + char *errors = strchr(pythonioencoding, ':'); + if (errors) { + *errors = '\0'; + errors++; + if (!errors[0]) { + errors = NULL; } } /* Does PYTHONIOENCODING contain an encoding? */ if (pythonioencoding[0]) { if (config->stdio_encoding == NULL) { - config->stdio_encoding = _PyMem_RawStrdup(pythonioencoding); - if (config->stdio_encoding == NULL) { + err = CONFIG_DECODE_LOCALE(&config->stdio_encoding, + pythonioencoding, + "PYTHONIOENCODING environment variable"); + if (_Py_INIT_FAILED(err)) { PyMem_RawFree(pythonioencoding); - return _Py_INIT_NO_MEMORY(); + return err; } } @@ -1202,16 +1358,18 @@ config_init_stdio_encoding(_PyCoreConfig *config) use "strict" error handler by default. PYTHONIOENCODING=latin1 behaves as PYTHONIOENCODING=latin1:strict. */ - if (!err) { - err = "strict"; + if (!errors) { + errors = "strict"; } } - if (config->stdio_errors == NULL && err != NULL) { - config->stdio_errors = _PyMem_RawStrdup(err); - if (config->stdio_errors == NULL) { + if (config->stdio_errors == NULL && errors != NULL) { + err = CONFIG_DECODE_LOCALE(&config->stdio_errors, + errors, + "PYTHONIOENCODING environment variable"); + if (_Py_INIT_FAILED(err)) { PyMem_RawFree(pythonioencoding); - return _Py_INIT_NO_MEMORY(); + return err; } } @@ -1219,199 +1377,123 @@ config_init_stdio_encoding(_PyCoreConfig *config) } /* UTF-8 Mode uses UTF-8/surrogateescape */ - if (config->preconfig.utf8_mode) { + if (preconfig->utf8_mode) { if (config->stdio_encoding == NULL) { - config->stdio_encoding = _PyMem_RawStrdup("utf-8"); - if (config->stdio_encoding == NULL) { - return _Py_INIT_NO_MEMORY(); + err = _PyCoreConfig_SetString(&config->stdio_encoding, L"utf-8"); + if (_Py_INIT_FAILED(err)) { + return err; } } if (config->stdio_errors == NULL) { - config->stdio_errors = _PyMem_RawStrdup("surrogateescape"); - if (config->stdio_errors == NULL) { - return _Py_INIT_NO_MEMORY(); + err = _PyCoreConfig_SetString(&config->stdio_errors, + L"surrogateescape"); + if (_Py_INIT_FAILED(err)) { + return err; } } } /* Choose the default error handler based on the current locale. */ if (config->stdio_encoding == NULL) { - _PyInitError err = get_locale_encoding(&config->stdio_encoding); + err = config_get_locale_encoding(&config->stdio_encoding); if (_Py_INIT_FAILED(err)) { return err; } } if (config->stdio_errors == NULL) { - const char *errors = get_stdio_errors(config); - config->stdio_errors = _PyMem_RawStrdup(errors); - if (config->stdio_errors == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } + const wchar_t *errors = config_get_stdio_errors(config); + assert(errors != NULL); - return _Py_INIT_OK(); -} - - -static _PyInitError -config_init_fs_encoding(_PyCoreConfig *config) -{ -#ifdef MS_WINDOWS - if (config->preconfig.legacy_windows_fs_encoding) { - /* Legacy Windows filesystem encoding: mbcs/replace */ - if (config->filesystem_encoding == NULL) { - config->filesystem_encoding = _PyMem_RawStrdup("mbcs"); - if (config->filesystem_encoding == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - if (config->filesystem_errors == NULL) { - config->filesystem_errors = _PyMem_RawStrdup("replace"); - if (config->filesystem_errors == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - } - - /* Windows defaults to utf-8/surrogatepass (PEP 529). - - Note: UTF-8 Mode takes the same code path and the Legacy Windows FS - encoding has the priortiy over UTF-8 Mode. */ - if (config->filesystem_encoding == NULL) { - config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); - if (config->filesystem_encoding == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - if (config->filesystem_errors == NULL) { - config->filesystem_errors = _PyMem_RawStrdup("surrogatepass"); - if (config->filesystem_errors == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } -#else - if (config->filesystem_encoding == NULL) { - if (config->preconfig.utf8_mode) { - /* UTF-8 Mode use: utf-8/surrogateescape */ - config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); - /* errors defaults to surrogateescape above */ - } - else if (_Py_GetForceASCII()) { - config->filesystem_encoding = _PyMem_RawStrdup("ascii"); - } - else { - /* macOS and Android use UTF-8, - other platforms use the locale encoding. */ -#if defined(__APPLE__) || defined(__ANDROID__) - config->filesystem_encoding = _PyMem_RawStrdup("utf-8"); -#else - _PyInitError err = get_locale_encoding(&config->filesystem_encoding); - if (_Py_INIT_FAILED(err)) { - return err; - } -#endif - } - - if (config->filesystem_encoding == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } - - if (config->filesystem_errors == NULL) { - /* by default, use the "surrogateescape" error handler */ - config->filesystem_errors = _PyMem_RawStrdup("surrogateescape"); - if (config->filesystem_errors == NULL) { - return _Py_INIT_NO_MEMORY(); - } - } -#endif - return _Py_INIT_OK(); -} - - -static _PyInitError -_PyCoreConfig_ReadPreConfig(_PyCoreConfig *config) -{ - _PyInitError err; - _PyPreConfig local_preconfig = _PyPreConfig_INIT; - _PyPreConfig_GetGlobalConfig(&local_preconfig); - - if (_PyPreConfig_Copy(&local_preconfig, &config->preconfig) < 0) { - err = _Py_INIT_NO_MEMORY(); - goto done; - } - - err = _PyPreConfig_Read(&local_preconfig); - if (_Py_INIT_FAILED(err)) { - goto done; - } - - if (_PyPreConfig_Copy(&config->preconfig, &local_preconfig) < 0) { - err = _Py_INIT_NO_MEMORY(); - goto done; - } - err = _Py_INIT_OK(); - -done: - _PyPreConfig_Clear(&local_preconfig); - return err; -} - - -static _PyInitError -_PyCoreConfig_GetPreConfig(_PyCoreConfig *config) -{ - /* Read config written by _PyPreConfig_Write() */ - if (_PyPreConfig_Copy(&config->preconfig, &_PyRuntime.preconfig) < 0) { - return _Py_INIT_NO_MEMORY(); - } - return _Py_INIT_OK(); -} - - -/* Read the configuration into _PyCoreConfig from: - - * Environment variables - * Py_xxx global configuration variables - - See _PyCoreConfig_ReadFromArgv() to parse also command line arguments. */ -_PyInitError -_PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig) -{ - _PyInitError err; - - err = _Py_PreInitialize(); - if (_Py_INIT_FAILED(err)) { - return err; - } - - err = _PyCoreConfig_GetPreConfig(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - _PyCoreConfig_GetGlobalConfig(config); - - if (preconfig != NULL) { - if (_PyPreConfig_Copy(&config->preconfig, preconfig) < 0) { - return _Py_INIT_NO_MEMORY(); - } - } - else { - err = _PyCoreConfig_ReadPreConfig(config); + err = _PyCoreConfig_SetString(&config->stdio_errors, errors); if (_Py_INIT_FAILED(err)) { return err; } } - assert(config->preconfig.use_environment >= 0); + return _Py_INIT_OK(); +} - if (config->preconfig.isolated > 0) { + +static _PyInitError +config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) +{ + _PyInitError err; + + if (config->filesystem_encoding == NULL) { +#ifdef _Py_FORCE_UTF8_FS_ENCODING + err = _PyCoreConfig_SetString(&config->filesystem_encoding, L"utf-8"); +#else + +#ifdef MS_WINDOWS + if (preconfig->legacy_windows_fs_encoding) { + /* Legacy Windows filesystem encoding: mbcs/replace */ + err = _PyCoreConfig_SetString(&config->filesystem_encoding, + L"mbcs"); + } + else +#endif + if (preconfig->utf8_mode) { + err = _PyCoreConfig_SetString(&config->filesystem_encoding, + L"utf-8"); + } +#ifndef MS_WINDOWS + else if (_Py_GetForceASCII()) { + err = _PyCoreConfig_SetString(&config->filesystem_encoding, + L"ascii"); + } +#endif + else { +#ifdef MS_WINDOWS + /* Windows defaults to utf-8/surrogatepass (PEP 529). */ + err = _PyCoreConfig_SetString(&config->filesystem_encoding, + L"utf-8"); +#else + err = config_get_locale_encoding(&config->filesystem_encoding); +#endif + } +#endif /* !_Py_FORCE_UTF8_FS_ENCODING */ + + if (_Py_INIT_FAILED(err)) { + return err; + } + } + + if (config->filesystem_errors == NULL) { + const wchar_t *errors; +#ifdef MS_WINDOWS + if (preconfig->legacy_windows_fs_encoding) { + errors = L"replace"; + } + else { + errors = L"surrogatepass"; + } +#else + errors = L"surrogateescape"; +#endif + err = _PyCoreConfig_SetString(&config->filesystem_errors, errors); + if (_Py_INIT_FAILED(err)) { + return err; + } + } + return _Py_INIT_OK(); +} + + +static _PyInitError +config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline) +{ + _PyInitError err; + const _PyPreConfig *preconfig = &_PyRuntime.preconfig; + + if (_PyPreCmdline_SetCoreConfig(cmdline, config) < 0) { + return _Py_INIT_NO_MEMORY(); + } + + if (config->isolated > 0) { config->user_site_directory = 0; } - if (config->preconfig.use_environment) { + if (config->use_environment) { err = config_read_env_vars(config); if (_Py_INIT_FAILED(err)) { return err; @@ -1460,30 +1542,30 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig) } /* default values */ - if (config->preconfig.dev_mode) { + if (config->dev_mode) { if (config->faulthandler < 0) { config->faulthandler = 1; } } - if (config->use_hash_seed < 0) { - config->use_hash_seed = 0; - config->hash_seed = 0; - } if (config->faulthandler < 0) { config->faulthandler = 0; } if (config->tracemalloc < 0) { config->tracemalloc = 0; } + if (config->use_hash_seed < 0) { + config->use_hash_seed = 0; + config->hash_seed = 0; + } if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) { - err = config_init_fs_encoding(config); + err = config_init_fs_encoding(config, preconfig); if (_Py_INIT_FAILED(err)) { return err; } } - err = config_init_stdio_encoding(config); + err = config_init_stdio_encoding(config, preconfig); if (_Py_INIT_FAILED(err)) { return err; } @@ -1495,14 +1577,6 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig) } } - assert(config->preconfig.use_environment >= 0); - assert(config->filesystem_encoding != NULL); - assert(config->filesystem_errors != NULL); - assert(config->stdio_encoding != NULL); - assert(config->stdio_errors != NULL); - assert(config->_check_hash_pycs_mode != NULL); - assert(_PyWstrList_CheckConsistency(&config->argv)); - return _Py_INIT_OK(); } @@ -1549,157 +1623,48 @@ config_init_stdio(const _PyCoreConfig *config) - set Py_xxx global configuration variables - initialize C standard streams (stdin, stdout, stderr) */ void -_PyCoreConfig_Write(const _PyCoreConfig *config) +_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime) { _PyCoreConfig_SetGlobalConfig(config); config_init_stdio(config); -} - -PyObject * -_PyCoreConfig_AsDict(const _PyCoreConfig *config) -{ - PyObject *dict; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - - if (_PyPreConfig_AsDict(&config->preconfig, dict) < 0) { - Py_DECREF(dict); - return NULL; - } - -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_INT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) -#define SET_ITEM_UINT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) -#define SET_ITEM_STR(ATTR) \ - SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) -#define FROM_WSTRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_WSTR(ATTR) \ - SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) -#define SET_ITEM_WSTRLIST(LIST) \ - SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST)) - - SET_ITEM_INT(install_signal_handlers); - SET_ITEM_INT(use_hash_seed); - SET_ITEM_UINT(hash_seed); - SET_ITEM_INT(faulthandler); - SET_ITEM_INT(tracemalloc); - SET_ITEM_INT(import_time); - SET_ITEM_INT(show_ref_count); - SET_ITEM_INT(show_alloc_count); - SET_ITEM_INT(dump_refs); - SET_ITEM_INT(malloc_stats); - SET_ITEM_STR(filesystem_encoding); - SET_ITEM_STR(filesystem_errors); - SET_ITEM_WSTR(pycache_prefix); - SET_ITEM_WSTR(program_name); - SET_ITEM_WSTRLIST(argv); - SET_ITEM_WSTR(program); - SET_ITEM_WSTRLIST(xoptions); - SET_ITEM_WSTRLIST(warnoptions); - SET_ITEM_WSTR(module_search_path_env); - SET_ITEM_WSTR(home); - SET_ITEM_WSTRLIST(module_search_paths); - SET_ITEM_WSTR(executable); - SET_ITEM_WSTR(prefix); - SET_ITEM_WSTR(base_prefix); - SET_ITEM_WSTR(exec_prefix); - SET_ITEM_WSTR(base_exec_prefix); -#ifdef MS_WINDOWS - SET_ITEM_WSTR(dll_path); -#endif - SET_ITEM_INT(site_import); - SET_ITEM_INT(bytes_warning); - SET_ITEM_INT(inspect); - SET_ITEM_INT(interactive); - SET_ITEM_INT(optimization_level); - SET_ITEM_INT(parser_debug); - SET_ITEM_INT(write_bytecode); - SET_ITEM_INT(verbose); - SET_ITEM_INT(quiet); - SET_ITEM_INT(user_site_directory); - SET_ITEM_INT(buffered_stdio); - SET_ITEM_STR(stdio_encoding); - SET_ITEM_STR(stdio_errors); -#ifdef MS_WINDOWS - SET_ITEM_INT(legacy_windows_stdio); -#endif - SET_ITEM_INT(skip_source_first_line); - SET_ITEM_WSTR(run_command); - SET_ITEM_WSTR(run_module); - SET_ITEM_WSTR(run_filename); - SET_ITEM_INT(_install_importlib); - SET_ITEM_STR(_check_hash_pycs_mode); - SET_ITEM_INT(_frozen); - - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef FROM_STRING -#undef FROM_WSTRING -#undef SET_ITEM -#undef SET_ITEM_INT -#undef SET_ITEM_UINT -#undef SET_ITEM_STR -#undef SET_ITEM_WSTR -#undef SET_ITEM_WSTRLIST -} - - -/* --- _PyCmdline ------------------------------------------------- */ - -typedef struct { - _PyPreCmdline precmdline; - _PyWstrList warnoptions; /* Command line -W options */ - _PyWstrList env_warnoptions; /* PYTHONWARNINGS environment variables */ - int print_help; /* -h, -? options */ - int print_version; /* -V option */ -} _PyCmdline; - - -static void -cmdline_clear(_PyCmdline *cmdline) -{ - _PyPreCmdline_Clear(&cmdline->precmdline); - _PyWstrList_Clear(&cmdline->warnoptions); - _PyWstrList_Clear(&cmdline->env_warnoptions); + /* Write the new pre-configuration into _PyRuntime */ + _PyPreConfig *preconfig = &runtime->preconfig; + preconfig->isolated = config->isolated; + preconfig->use_environment = config->use_environment; + preconfig->dev_mode = config->dev_mode; } /* --- _PyCoreConfig command line parser -------------------------- */ +static void +config_usage(int error, const wchar_t* program) +{ + FILE *f = error ? stderr : stdout; + + fprintf(f, usage_line, program); + if (error) + fprintf(f, "Try `python -h' for more information.\n"); + else { + fputs(usage_1, f); + fputs(usage_2, f); + fputs(usage_3, f); + fprintf(f, usage_4, (wint_t)DELIM); + fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP); + fputs(usage_6, f); + } +} + + /* Parse the command line arguments */ static _PyInitError -config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, - int *need_usage) +config_parse_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline, + _PyWstrList *warnoptions) { - const _PyWstrList *argv = &cmdline->precmdline.argv; + _PyInitError err; + const _PyWstrList *argv = &precmdline->argv; + int print_version = 0; _PyOS_ResetGetOpt(); do { @@ -1744,17 +1709,20 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, case 0: // Handle long option. assert(longindex == 0); // Only one long option now. - if (!wcscmp(_PyOS_optarg, L"always")) { - config->_check_hash_pycs_mode = "always"; - } else if (!wcscmp(_PyOS_optarg, L"never")) { - config->_check_hash_pycs_mode = "never"; - } else if (!wcscmp(_PyOS_optarg, L"default")) { - config->_check_hash_pycs_mode = "default"; + if (wcscmp(_PyOS_optarg, L"always") == 0 + || wcscmp(_PyOS_optarg, L"never") == 0 + || wcscmp(_PyOS_optarg, L"default") == 0) + { + err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode, + _PyOS_optarg); + if (_Py_INIT_FAILED(err)) { + return err; + } } else { fprintf(stderr, "--check-hash-based-pycs must be one of " "'default', 'always', or 'never'\n"); - *need_usage = 1; - return _Py_INIT_OK(); + config_usage(1, config->program); + return _Py_INIT_EXIT(2); } break; @@ -1774,7 +1742,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, case 'E': case 'I': case 'X': - /* option handled by _PyPreConfig_ReadFromArgv() */ + /* option handled by _PyPreCmdline_Read() */ break; /* case 'J': reserved for Jython */ @@ -1813,15 +1781,15 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, case 'h': case '?': - cmdline->print_help++; - break; + config_usage(0, config->program); + return _Py_INIT_EXIT(0); case 'V': - cmdline->print_version++; + print_version++; break; case 'W': - if (_PyWstrList_Append(&cmdline->warnoptions, _PyOS_optarg) < 0) { + if (_PyWstrList_Append(warnoptions, _PyOS_optarg) < 0) { return _Py_INIT_NO_MEMORY(); } break; @@ -1838,11 +1806,17 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, default: /* unknown argument: parsing failed */ - *need_usage = 1; - return _Py_INIT_OK(); + config_usage(1, config->program); + return _Py_INIT_EXIT(2); } } while (1); + if (print_version) { + printf("Python %s\n", + (print_version >= 2) ? Py_GetVersion() : PY_VERSION); + return _Py_INIT_EXIT(0); + } + if (config->run_command == NULL && config->run_module == NULL && _PyOS_optind < argv->length && wcscmp(argv->items[_PyOS_optind], L"-") != 0 @@ -1874,15 +1848,18 @@ config_parse_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, /* Get warning options from PYTHONWARNINGS environment variable. */ static _PyInitError -cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config) +config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions) { - wchar_t *env; - int res = _PyCoreConfig_GetEnvDup(config, &env, - L"PYTHONWARNINGS", "PYTHONWARNINGS"); - if (res < 0) { - return DECODE_LOCALE_ERR("PYTHONWARNINGS", res); + _PyInitError err; + /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */ + wchar_t *env = NULL; + err = CONFIG_GET_ENV_DUP(config, &env, + L"PYTHONWARNINGS", "PYTHONWARNINGS"); + if (_Py_INIT_FAILED(err)) { + return err; } + /* env var is not set or is empty */ if (env == NULL) { return _Py_INIT_OK(); } @@ -1893,7 +1870,7 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config) warning != NULL; warning = WCSTOK(NULL, L",", &context)) { - if (_PyWstrList_Append(&cmdline->env_warnoptions, warning) < 0) { + if (_PyWstrList_Append(warnoptions, warning) < 0) { PyMem_RawFree(env); return _Py_INIT_NO_MEMORY(); } @@ -1904,9 +1881,9 @@ cmdline_init_env_warnoptions(_PyCmdline *cmdline, const _PyCoreConfig *config) static _PyInitError -config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline) +config_init_program(_PyCoreConfig *config, const _PyPreCmdline *cmdline) { - const _PyWstrList *argv = &cmdline->precmdline.argv; + const _PyWstrList *argv = &cmdline->argv; wchar_t *program; if (argv->length >= 1) { program = argv->items[0]; @@ -1923,11 +1900,25 @@ config_init_program(_PyCoreConfig *config, const _PyCmdline *cmdline) } -static _PyInitError -config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) +static int +config_add_warnoption(_PyCoreConfig *config, const wchar_t *option) { - assert(config->warnoptions.length == 0); + if (_PyWstrList_Find(&config->warnoptions, option)) { + /* Already present: do nothing */ + return 0; + } + if (_PyWstrList_Append(&config->warnoptions, option)) { + return -1; + } + return 0; +} + +static _PyInitError +config_init_warnoptions(_PyCoreConfig *config, + const _PyWstrList *cmdline_warnoptions, + const _PyWstrList *env_warnoptions) +{ /* The priority order for warnings configuration is (highest precedence * first): * @@ -1943,18 +1934,27 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) * the lowest precedence entries first so that later entries override them. */ - if (config->preconfig.dev_mode) { - if (_PyWstrList_Append(&config->warnoptions, L"default")) { + if (config->dev_mode) { + if (config_add_warnoption(config, L"default") < 0) { return _Py_INIT_NO_MEMORY(); } } - if (_PyWstrList_Extend(&config->warnoptions, &cmdline->env_warnoptions) < 0) { - return _Py_INIT_NO_MEMORY(); + Py_ssize_t i; + const _PyWstrList *options; + + options = env_warnoptions; + for (i = 0; i < options->length; i++) { + if (config_add_warnoption(config, options->items[i]) < 0) { + return _Py_INIT_NO_MEMORY(); + } } - if (_PyWstrList_Extend(&config->warnoptions, &cmdline->warnoptions) < 0) { - return _Py_INIT_NO_MEMORY(); + options = cmdline_warnoptions; + for (i = 0; i < options->length; i++) { + if (config_add_warnoption(config, options->items[i]) < 0) { + return _Py_INIT_NO_MEMORY(); + } } /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c @@ -1969,7 +1969,7 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) else { filter = L"default::BytesWarning"; } - if (_PyWstrList_Append(&config->warnoptions, filter)) { + if (config_add_warnoption(config, filter) < 0) { return _Py_INIT_NO_MEMORY(); } } @@ -1978,9 +1978,9 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline) static _PyInitError -config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline) +config_init_argv(_PyCoreConfig *config, const _PyPreCmdline *cmdline) { - const _PyWstrList *cmdline_argv = &cmdline->precmdline.argv; + const _PyWstrList *cmdline_argv = &cmdline->argv; _PyWstrList config_argv = _PyWstrList_INIT; /* Copy argv to be able to modify it (to force -c/-m) */ @@ -2026,100 +2026,130 @@ config_init_argv(_PyCoreConfig *config, const _PyCmdline *cmdline) } -static void -config_usage(int error, const wchar_t* program) +static _PyInitError +core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline) { - FILE *f = error ? stderr : stdout; + _PyInitError err; - fprintf(f, usage_line, program); - if (error) - fprintf(f, "Try `python -h' for more information.\n"); - else { - fputs(usage_1, f); - fputs(usage_2, f); - fputs(usage_3, f); - fprintf(f, usage_4, (wint_t)DELIM); - fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP); - fputs(usage_6, f); + if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) { + return _Py_INIT_NO_MEMORY(); } + + _PyPreConfig preconfig = _PyPreConfig_INIT; + if (_PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig) < 0) { + err = _Py_INIT_NO_MEMORY(); + goto done; + } + + _PyCoreConfig_GetCoreConfig(&preconfig, config); + + err = _PyPreCmdline_Read(precmdline, &preconfig); + +done: + _PyPreConfig_Clear(&preconfig); + return err; } -/* Parse command line options and environment variables. */ static _PyInitError -config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, - const _PyPreConfig *preconfig) +config_read_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline) { - int need_usage = 0; _PyInitError err; + _PyWstrList cmdline_warnoptions = _PyWstrList_INIT; + _PyWstrList env_warnoptions = _PyWstrList_INIT; - _PyCoreConfig_GetGlobalConfig(config); + err = config_parse_cmdline(config, precmdline, &cmdline_warnoptions); + if (_Py_INIT_FAILED(err)) { + goto done; + } - if (config->program == NULL) { - err = config_init_program(config, cmdline); + err = config_init_argv(config, precmdline); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + err = config_read(config, precmdline); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + if (config->use_environment) { + err = config_init_env_warnoptions(config, &env_warnoptions); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } } - err = _PyPreCmdline_Read(&cmdline->precmdline); + err = config_init_warnoptions(config, + &cmdline_warnoptions, &env_warnoptions); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } - _PyPreCmdline_SetPreConfig(&cmdline->precmdline, &config->preconfig); - if (_PyWstrList_Extend(&config->xoptions, &cmdline->precmdline.xoptions) < 0) { - return _Py_INIT_NO_MEMORY(); - } - - err = config_parse_cmdline(config, cmdline, &need_usage); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (need_usage) { - config_usage(1, config->program); - return _Py_INIT_EXIT(2); - } - - if (cmdline->print_help) { - config_usage(0, config->program); - return _Py_INIT_EXIT(0); - } - - if (cmdline->print_version) { - printf("Python %s\n", - (cmdline->print_version >= 2) ? Py_GetVersion() : PY_VERSION); - return _Py_INIT_EXIT(0); - } - - err = config_init_argv(config, cmdline); - if (_Py_INIT_FAILED(err)) { - return err; - } - - err = _PyCoreConfig_Read(config, preconfig); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (config->preconfig.use_environment) { - err = cmdline_init_env_warnoptions(cmdline, config); + if (config->check_hash_pycs_mode == NULL) { + err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode, L"default"); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } } - err = config_init_warnoptions(config, cmdline); - if (_Py_INIT_FAILED(err)) { - return err; - } + err = _Py_INIT_OK(); - const _PyWstrList *argv = &cmdline->precmdline.argv; - if (_Py_SetArgcArgv(argv->length, argv->items) < 0) { - return _Py_INIT_NO_MEMORY(); +done: + _PyWstrList_Clear(&cmdline_warnoptions); + _PyWstrList_Clear(&env_warnoptions); + return err; +} + + +_PyInitError +_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args) +{ + if (args->use_bytes_argv) { + _PyInitError err; + + err = _PyRuntime_Initialize(); + if (_Py_INIT_FAILED(err)) { + return err; + } + _PyRuntimeState *runtime = &_PyRuntime; + + /* do nothing if Python is already pre-initialized: + _PyCoreConfig_Write() will update _PyRuntime.preconfig later */ + if (!runtime->pre_initialized) { + err = _Py_PreInitializeFromCoreConfig(config, args); + if (_Py_INIT_FAILED(err)) { + return err; + } + } } - return _Py_INIT_OK(); + return _PyArgv_AsWstrList(args, &config->argv); +} + + +/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python + if needed to ensure that encodings are properly configured. */ +_PyInitError +_PyCoreConfig_SetArgv(_PyCoreConfig *config, int argc, char **argv) +{ + _PyArgv args = { + .argc = argc, + .use_bytes_argv = 1, + .bytes_argv = argv, + .wchar_argv = NULL}; + return _PyCoreConfig_SetPyArgv(config, &args); +} + + +_PyInitError +_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, int argc, wchar_t **argv) +{ + _PyArgv args = { + .argc = argc, + .use_bytes_argv = 0, + .bytes_argv = NULL, + .wchar_argv = argv}; + return _PyCoreConfig_SetPyArgv(config, &args); } @@ -2129,30 +2159,143 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline, * Environment variables * Py_xxx global configuration variables */ _PyInitError -_PyCoreConfig_ReadFromArgv(_PyCoreConfig *config, const _PyArgv *args, - const _PyPreConfig *preconfig) +_PyCoreConfig_Read(_PyCoreConfig *config) { _PyInitError err; - err = _Py_PreInitialize(); + err = _Py_PreInitializeFromCoreConfig(config, NULL); if (_Py_INIT_FAILED(err)) { return err; } - _PyCmdline cmdline = {.precmdline = _PyPreCmdline_INIT}; + _PyCoreConfig_GetGlobalConfig(config); - err = _PyPreCmdline_Init(&cmdline.precmdline, args); + _PyPreCmdline precmdline = _PyPreCmdline_INIT; + err = core_read_precmdline(config, &precmdline); if (_Py_INIT_FAILED(err)) { goto done; } - err = config_from_cmdline(config, &cmdline, preconfig); + if (config->program == NULL) { + err = config_init_program(config, &precmdline); + if (_Py_INIT_FAILED(err)) { + goto done; + } + } + + err = config_read_cmdline(config, &precmdline); if (_Py_INIT_FAILED(err)) { goto done; } + + const _PyWstrList *argv = &precmdline.argv; + if (_Py_SetArgcArgv(argv->length, argv->items) < 0) { + err = _Py_INIT_NO_MEMORY(); + goto done; + } + + /* Check config consistency */ + assert(config->isolated >= 0); + assert(config->use_environment >= 0); + assert(config->dev_mode >= 0); + assert(config->install_signal_handlers >= 0); + assert(config->use_hash_seed >= 0); + assert(config->faulthandler >= 0); + assert(config->tracemalloc >= 0); + assert(config->site_import >= 0); + assert(config->bytes_warning >= 0); + assert(config->inspect >= 0); + assert(config->interactive >= 0); + assert(config->optimization_level >= 0); + assert(config->parser_debug >= 0); + assert(config->write_bytecode >= 0); + assert(config->verbose >= 0); + assert(config->quiet >= 0); + assert(config->user_site_directory >= 0); + assert(config->buffered_stdio >= 0); + assert(config->program_name != NULL); + assert(config->program != NULL); + assert(_PyWstrList_CheckConsistency(&config->argv)); + assert(_PyWstrList_CheckConsistency(&config->xoptions)); + assert(_PyWstrList_CheckConsistency(&config->warnoptions)); + assert(_PyWstrList_CheckConsistency(&config->module_search_paths)); + if (config->_install_importlib) { + assert(config->executable != NULL); + assert(config->prefix != NULL); + assert(config->base_prefix != NULL); + assert(config->exec_prefix != NULL); + assert(config->base_exec_prefix != NULL); +#ifdef MS_WINDOWS + assert(config->dll_path != NULL); +#endif + } + assert(config->filesystem_encoding != NULL); + assert(config->filesystem_errors != NULL); + assert(config->stdio_encoding != NULL); + assert(config->stdio_errors != NULL); +#ifdef MS_WINDOWS + assert(config->legacy_windows_stdio >= 0); +#endif + assert(config->check_hash_pycs_mode != NULL); + assert(config->_install_importlib >= 0); + assert(config->_frozen >= 0); + err = _Py_INIT_OK(); done: - cmdline_clear(&cmdline); + _PyPreCmdline_Clear(&precmdline); return err; } + + +PyObject* +_Py_GetConfigsAsDict(void) +{ + PyObject *config = NULL; + PyObject *dict = NULL; + + config = PyDict_New(); + if (config == NULL) { + goto error; + } + + /* global config */ + dict = _Py_GetGlobalVariablesAsDict(); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(config, "global_config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + + /* pre config */ + PyInterpreterState *interp = _PyInterpreterState_Get(); + const _PyPreConfig *pre_config = &_PyRuntime.preconfig; + dict = _PyPreConfig_AsDict(pre_config); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(config, "pre_config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + + /* core config */ + const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp); + dict = _PyCoreConfig_AsDict(core_config); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(config, "core_config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + + return config; + +error: + Py_XDECREF(config); + Py_XDECREF(dict); + return NULL; +} diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index e5bddaab6ca..c51f97abd28 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -38,9 +38,10 @@ const char *_PyImport_DynLoadFiletab[] = { ".dll", #else /* !__CYGWIN__ */ "." SOABI ".so", -#ifndef Py_DEBUG +#ifdef ALT_SOABI + "." ALT_SOABI ".so", +#endif ".abi" PYTHON_ABI_STRING ".so", -#endif /* ! Py_DEBUG */ ".so", #endif /* __CYGWIN__ */ NULL, diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 36918c3579d..457d47f5eed 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -215,12 +215,14 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, #if HAVE_SXS cookie = _Py_ActivateActCtx(); #endif - /* We use LoadLibraryEx so Windows looks for dependent DLLs - in directory of pathname first. */ - /* XXX This call doesn't exist in Windows CE */ + /* bpo-36085: We use LoadLibraryEx with restricted search paths + to avoid DLL preloading attacks and enable use of the + AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to + ensure DLLs adjacent to the PYD are preferred. */ Py_BEGIN_ALLOW_THREADS hDLL = LoadLibraryExW(wpathname, NULL, - LOAD_WITH_ALTERED_SEARCH_PATH); + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); Py_END_ALLOW_THREADS #if HAVE_SXS _Py_DeactivateActCtx(cookie); diff --git a/Python/fileutils.c b/Python/fileutils.c index b933874193b..dfad48edb81 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -85,7 +85,7 @@ _Py_device_encoding(int fd) Py_RETURN_NONE; } -#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) +#if !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) #define USE_FORCE_ASCII @@ -309,7 +309,7 @@ _Py_ResetForceASCII(void) { /* nothing to do */ } -#endif /* !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) */ +#endif /* !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) */ #if !defined(HAVE_MBRTOWC) || defined(USE_FORCE_ASCII) @@ -536,7 +536,7 @@ _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, int current_locale, _Py_error_handler errors) { if (current_locale) { -#if defined(__ANDROID__) || defined(__VXWORKS__) +#ifdef _Py_FORCE_UTF8_LOCALE return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, errors); #else @@ -544,7 +544,7 @@ _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, #endif } -#if defined(__APPLE__) || defined(__ANDROID__) || defined(__VXWORKS__) +#ifdef _Py_FORCE_UTF8_FS_ENCODING return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, errors); #else @@ -569,7 +569,7 @@ _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, #endif return decode_current_locale(arg, wstr, wlen, reason, errors); -#endif /* __APPLE__ or __ANDROID__ or __VXWORKS__ */ +#endif /* !_Py_FORCE_UTF8_FS_ENCODING */ } @@ -727,7 +727,7 @@ encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, int raw_malloc, int current_locale, _Py_error_handler errors) { if (current_locale) { -#ifdef __ANDROID__ +#ifdef _Py_FORCE_UTF8_LOCALE return _Py_EncodeUTF8Ex(text, str, error_pos, reason, raw_malloc, errors); #else @@ -736,7 +736,7 @@ encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, #endif } -#if defined(__APPLE__) || defined(__ANDROID__) +#ifdef _Py_FORCE_UTF8_FS_ENCODING return _Py_EncodeUTF8Ex(text, str, error_pos, reason, raw_malloc, errors); #else @@ -762,7 +762,7 @@ encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, return encode_current_locale(text, str, error_pos, reason, raw_malloc, errors); -#endif /* __APPLE__ or __ANDROID__ */ +#endif /* _Py_FORCE_UTF8_FS_ENCODING */ } static char* diff --git a/Python/frozen.c b/Python/frozen.c index f1901d24dee..228a11019cf 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -15,15 +15,15 @@ the appropriate bytes from M___main__.c. */ static unsigned char M___hello__[] = { - 227,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,64,0,0,0,115,16,0,0,0,100,0,90,0,101,1, - 100,1,131,1,1,0,100,2,83,0,41,3,84,122,12,72, - 101,108,108,111,32,119,111,114,108,100,33,78,41,2,218,11, - 105,110,105,116,105,97,108,105,122,101,100,218,5,112,114,105, - 110,116,169,0,114,3,0,0,0,114,3,0,0,0,250,22, - 46,47,84,111,111,108,115,47,102,114,101,101,122,101,47,102, - 108,97,103,46,112,121,218,8,60,109,111,100,117,108,101,62, - 1,0,0,0,115,2,0,0,0,4,1, + 227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0, + 90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3, + 84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78, + 41,2,218,11,105,110,105,116,105,97,108,105,122,101,100,218, + 5,112,114,105,110,116,169,0,114,3,0,0,0,114,3,0, + 0,0,250,20,84,111,111,108,115,47,102,114,101,101,122,101, + 47,102,108,97,103,46,112,121,218,8,60,109,111,100,117,108, + 101,62,1,0,0,0,115,2,0,0,0,4,1, }; #define SIZE (int)sizeof(M___hello__) diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 6554aa75b03..a777576ad78 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -18,9 +18,7 @@ Py_FrozenMain(int argc, char **argv) { _PyInitError err = _PyRuntime_Initialize(); if (_Py_INIT_FAILED(err)) { - fprintf(stderr, "Fatal Python error: %s\n", err.msg); - fflush(stderr); - exit(1); + _Py_ExitInitError(err); } const char *p; diff --git a/Python/graminit.c b/Python/graminit.c index 441502e9087..0587b1c0fc1 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -1,17 +1,16 @@ /* Generated by Parser/pgen */ -#include "pgenheaders.h" #include "grammar.h" grammar _PyParser_Grammar; -static arc arcs_0_0[3] = { +static const arc arcs_0_0[3] = { {2, 1}, {3, 2}, {4, 1}, }; -static arc arcs_0_1[1] = { +static const arc arcs_0_1[1] = { {0, 1}, }; -static arc arcs_0_2[1] = { +static const arc arcs_0_2[1] = { {2, 1}, }; static state states_0[3] = { @@ -19,26 +18,26 @@ static state states_0[3] = { {1, arcs_0_1}, {1, arcs_0_2}, }; -static arc arcs_1_0[3] = { +static const arc arcs_1_0[3] = { {44, 1}, {2, 0}, {45, 0}, }; -static arc arcs_1_1[1] = { +static const arc arcs_1_1[1] = { {0, 1}, }; static state states_1[2] = { {3, arcs_1_0}, {1, arcs_1_1}, }; -static arc arcs_2_0[1] = { +static const arc arcs_2_0[1] = { {47, 1}, }; -static arc arcs_2_1[2] = { +static const arc arcs_2_1[2] = { {44, 2}, {2, 1}, }; -static arc arcs_2_2[1] = { +static const arc arcs_2_2[1] = { {0, 2}, }; static state states_2[3] = { @@ -46,27 +45,27 @@ static state states_2[3] = { {2, arcs_2_1}, {1, arcs_2_2}, }; -static arc arcs_3_0[1] = { +static const arc arcs_3_0[1] = { {10, 1}, }; -static arc arcs_3_1[1] = { +static const arc arcs_3_1[1] = { {49, 2}, }; -static arc arcs_3_2[2] = { +static const arc arcs_3_2[2] = { {5, 3}, {2, 4}, }; -static arc arcs_3_3[2] = { +static const arc arcs_3_3[2] = { {50, 5}, {51, 6}, }; -static arc arcs_3_4[1] = { +static const arc arcs_3_4[1] = { {0, 4}, }; -static arc arcs_3_5[1] = { +static const arc arcs_3_5[1] = { {2, 4}, }; -static arc arcs_3_6[1] = { +static const arc arcs_3_6[1] = { {50, 5}, }; static state states_3[7] = { @@ -78,10 +77,10 @@ static state states_3[7] = { {1, arcs_3_5}, {1, arcs_3_6}, }; -static arc arcs_4_0[1] = { +static const arc arcs_4_0[1] = { {48, 1}, }; -static arc arcs_4_1[2] = { +static const arc arcs_4_1[2] = { {48, 1}, {0, 1}, }; @@ -89,15 +88,15 @@ static state states_4[2] = { {1, arcs_4_0}, {2, arcs_4_1}, }; -static arc arcs_5_0[1] = { +static const arc arcs_5_0[1] = { {52, 1}, }; -static arc arcs_5_1[3] = { +static const arc arcs_5_1[3] = { {54, 2}, {55, 2}, {56, 2}, }; -static arc arcs_5_2[1] = { +static const arc arcs_5_2[1] = { {0, 2}, }; static state states_5[3] = { @@ -105,13 +104,13 @@ static state states_5[3] = { {3, arcs_5_1}, {1, arcs_5_2}, }; -static arc arcs_6_0[1] = { +static const arc arcs_6_0[1] = { {38, 1}, }; -static arc arcs_6_1[1] = { +static const arc arcs_6_1[1] = { {56, 2}, }; -static arc arcs_6_2[1] = { +static const arc arcs_6_2[1] = { {0, 2}, }; static state states_6[3] = { @@ -119,33 +118,33 @@ static state states_6[3] = { {1, arcs_6_1}, {1, arcs_6_2}, }; -static arc arcs_7_0[1] = { +static const arc arcs_7_0[1] = { {19, 1}, }; -static arc arcs_7_1[1] = { +static const arc arcs_7_1[1] = { {40, 2}, }; -static arc arcs_7_2[1] = { +static const arc arcs_7_2[1] = { {57, 3}, }; -static arc arcs_7_3[2] = { +static const arc arcs_7_3[2] = { {58, 4}, {59, 5}, }; -static arc arcs_7_4[1] = { +static const arc arcs_7_4[1] = { {60, 6}, }; -static arc arcs_7_5[2] = { +static const arc arcs_7_5[2] = { {61, 7}, {62, 8}, }; -static arc arcs_7_6[1] = { +static const arc arcs_7_6[1] = { {59, 5}, }; -static arc arcs_7_7[1] = { +static const arc arcs_7_7[1] = { {62, 8}, }; -static arc arcs_7_8[1] = { +static const arc arcs_7_8[1] = { {0, 8}, }; static state states_7[9] = { @@ -159,17 +158,17 @@ static state states_7[9] = { {1, arcs_7_7}, {1, arcs_7_8}, }; -static arc arcs_8_0[1] = { +static const arc arcs_8_0[1] = { {5, 1}, }; -static arc arcs_8_1[2] = { +static const arc arcs_8_1[2] = { {50, 2}, {63, 3}, }; -static arc arcs_8_2[1] = { +static const arc arcs_8_2[1] = { {0, 2}, }; -static arc arcs_8_3[1] = { +static const arc arcs_8_3[1] = { {50, 2}, }; static state states_8[4] = { @@ -178,116 +177,221 @@ static state states_8[4] = { {1, arcs_8_2}, {1, arcs_8_3}, }; -static arc arcs_9_0[3] = { +static const arc arcs_9_0[3] = { {6, 1}, {64, 2}, {65, 3}, }; -static arc arcs_9_1[4] = { +static const arc arcs_9_1[4] = { {66, 4}, {61, 5}, {65, 6}, {0, 1}, }; -static arc arcs_9_2[1] = { +static const arc arcs_9_2[1] = { {65, 7}, }; -static arc arcs_9_3[4] = { +static const arc arcs_9_3[4] = { {66, 8}, {67, 9}, {61, 5}, {0, 3}, }; -static arc arcs_9_4[4] = { +static const arc arcs_9_4[4] = { {64, 2}, {61, 10}, {65, 11}, {0, 4}, }; -static arc arcs_9_5[1] = { +static const arc arcs_9_5[1] = { {0, 5}, }; -static arc arcs_9_6[3] = { +static const arc arcs_9_6[3] = { {66, 4}, {61, 5}, {0, 6}, }; -static arc arcs_9_7[3] = { +static const arc arcs_9_7[3] = { {66, 12}, {61, 5}, {0, 7}, }; -static arc arcs_9_8[5] = { +static const arc arcs_9_8[6] = { {6, 13}, {64, 2}, - {61, 14}, + {68, 14}, + {61, 15}, {65, 3}, {0, 8}, }; -static arc arcs_9_9[1] = { - {60, 15}, +static const arc arcs_9_9[1] = { + {60, 16}, }; -static arc arcs_9_10[3] = { +static const arc arcs_9_10[3] = { {64, 2}, {65, 11}, {0, 10}, }; -static arc arcs_9_11[4] = { +static const arc arcs_9_11[4] = { {66, 4}, - {67, 16}, + {67, 17}, {61, 5}, {0, 11}, }; -static arc arcs_9_12[2] = { +static const arc arcs_9_12[2] = { {61, 5}, {0, 12}, }; -static arc arcs_9_13[4] = { - {66, 17}, +static const arc arcs_9_13[4] = { + {66, 18}, {61, 5}, - {65, 18}, + {65, 19}, {0, 13}, }; -static arc arcs_9_14[4] = { - {6, 13}, - {64, 2}, - {65, 3}, +static const arc arcs_9_14[2] = { + {66, 20}, {0, 14}, }; -static arc arcs_9_15[3] = { - {66, 8}, - {61, 5}, +static const arc arcs_9_15[5] = { + {6, 13}, + {64, 2}, + {68, 14}, + {65, 3}, {0, 15}, }; -static arc arcs_9_16[1] = { +static const arc arcs_9_16[3] = { + {66, 8}, + {61, 5}, + {0, 16}, +}; +static const arc arcs_9_17[1] = { {60, 6}, }; -static arc arcs_9_17[4] = { +static const arc arcs_9_18[4] = { {64, 2}, - {61, 19}, - {65, 20}, - {0, 17}, -}; -static arc arcs_9_18[3] = { - {66, 17}, - {61, 5}, + {61, 21}, + {65, 22}, {0, 18}, }; -static arc arcs_9_19[3] = { - {64, 2}, - {65, 20}, +static const arc arcs_9_19[3] = { + {66, 18}, + {61, 5}, {0, 19}, }; -static arc arcs_9_20[4] = { - {66, 17}, - {67, 21}, - {61, 5}, +static const arc arcs_9_20[5] = { + {6, 23}, + {64, 2}, + {61, 24}, + {65, 25}, {0, 20}, }; -static arc arcs_9_21[1] = { - {60, 18}, +static const arc arcs_9_21[3] = { + {64, 2}, + {65, 22}, + {0, 21}, }; -static state states_9[22] = { +static const arc arcs_9_22[4] = { + {66, 18}, + {67, 26}, + {61, 5}, + {0, 22}, +}; +static const arc arcs_9_23[4] = { + {66, 27}, + {61, 5}, + {65, 28}, + {0, 23}, +}; +static const arc arcs_9_24[1] = { + {65, 25}, +}; +static const arc arcs_9_25[4] = { + {66, 29}, + {67, 30}, + {61, 5}, + {0, 25}, +}; +static const arc arcs_9_26[1] = { + {60, 19}, +}; +static const arc arcs_9_27[4] = { + {64, 2}, + {61, 31}, + {65, 32}, + {0, 27}, +}; +static const arc arcs_9_28[3] = { + {66, 27}, + {61, 5}, + {0, 28}, +}; +static const arc arcs_9_29[5] = { + {6, 33}, + {64, 2}, + {61, 34}, + {65, 25}, + {0, 29}, +}; +static const arc arcs_9_30[1] = { + {60, 35}, +}; +static const arc arcs_9_31[3] = { + {64, 2}, + {65, 32}, + {0, 31}, +}; +static const arc arcs_9_32[4] = { + {66, 27}, + {67, 36}, + {61, 5}, + {0, 32}, +}; +static const arc arcs_9_33[4] = { + {66, 37}, + {61, 5}, + {65, 38}, + {0, 33}, +}; +static const arc arcs_9_34[4] = { + {6, 33}, + {64, 2}, + {65, 25}, + {0, 34}, +}; +static const arc arcs_9_35[3] = { + {66, 29}, + {61, 5}, + {0, 35}, +}; +static const arc arcs_9_36[1] = { + {60, 28}, +}; +static const arc arcs_9_37[4] = { + {64, 2}, + {61, 39}, + {65, 40}, + {0, 37}, +}; +static const arc arcs_9_38[3] = { + {66, 37}, + {61, 5}, + {0, 38}, +}; +static const arc arcs_9_39[3] = { + {64, 2}, + {65, 40}, + {0, 39}, +}; +static const arc arcs_9_40[4] = { + {66, 37}, + {67, 41}, + {61, 5}, + {0, 40}, +}; +static const arc arcs_9_41[1] = { + {60, 38}, +}; +static state states_9[42] = { {3, arcs_9_0}, {4, arcs_9_1}, {1, arcs_9_2}, @@ -296,32 +400,52 @@ static state states_9[22] = { {1, arcs_9_5}, {3, arcs_9_6}, {3, arcs_9_7}, - {5, arcs_9_8}, + {6, arcs_9_8}, {1, arcs_9_9}, {3, arcs_9_10}, {4, arcs_9_11}, {2, arcs_9_12}, {4, arcs_9_13}, - {4, arcs_9_14}, - {3, arcs_9_15}, - {1, arcs_9_16}, - {4, arcs_9_17}, - {3, arcs_9_18}, + {2, arcs_9_14}, + {5, arcs_9_15}, + {3, arcs_9_16}, + {1, arcs_9_17}, + {4, arcs_9_18}, {3, arcs_9_19}, - {4, arcs_9_20}, - {1, arcs_9_21}, + {5, arcs_9_20}, + {3, arcs_9_21}, + {4, arcs_9_22}, + {4, arcs_9_23}, + {1, arcs_9_24}, + {4, arcs_9_25}, + {1, arcs_9_26}, + {4, arcs_9_27}, + {3, arcs_9_28}, + {5, arcs_9_29}, + {1, arcs_9_30}, + {3, arcs_9_31}, + {4, arcs_9_32}, + {4, arcs_9_33}, + {4, arcs_9_34}, + {3, arcs_9_35}, + {1, arcs_9_36}, + {4, arcs_9_37}, + {3, arcs_9_38}, + {3, arcs_9_39}, + {4, arcs_9_40}, + {1, arcs_9_41}, }; -static arc arcs_10_0[1] = { +static const arc arcs_10_0[1] = { {40, 1}, }; -static arc arcs_10_1[2] = { +static const arc arcs_10_1[2] = { {59, 2}, {0, 1}, }; -static arc arcs_10_2[1] = { +static const arc arcs_10_2[1] = { {60, 3}, }; -static arc arcs_10_3[1] = { +static const arc arcs_10_3[1] = { {0, 3}, }; static state states_10[4] = { @@ -330,84 +454,157 @@ static state states_10[4] = { {1, arcs_10_2}, {1, arcs_10_3}, }; -static arc arcs_11_0[3] = { +static const arc arcs_11_0[3] = { {6, 1}, {64, 2}, - {69, 3}, + {70, 3}, }; -static arc arcs_11_1[3] = { +static const arc arcs_11_1[3] = { {66, 4}, - {69, 5}, + {70, 5}, {0, 1}, }; -static arc arcs_11_2[1] = { - {69, 6}, +static const arc arcs_11_2[1] = { + {70, 6}, }; -static arc arcs_11_3[3] = { +static const arc arcs_11_3[3] = { {66, 7}, {67, 8}, {0, 3}, }; -static arc arcs_11_4[3] = { +static const arc arcs_11_4[3] = { {64, 2}, - {69, 9}, + {70, 9}, {0, 4}, }; -static arc arcs_11_5[2] = { +static const arc arcs_11_5[2] = { {66, 4}, {0, 5}, }; -static arc arcs_11_6[2] = { +static const arc arcs_11_6[2] = { {66, 10}, {0, 6}, }; -static arc arcs_11_7[4] = { +static const arc arcs_11_7[5] = { {6, 11}, {64, 2}, - {69, 3}, + {68, 12}, + {70, 3}, {0, 7}, }; -static arc arcs_11_8[1] = { - {60, 12}, +static const arc arcs_11_8[1] = { + {60, 13}, }; -static arc arcs_11_9[3] = { +static const arc arcs_11_9[3] = { {66, 4}, - {67, 13}, + {67, 14}, {0, 9}, }; -static arc arcs_11_10[1] = { +static const arc arcs_11_10[1] = { {0, 10}, }; -static arc arcs_11_11[3] = { - {66, 14}, - {69, 15}, +static const arc arcs_11_11[3] = { + {66, 15}, + {70, 16}, {0, 11}, }; -static arc arcs_11_12[2] = { - {66, 7}, +static const arc arcs_11_12[2] = { + {66, 17}, {0, 12}, }; -static arc arcs_11_13[1] = { +static const arc arcs_11_13[2] = { + {66, 7}, + {0, 13}, +}; +static const arc arcs_11_14[1] = { {60, 5}, }; -static arc arcs_11_14[3] = { +static const arc arcs_11_15[3] = { {64, 2}, - {69, 16}, - {0, 14}, -}; -static arc arcs_11_15[2] = { - {66, 14}, + {70, 18}, {0, 15}, }; -static arc arcs_11_16[3] = { - {66, 14}, - {67, 17}, +static const arc arcs_11_16[2] = { + {66, 15}, {0, 16}, }; -static arc arcs_11_17[1] = { - {60, 15}, +static const arc arcs_11_17[4] = { + {6, 19}, + {64, 2}, + {70, 20}, + {0, 17}, }; -static state states_11[18] = { +static const arc arcs_11_18[3] = { + {66, 15}, + {67, 21}, + {0, 18}, +}; +static const arc arcs_11_19[3] = { + {66, 22}, + {70, 23}, + {0, 19}, +}; +static const arc arcs_11_20[3] = { + {66, 24}, + {67, 25}, + {0, 20}, +}; +static const arc arcs_11_21[1] = { + {60, 16}, +}; +static const arc arcs_11_22[3] = { + {64, 2}, + {70, 26}, + {0, 22}, +}; +static const arc arcs_11_23[2] = { + {66, 22}, + {0, 23}, +}; +static const arc arcs_11_24[4] = { + {6, 27}, + {64, 2}, + {70, 20}, + {0, 24}, +}; +static const arc arcs_11_25[1] = { + {60, 28}, +}; +static const arc arcs_11_26[3] = { + {66, 22}, + {67, 29}, + {0, 26}, +}; +static const arc arcs_11_27[3] = { + {66, 30}, + {70, 31}, + {0, 27}, +}; +static const arc arcs_11_28[2] = { + {66, 24}, + {0, 28}, +}; +static const arc arcs_11_29[1] = { + {60, 23}, +}; +static const arc arcs_11_30[3] = { + {64, 2}, + {70, 32}, + {0, 30}, +}; +static const arc arcs_11_31[2] = { + {66, 30}, + {0, 31}, +}; +static const arc arcs_11_32[3] = { + {66, 30}, + {67, 33}, + {0, 32}, +}; +static const arc arcs_11_33[1] = { + {60, 31}, +}; +static state states_11[34] = { {3, arcs_11_0}, {3, arcs_11_1}, {1, arcs_11_2}, @@ -415,51 +612,67 @@ static state states_11[18] = { {3, arcs_11_4}, {2, arcs_11_5}, {2, arcs_11_6}, - {4, arcs_11_7}, + {5, arcs_11_7}, {1, arcs_11_8}, {3, arcs_11_9}, {1, arcs_11_10}, {3, arcs_11_11}, {2, arcs_11_12}, - {1, arcs_11_13}, - {3, arcs_11_14}, - {2, arcs_11_15}, - {3, arcs_11_16}, - {1, arcs_11_17}, + {2, arcs_11_13}, + {1, arcs_11_14}, + {3, arcs_11_15}, + {2, arcs_11_16}, + {4, arcs_11_17}, + {3, arcs_11_18}, + {3, arcs_11_19}, + {3, arcs_11_20}, + {1, arcs_11_21}, + {3, arcs_11_22}, + {2, arcs_11_23}, + {4, arcs_11_24}, + {1, arcs_11_25}, + {3, arcs_11_26}, + {3, arcs_11_27}, + {2, arcs_11_28}, + {1, arcs_11_29}, + {3, arcs_11_30}, + {2, arcs_11_31}, + {3, arcs_11_32}, + {1, arcs_11_33}, }; -static arc arcs_12_0[1] = { +static const arc arcs_12_0[1] = { {40, 1}, }; -static arc arcs_12_1[1] = { +static const arc arcs_12_1[1] = { {0, 1}, }; static state states_12[2] = { {1, arcs_12_0}, {1, arcs_12_1}, }; -static arc arcs_13_0[2] = { +static const arc arcs_13_0[2] = { {3, 1}, {4, 1}, }; -static arc arcs_13_1[1] = { +static const arc arcs_13_1[1] = { {0, 1}, }; static state states_13[2] = { {2, arcs_13_0}, {1, arcs_13_1}, }; -static arc arcs_14_0[1] = { - {70, 1}, +static const arc arcs_14_0[1] = { + {71, 1}, }; -static arc arcs_14_1[2] = { - {71, 2}, +static const arc arcs_14_1[2] = { + {72, 2}, {2, 3}, }; -static arc arcs_14_2[2] = { +static const arc arcs_14_2[2] = { {2, 3}, - {70, 1}, + {71, 1}, }; -static arc arcs_14_3[1] = { +static const arc arcs_14_3[1] = { {0, 3}, }; static state states_14[4] = { @@ -468,8 +681,7 @@ static state states_14[4] = { {2, arcs_14_2}, {1, arcs_14_3}, }; -static arc arcs_15_0[8] = { - {72, 1}, +static const arc arcs_15_0[8] = { {73, 1}, {74, 1}, {75, 1}, @@ -477,35 +689,36 @@ static arc arcs_15_0[8] = { {77, 1}, {78, 1}, {79, 1}, + {80, 1}, }; -static arc arcs_15_1[1] = { +static const arc arcs_15_1[1] = { {0, 1}, }; static state states_15[2] = { {8, arcs_15_0}, {1, arcs_15_1}, }; -static arc arcs_16_0[1] = { - {80, 1}, +static const arc arcs_16_0[1] = { + {81, 1}, }; -static arc arcs_16_1[4] = { +static const arc arcs_16_1[4] = { {67, 2}, - {81, 3}, - {82, 4}, + {82, 3}, + {83, 4}, {0, 1}, }; -static arc arcs_16_2[2] = { - {80, 5}, - {83, 5}, +static const arc arcs_16_2[2] = { + {81, 5}, + {84, 5}, }; -static arc arcs_16_3[1] = { +static const arc arcs_16_3[1] = { {0, 3}, }; -static arc arcs_16_4[2] = { +static const arc arcs_16_4[2] = { {47, 3}, - {83, 3}, + {84, 3}, }; -static arc arcs_16_5[3] = { +static const arc arcs_16_5[3] = { {67, 2}, {61, 3}, {0, 5}, @@ -518,21 +731,21 @@ static state states_16[6] = { {2, arcs_16_4}, {3, arcs_16_5}, }; -static arc arcs_17_0[1] = { +static const arc arcs_17_0[1] = { {59, 1}, }; -static arc arcs_17_1[1] = { +static const arc arcs_17_1[1] = { {60, 2}, }; -static arc arcs_17_2[2] = { +static const arc arcs_17_2[2] = { {67, 3}, {0, 2}, }; -static arc arcs_17_3[2] = { +static const arc arcs_17_3[2] = { {47, 4}, - {83, 4}, + {84, 4}, }; -static arc arcs_17_4[1] = { +static const arc arcs_17_4[1] = { {0, 4}, }; static state states_17[5] = { @@ -542,16 +755,16 @@ static state states_17[5] = { {2, arcs_17_3}, {1, arcs_17_4}, }; -static arc arcs_18_0[2] = { - {84, 1}, +static const arc arcs_18_0[2] = { + {85, 1}, {60, 1}, }; -static arc arcs_18_1[2] = { +static const arc arcs_18_1[2] = { {66, 2}, {0, 1}, }; -static arc arcs_18_2[3] = { - {84, 1}, +static const arc arcs_18_2[3] = { + {85, 1}, {60, 1}, {0, 2}, }; @@ -560,8 +773,7 @@ static state states_18[3] = { {2, arcs_18_1}, {3, arcs_18_2}, }; -static arc arcs_19_0[13] = { - {85, 1}, +static const arc arcs_19_0[13] = { {86, 1}, {87, 1}, {88, 1}, @@ -574,21 +786,22 @@ static arc arcs_19_0[13] = { {95, 1}, {96, 1}, {97, 1}, + {98, 1}, }; -static arc arcs_19_1[1] = { +static const arc arcs_19_1[1] = { {0, 1}, }; static state states_19[2] = { {13, arcs_19_0}, {1, arcs_19_1}, }; -static arc arcs_20_0[1] = { +static const arc arcs_20_0[1] = { {20, 1}, }; -static arc arcs_20_1[1] = { - {98, 2}, +static const arc arcs_20_1[1] = { + {99, 2}, }; -static arc arcs_20_2[1] = { +static const arc arcs_20_2[1] = { {0, 2}, }; static state states_20[3] = { @@ -596,58 +809,58 @@ static state states_20[3] = { {1, arcs_20_1}, {1, arcs_20_2}, }; -static arc arcs_21_0[1] = { +static const arc arcs_21_0[1] = { {29, 1}, }; -static arc arcs_21_1[1] = { +static const arc arcs_21_1[1] = { {0, 1}, }; static state states_21[2] = { {1, arcs_21_0}, {1, arcs_21_1}, }; -static arc arcs_22_0[5] = { - {99, 1}, +static const arc arcs_22_0[5] = { {100, 1}, {101, 1}, {102, 1}, {103, 1}, + {104, 1}, }; -static arc arcs_22_1[1] = { +static const arc arcs_22_1[1] = { {0, 1}, }; static state states_22[2] = { {5, arcs_22_0}, {1, arcs_22_1}, }; -static arc arcs_23_0[1] = { +static const arc arcs_23_0[1] = { {16, 1}, }; -static arc arcs_23_1[1] = { +static const arc arcs_23_1[1] = { {0, 1}, }; static state states_23[2] = { {1, arcs_23_0}, {1, arcs_23_1}, }; -static arc arcs_24_0[1] = { +static const arc arcs_24_0[1] = { {18, 1}, }; -static arc arcs_24_1[1] = { +static const arc arcs_24_1[1] = { {0, 1}, }; static state states_24[2] = { {1, arcs_24_0}, {1, arcs_24_1}, }; -static arc arcs_25_0[1] = { +static const arc arcs_25_0[1] = { {31, 1}, }; -static arc arcs_25_1[2] = { - {80, 2}, +static const arc arcs_25_1[2] = { + {81, 2}, {0, 1}, }; -static arc arcs_25_2[1] = { +static const arc arcs_25_2[1] = { {0, 2}, }; static state states_25[3] = { @@ -655,31 +868,31 @@ static state states_25[3] = { {2, arcs_25_1}, {1, arcs_25_2}, }; -static arc arcs_26_0[1] = { - {83, 1}, +static const arc arcs_26_0[1] = { + {84, 1}, }; -static arc arcs_26_1[1] = { +static const arc arcs_26_1[1] = { {0, 1}, }; static state states_26[2] = { {1, arcs_26_0}, {1, arcs_26_1}, }; -static arc arcs_27_0[1] = { +static const arc arcs_27_0[1] = { {30, 1}, }; -static arc arcs_27_1[2] = { +static const arc arcs_27_1[2] = { {60, 2}, {0, 1}, }; -static arc arcs_27_2[2] = { +static const arc arcs_27_2[2] = { {22, 3}, {0, 2}, }; -static arc arcs_27_3[1] = { +static const arc arcs_27_3[1] = { {60, 4}, }; -static arc arcs_27_4[1] = { +static const arc arcs_27_4[1] = { {0, 4}, }; static state states_27[5] = { @@ -689,24 +902,24 @@ static state states_27[5] = { {1, arcs_27_3}, {1, arcs_27_4}, }; -static arc arcs_28_0[2] = { - {104, 1}, +static const arc arcs_28_0[2] = { {105, 1}, + {106, 1}, }; -static arc arcs_28_1[1] = { +static const arc arcs_28_1[1] = { {0, 1}, }; static state states_28[2] = { {2, arcs_28_0}, {1, arcs_28_1}, }; -static arc arcs_29_0[1] = { +static const arc arcs_29_0[1] = { {25, 1}, }; -static arc arcs_29_1[1] = { - {106, 2}, +static const arc arcs_29_1[1] = { + {107, 2}, }; -static arc arcs_29_2[1] = { +static const arc arcs_29_2[1] = { {0, 2}, }; static state states_29[3] = { @@ -714,35 +927,35 @@ static state states_29[3] = { {1, arcs_29_1}, {1, arcs_29_2}, }; -static arc arcs_30_0[1] = { +static const arc arcs_30_0[1] = { {22, 1}, }; -static arc arcs_30_1[3] = { - {107, 2}, +static const arc arcs_30_1[3] = { + {108, 2}, {9, 2}, {49, 3}, }; -static arc arcs_30_2[4] = { - {107, 2}, +static const arc arcs_30_2[4] = { + {108, 2}, {9, 2}, {25, 4}, {49, 3}, }; -static arc arcs_30_3[1] = { +static const arc arcs_30_3[1] = { {25, 4}, }; -static arc arcs_30_4[3] = { +static const arc arcs_30_4[3] = { {5, 5}, {6, 6}, - {108, 6}, + {109, 6}, }; -static arc arcs_30_5[1] = { - {108, 7}, +static const arc arcs_30_5[1] = { + {109, 7}, }; -static arc arcs_30_6[1] = { +static const arc arcs_30_6[1] = { {0, 6}, }; -static arc arcs_30_7[1] = { +static const arc arcs_30_7[1] = { {50, 6}, }; static state states_30[8] = { @@ -755,17 +968,17 @@ static state states_30[8] = { {1, arcs_30_6}, {1, arcs_30_7}, }; -static arc arcs_31_0[1] = { +static const arc arcs_31_0[1] = { {40, 1}, }; -static arc arcs_31_1[2] = { - {110, 2}, +static const arc arcs_31_1[2] = { + {111, 2}, {0, 1}, }; -static arc arcs_31_2[1] = { +static const arc arcs_31_2[1] = { {40, 3}, }; -static arc arcs_31_3[1] = { +static const arc arcs_31_3[1] = { {0, 3}, }; static state states_31[4] = { @@ -774,17 +987,17 @@ static state states_31[4] = { {1, arcs_31_2}, {1, arcs_31_3}, }; -static arc arcs_32_0[1] = { +static const arc arcs_32_0[1] = { {49, 1}, }; -static arc arcs_32_1[2] = { - {110, 2}, +static const arc arcs_32_1[2] = { + {111, 2}, {0, 1}, }; -static arc arcs_32_2[1] = { +static const arc arcs_32_2[1] = { {40, 3}, }; -static arc arcs_32_3[1] = { +static const arc arcs_32_3[1] = { {0, 3}, }; static state states_32[4] = { @@ -793,15 +1006,15 @@ static state states_32[4] = { {1, arcs_32_2}, {1, arcs_32_3}, }; -static arc arcs_33_0[1] = { - {109, 1}, +static const arc arcs_33_0[1] = { + {110, 1}, }; -static arc arcs_33_1[2] = { +static const arc arcs_33_1[2] = { {66, 2}, {0, 1}, }; -static arc arcs_33_2[2] = { - {109, 1}, +static const arc arcs_33_2[2] = { + {110, 1}, {0, 2}, }; static state states_33[3] = { @@ -809,10 +1022,10 @@ static state states_33[3] = { {2, arcs_33_1}, {2, arcs_33_2}, }; -static arc arcs_34_0[1] = { - {111, 1}, +static const arc arcs_34_0[1] = { + {112, 1}, }; -static arc arcs_34_1[2] = { +static const arc arcs_34_1[2] = { {66, 0}, {0, 1}, }; @@ -820,24 +1033,24 @@ static state states_34[2] = { {1, arcs_34_0}, {2, arcs_34_1}, }; -static arc arcs_35_0[1] = { +static const arc arcs_35_0[1] = { {40, 1}, }; -static arc arcs_35_1[2] = { - {107, 0}, +static const arc arcs_35_1[2] = { + {108, 0}, {0, 1}, }; static state states_35[2] = { {1, arcs_35_0}, {2, arcs_35_1}, }; -static arc arcs_36_0[1] = { +static const arc arcs_36_0[1] = { {23, 1}, }; -static arc arcs_36_1[1] = { +static const arc arcs_36_1[1] = { {40, 2}, }; -static arc arcs_36_2[2] = { +static const arc arcs_36_2[2] = { {66, 1}, {0, 2}, }; @@ -846,13 +1059,13 @@ static state states_36[3] = { {1, arcs_36_1}, {2, arcs_36_2}, }; -static arc arcs_37_0[1] = { +static const arc arcs_37_0[1] = { {27, 1}, }; -static arc arcs_37_1[1] = { +static const arc arcs_37_1[1] = { {40, 2}, }; -static arc arcs_37_2[2] = { +static const arc arcs_37_2[2] = { {66, 1}, {0, 2}, }; @@ -861,20 +1074,20 @@ static state states_37[3] = { {1, arcs_37_1}, {2, arcs_37_2}, }; -static arc arcs_38_0[1] = { +static const arc arcs_38_0[1] = { {15, 1}, }; -static arc arcs_38_1[1] = { +static const arc arcs_38_1[1] = { {60, 2}, }; -static arc arcs_38_2[2] = { +static const arc arcs_38_2[2] = { {66, 3}, {0, 2}, }; -static arc arcs_38_3[1] = { +static const arc arcs_38_3[1] = { {60, 4}, }; -static arc arcs_38_4[1] = { +static const arc arcs_38_4[1] = { {0, 4}, }; static state states_38[5] = { @@ -884,33 +1097,33 @@ static state states_38[5] = { {1, arcs_38_3}, {1, arcs_38_4}, }; -static arc arcs_39_0[9] = { - {112, 1}, +static const arc arcs_39_0[9] = { + {113, 1}, {55, 1}, {53, 1}, - {113, 1}, - {56, 1}, {114, 1}, + {56, 1}, {115, 1}, {116, 1}, {117, 1}, + {118, 1}, }; -static arc arcs_39_1[1] = { +static const arc arcs_39_1[1] = { {0, 1}, }; static state states_39[2] = { {9, arcs_39_0}, {1, arcs_39_1}, }; -static arc arcs_40_0[1] = { +static const arc arcs_40_0[1] = { {38, 1}, }; -static arc arcs_40_1[3] = { - {113, 2}, +static const arc arcs_40_1[3] = { + {114, 2}, {56, 2}, - {117, 2}, + {118, 2}, }; -static arc arcs_40_2[1] = { +static const arc arcs_40_2[1] = { {0, 2}, }; static state states_40[3] = { @@ -918,30 +1131,30 @@ static state states_40[3] = { {3, arcs_40_1}, {1, arcs_40_2}, }; -static arc arcs_41_0[1] = { +static const arc arcs_41_0[1] = { {24, 1}, }; -static arc arcs_41_1[1] = { - {118, 2}, +static const arc arcs_41_1[1] = { + {119, 2}, }; -static arc arcs_41_2[1] = { +static const arc arcs_41_2[1] = { {59, 3}, }; -static arc arcs_41_3[1] = { - {119, 4}, +static const arc arcs_41_3[1] = { + {120, 4}, }; -static arc arcs_41_4[3] = { - {120, 1}, - {121, 5}, +static const arc arcs_41_4[3] = { + {121, 1}, + {122, 5}, {0, 4}, }; -static arc arcs_41_5[1] = { +static const arc arcs_41_5[1] = { {59, 6}, }; -static arc arcs_41_6[1] = { - {119, 7}, +static const arc arcs_41_6[1] = { + {120, 7}, }; -static arc arcs_41_7[1] = { +static const arc arcs_41_7[1] = { {0, 7}, }; static state states_41[8] = { @@ -954,29 +1167,29 @@ static state states_41[8] = { {1, arcs_41_6}, {1, arcs_41_7}, }; -static arc arcs_42_0[1] = { +static const arc arcs_42_0[1] = { {33, 1}, }; -static arc arcs_42_1[1] = { - {118, 2}, +static const arc arcs_42_1[1] = { + {119, 2}, }; -static arc arcs_42_2[1] = { +static const arc arcs_42_2[1] = { {59, 3}, }; -static arc arcs_42_3[1] = { - {119, 4}, +static const arc arcs_42_3[1] = { + {120, 4}, }; -static arc arcs_42_4[2] = { - {121, 5}, +static const arc arcs_42_4[2] = { + {122, 5}, {0, 4}, }; -static arc arcs_42_5[1] = { +static const arc arcs_42_5[1] = { {59, 6}, }; -static arc arcs_42_6[1] = { - {119, 7}, +static const arc arcs_42_6[1] = { + {120, 7}, }; -static arc arcs_42_7[1] = { +static const arc arcs_42_7[1] = { {0, 7}, }; static state states_42[8] = { @@ -989,39 +1202,39 @@ static state states_42[8] = { {1, arcs_42_6}, {1, arcs_42_7}, }; -static arc arcs_43_0[1] = { +static const arc arcs_43_0[1] = { {21, 1}, }; -static arc arcs_43_1[1] = { - {98, 2}, +static const arc arcs_43_1[1] = { + {99, 2}, }; -static arc arcs_43_2[1] = { - {122, 3}, +static const arc arcs_43_2[1] = { + {123, 3}, }; -static arc arcs_43_3[1] = { +static const arc arcs_43_3[1] = { {47, 4}, }; -static arc arcs_43_4[1] = { +static const arc arcs_43_4[1] = { {59, 5}, }; -static arc arcs_43_5[2] = { +static const arc arcs_43_5[2] = { {61, 6}, - {119, 7}, + {120, 7}, }; -static arc arcs_43_6[1] = { - {119, 7}, +static const arc arcs_43_6[1] = { + {120, 7}, }; -static arc arcs_43_7[2] = { - {121, 8}, +static const arc arcs_43_7[2] = { + {122, 8}, {0, 7}, }; -static arc arcs_43_8[1] = { +static const arc arcs_43_8[1] = { {59, 9}, }; -static arc arcs_43_9[1] = { - {119, 10}, +static const arc arcs_43_9[1] = { + {120, 10}, }; -static arc arcs_43_10[1] = { +static const arc arcs_43_10[1] = { {0, 10}, }; static state states_43[11] = { @@ -1037,48 +1250,48 @@ static state states_43[11] = { {1, arcs_43_9}, {1, arcs_43_10}, }; -static arc arcs_44_0[1] = { +static const arc arcs_44_0[1] = { {32, 1}, }; -static arc arcs_44_1[1] = { +static const arc arcs_44_1[1] = { {59, 2}, }; -static arc arcs_44_2[1] = { - {119, 3}, +static const arc arcs_44_2[1] = { + {120, 3}, }; -static arc arcs_44_3[2] = { - {123, 4}, - {124, 5}, +static const arc arcs_44_3[2] = { + {124, 4}, + {125, 5}, }; -static arc arcs_44_4[1] = { +static const arc arcs_44_4[1] = { {59, 6}, }; -static arc arcs_44_5[1] = { +static const arc arcs_44_5[1] = { {59, 7}, }; -static arc arcs_44_6[1] = { - {119, 8}, +static const arc arcs_44_6[1] = { + {120, 8}, }; -static arc arcs_44_7[1] = { - {119, 9}, +static const arc arcs_44_7[1] = { + {120, 9}, }; -static arc arcs_44_8[1] = { +static const arc arcs_44_8[1] = { {0, 8}, }; -static arc arcs_44_9[4] = { - {121, 10}, - {123, 4}, - {124, 5}, +static const arc arcs_44_9[4] = { + {122, 10}, + {124, 4}, + {125, 5}, {0, 9}, }; -static arc arcs_44_10[1] = { +static const arc arcs_44_10[1] = { {59, 11}, }; -static arc arcs_44_11[1] = { - {119, 12}, +static const arc arcs_44_11[1] = { + {120, 12}, }; -static arc arcs_44_12[2] = { - {123, 4}, +static const arc arcs_44_12[2] = { + {124, 4}, {0, 12}, }; static state states_44[13] = { @@ -1096,24 +1309,24 @@ static state states_44[13] = { {1, arcs_44_11}, {2, arcs_44_12}, }; -static arc arcs_45_0[1] = { +static const arc arcs_45_0[1] = { {34, 1}, }; -static arc arcs_45_1[1] = { - {125, 2}, +static const arc arcs_45_1[1] = { + {126, 2}, }; -static arc arcs_45_2[2] = { +static const arc arcs_45_2[2] = { {66, 1}, {59, 3}, }; -static arc arcs_45_3[2] = { +static const arc arcs_45_3[2] = { {61, 4}, - {119, 5}, + {120, 5}, }; -static arc arcs_45_4[1] = { - {119, 5}, +static const arc arcs_45_4[1] = { + {120, 5}, }; -static arc arcs_45_5[1] = { +static const arc arcs_45_5[1] = { {0, 5}, }; static state states_45[6] = { @@ -1124,17 +1337,17 @@ static state states_45[6] = { {1, arcs_45_4}, {1, arcs_45_5}, }; -static arc arcs_46_0[1] = { +static const arc arcs_46_0[1] = { {60, 1}, }; -static arc arcs_46_1[2] = { - {110, 2}, +static const arc arcs_46_1[2] = { + {111, 2}, {0, 1}, }; -static arc arcs_46_2[1] = { - {126, 3}, +static const arc arcs_46_2[1] = { + {127, 3}, }; -static arc arcs_46_3[1] = { +static const arc arcs_46_3[1] = { {0, 3}, }; static state states_46[4] = { @@ -1143,21 +1356,21 @@ static state states_46[4] = { {1, arcs_46_2}, {1, arcs_46_3}, }; -static arc arcs_47_0[1] = { - {127, 1}, +static const arc arcs_47_0[1] = { + {128, 1}, }; -static arc arcs_47_1[2] = { +static const arc arcs_47_1[2] = { {60, 2}, {0, 1}, }; -static arc arcs_47_2[2] = { - {110, 3}, +static const arc arcs_47_2[2] = { + {111, 3}, {0, 2}, }; -static arc arcs_47_3[1] = { +static const arc arcs_47_3[1] = { {40, 4}, }; -static arc arcs_47_4[1] = { +static const arc arcs_47_4[1] = { {0, 4}, }; static state states_47[5] = { @@ -1167,21 +1380,21 @@ static state states_47[5] = { {1, arcs_47_3}, {1, arcs_47_4}, }; -static arc arcs_48_0[2] = { +static const arc arcs_48_0[2] = { {2, 1}, {4, 2}, }; -static arc arcs_48_1[1] = { - {128, 3}, +static const arc arcs_48_1[1] = { + {129, 3}, }; -static arc arcs_48_2[1] = { +static const arc arcs_48_2[1] = { {0, 2}, }; -static arc arcs_48_3[1] = { +static const arc arcs_48_3[1] = { {45, 4}, }; -static arc arcs_48_4[2] = { - {129, 2}, +static const arc arcs_48_4[2] = { + {130, 2}, {45, 4}, }; static state states_48[5] = { @@ -1191,17 +1404,17 @@ static state states_48[5] = { {1, arcs_48_3}, {2, arcs_48_4}, }; -static arc arcs_49_0[1] = { +static const arc arcs_49_0[1] = { {60, 1}, }; -static arc arcs_49_1[2] = { - {130, 2}, +static const arc arcs_49_1[2] = { + {131, 2}, {0, 1}, }; -static arc arcs_49_2[1] = { +static const arc arcs_49_2[1] = { {60, 3}, }; -static arc arcs_49_3[1] = { +static const arc arcs_49_3[1] = { {0, 3}, }; static state states_49[4] = { @@ -1210,24 +1423,24 @@ static state states_49[4] = { {1, arcs_49_2}, {1, arcs_49_3}, }; -static arc arcs_50_0[2] = { - {131, 1}, - {132, 2}, +static const arc arcs_50_0[2] = { + {132, 1}, + {133, 2}, }; -static arc arcs_50_1[1] = { +static const arc arcs_50_1[1] = { {0, 1}, }; -static arc arcs_50_2[2] = { +static const arc arcs_50_2[2] = { {24, 3}, {0, 2}, }; -static arc arcs_50_3[1] = { - {132, 4}, +static const arc arcs_50_3[1] = { + {133, 4}, }; -static arc arcs_50_4[1] = { - {121, 5}, +static const arc arcs_50_4[1] = { + {122, 5}, }; -static arc arcs_50_5[1] = { +static const arc arcs_50_5[1] = { {60, 1}, }; static state states_50[6] = { @@ -1238,31 +1451,31 @@ static state states_50[6] = { {1, arcs_50_4}, {1, arcs_50_5}, }; -static arc arcs_51_0[2] = { - {134, 1}, - {132, 1}, +static const arc arcs_51_0[2] = { + {135, 1}, + {133, 1}, }; -static arc arcs_51_1[1] = { +static const arc arcs_51_1[1] = { {0, 1}, }; static state states_51[2] = { {2, arcs_51_0}, {1, arcs_51_1}, }; -static arc arcs_52_0[1] = { +static const arc arcs_52_0[1] = { {26, 1}, }; -static arc arcs_52_1[2] = { +static const arc arcs_52_1[2] = { {59, 2}, - {68, 3}, + {69, 3}, }; -static arc arcs_52_2[1] = { +static const arc arcs_52_2[1] = { {60, 4}, }; -static arc arcs_52_3[1] = { +static const arc arcs_52_3[1] = { {59, 2}, }; -static arc arcs_52_4[1] = { +static const arc arcs_52_4[1] = { {0, 4}, }; static state states_52[5] = { @@ -1272,20 +1485,20 @@ static state states_52[5] = { {1, arcs_52_3}, {1, arcs_52_4}, }; -static arc arcs_53_0[1] = { +static const arc arcs_53_0[1] = { {26, 1}, }; -static arc arcs_53_1[2] = { +static const arc arcs_53_1[2] = { {59, 2}, - {68, 3}, + {69, 3}, }; -static arc arcs_53_2[1] = { - {133, 4}, +static const arc arcs_53_2[1] = { + {134, 4}, }; -static arc arcs_53_3[1] = { +static const arc arcs_53_3[1] = { {59, 2}, }; -static arc arcs_53_4[1] = { +static const arc arcs_53_4[1] = { {0, 4}, }; static state states_53[5] = { @@ -1295,36 +1508,36 @@ static state states_53[5] = { {1, arcs_53_3}, {1, arcs_53_4}, }; -static arc arcs_54_0[1] = { - {135, 1}, +static const arc arcs_54_0[1] = { + {136, 1}, }; -static arc arcs_54_1[2] = { - {136, 0}, +static const arc arcs_54_1[2] = { + {137, 0}, {0, 1}, }; static state states_54[2] = { {1, arcs_54_0}, {2, arcs_54_1}, }; -static arc arcs_55_0[1] = { - {137, 1}, +static const arc arcs_55_0[1] = { + {138, 1}, }; -static arc arcs_55_1[2] = { - {138, 0}, +static const arc arcs_55_1[2] = { + {139, 0}, {0, 1}, }; static state states_55[2] = { {1, arcs_55_0}, {2, arcs_55_1}, }; -static arc arcs_56_0[2] = { +static const arc arcs_56_0[2] = { {28, 1}, - {139, 2}, + {140, 2}, }; -static arc arcs_56_1[1] = { - {137, 2}, +static const arc arcs_56_1[1] = { + {138, 2}, }; -static arc arcs_56_2[1] = { +static const arc arcs_56_2[1] = { {0, 2}, }; static state states_56[3] = { @@ -1332,38 +1545,38 @@ static state states_56[3] = { {1, arcs_56_1}, {1, arcs_56_2}, }; -static arc arcs_57_0[1] = { - {126, 1}, +static const arc arcs_57_0[1] = { + {127, 1}, }; -static arc arcs_57_1[2] = { - {140, 0}, +static const arc arcs_57_1[2] = { + {141, 0}, {0, 1}, }; static state states_57[2] = { {1, arcs_57_0}, {2, arcs_57_1}, }; -static arc arcs_58_0[10] = { - {141, 1}, +static const arc arcs_58_0[10] = { {142, 1}, {143, 1}, - {141, 1}, {144, 1}, + {142, 1}, {145, 1}, {146, 1}, - {122, 1}, - {147, 2}, + {147, 1}, + {123, 1}, + {148, 2}, {28, 3}, }; -static arc arcs_58_1[1] = { +static const arc arcs_58_1[1] = { {0, 1}, }; -static arc arcs_58_2[2] = { +static const arc arcs_58_2[2] = { {28, 1}, {0, 2}, }; -static arc arcs_58_3[1] = { - {122, 1}, +static const arc arcs_58_3[1] = { + {123, 1}, }; static state states_58[4] = { {10, arcs_58_0}, @@ -1371,13 +1584,13 @@ static state states_58[4] = { {2, arcs_58_2}, {1, arcs_58_3}, }; -static arc arcs_59_0[1] = { +static const arc arcs_59_0[1] = { {6, 1}, }; -static arc arcs_59_1[1] = { - {126, 2}, +static const arc arcs_59_1[1] = { + {127, 2}, }; -static arc arcs_59_2[1] = { +static const arc arcs_59_2[1] = { {0, 2}, }; static state states_59[3] = { @@ -1385,55 +1598,55 @@ static state states_59[3] = { {1, arcs_59_1}, {1, arcs_59_2}, }; -static arc arcs_60_0[1] = { - {148, 1}, +static const arc arcs_60_0[1] = { + {149, 1}, }; -static arc arcs_60_1[2] = { - {149, 0}, +static const arc arcs_60_1[2] = { + {150, 0}, {0, 1}, }; static state states_60[2] = { {1, arcs_60_0}, {2, arcs_60_1}, }; -static arc arcs_61_0[1] = { - {150, 1}, +static const arc arcs_61_0[1] = { + {151, 1}, }; -static arc arcs_61_1[2] = { - {151, 0}, +static const arc arcs_61_1[2] = { + {152, 0}, {0, 1}, }; static state states_61[2] = { {1, arcs_61_0}, {2, arcs_61_1}, }; -static arc arcs_62_0[1] = { - {152, 1}, +static const arc arcs_62_0[1] = { + {153, 1}, }; -static arc arcs_62_1[2] = { - {153, 0}, +static const arc arcs_62_1[2] = { + {154, 0}, {0, 1}, }; static state states_62[2] = { {1, arcs_62_0}, {2, arcs_62_1}, }; -static arc arcs_63_0[1] = { - {154, 1}, +static const arc arcs_63_0[1] = { + {155, 1}, }; -static arc arcs_63_1[3] = { - {155, 0}, +static const arc arcs_63_1[3] = { {156, 0}, + {157, 0}, {0, 1}, }; static state states_63[2] = { {1, arcs_63_0}, {3, arcs_63_1}, }; -static arc arcs_64_0[1] = { - {157, 1}, +static const arc arcs_64_0[1] = { + {158, 1}, }; -static arc arcs_64_1[3] = { +static const arc arcs_64_1[3] = { {7, 0}, {8, 0}, {0, 1}, @@ -1442,13 +1655,13 @@ static state states_64[2] = { {1, arcs_64_0}, {3, arcs_64_1}, }; -static arc arcs_65_0[1] = { - {158, 1}, +static const arc arcs_65_0[1] = { + {159, 1}, }; -static arc arcs_65_1[6] = { - {159, 0}, - {6, 0}, +static const arc arcs_65_1[6] = { {160, 0}, + {6, 0}, + {68, 0}, {161, 0}, {10, 0}, {0, 1}, @@ -1457,16 +1670,16 @@ static state states_65[2] = { {1, arcs_65_0}, {6, arcs_65_1}, }; -static arc arcs_66_0[4] = { +static const arc arcs_66_0[4] = { {7, 1}, {8, 1}, {37, 1}, {162, 2}, }; -static arc arcs_66_1[1] = { - {158, 2}, +static const arc arcs_66_1[1] = { + {159, 2}, }; -static arc arcs_66_2[1] = { +static const arc arcs_66_2[1] = { {0, 2}, }; static state states_66[3] = { @@ -1474,17 +1687,17 @@ static state states_66[3] = { {1, arcs_66_1}, {1, arcs_66_2}, }; -static arc arcs_67_0[1] = { +static const arc arcs_67_0[1] = { {163, 1}, }; -static arc arcs_67_1[2] = { +static const arc arcs_67_1[2] = { {64, 2}, {0, 1}, }; -static arc arcs_67_2[1] = { - {158, 3}, +static const arc arcs_67_2[1] = { + {159, 3}, }; -static arc arcs_67_3[1] = { +static const arc arcs_67_3[1] = { {0, 3}, }; static state states_67[4] = { @@ -1493,14 +1706,14 @@ static state states_67[4] = { {1, arcs_67_2}, {1, arcs_67_3}, }; -static arc arcs_68_0[2] = { +static const arc arcs_68_0[2] = { {39, 1}, {164, 2}, }; -static arc arcs_68_1[1] = { +static const arc arcs_68_1[1] = { {164, 2}, }; -static arc arcs_68_2[2] = { +static const arc arcs_68_2[2] = { {165, 2}, {0, 2}, }; @@ -1509,7 +1722,7 @@ static state states_68[3] = { {1, arcs_68_1}, {2, arcs_68_2}, }; -static arc arcs_69_0[10] = { +static const arc arcs_69_0[10] = { {5, 1}, {9, 2}, {11, 2}, @@ -1521,33 +1734,33 @@ static arc arcs_69_0[10] = { {41, 2}, {42, 5}, }; -static arc arcs_69_1[3] = { +static const arc arcs_69_1[3] = { {50, 2}, {166, 6}, - {83, 6}, + {84, 6}, }; -static arc arcs_69_2[1] = { +static const arc arcs_69_2[1] = { {0, 2}, }; -static arc arcs_69_3[2] = { +static const arc arcs_69_3[2] = { {167, 2}, {166, 7}, }; -static arc arcs_69_4[2] = { +static const arc arcs_69_4[2] = { {168, 2}, {169, 8}, }; -static arc arcs_69_5[2] = { +static const arc arcs_69_5[2] = { {42, 5}, {0, 5}, }; -static arc arcs_69_6[1] = { +static const arc arcs_69_6[1] = { {50, 2}, }; -static arc arcs_69_7[1] = { +static const arc arcs_69_7[1] = { {167, 2}, }; -static arc arcs_69_8[1] = { +static const arc arcs_69_8[1] = { {168, 2}, }; static state states_69[9] = { @@ -1561,24 +1774,24 @@ static state states_69[9] = { {1, arcs_69_7}, {1, arcs_69_8}, }; -static arc arcs_70_0[2] = { - {118, 1}, - {84, 1}, +static const arc arcs_70_0[2] = { + {119, 1}, + {85, 1}, }; -static arc arcs_70_1[3] = { +static const arc arcs_70_1[3] = { {66, 2}, {170, 3}, {0, 1}, }; -static arc arcs_70_2[3] = { - {118, 4}, - {84, 4}, +static const arc arcs_70_2[3] = { + {119, 4}, + {85, 4}, {0, 2}, }; -static arc arcs_70_3[1] = { +static const arc arcs_70_3[1] = { {0, 3}, }; -static arc arcs_70_4[2] = { +static const arc arcs_70_4[2] = { {66, 2}, {0, 4}, }; @@ -1589,28 +1802,28 @@ static state states_70[5] = { {1, arcs_70_3}, {2, arcs_70_4}, }; -static arc arcs_71_0[3] = { +static const arc arcs_71_0[3] = { {5, 1}, - {107, 2}, + {108, 2}, {14, 3}, }; -static arc arcs_71_1[2] = { +static const arc arcs_71_1[2] = { {50, 4}, {51, 5}, }; -static arc arcs_71_2[1] = { +static const arc arcs_71_2[1] = { {40, 4}, }; -static arc arcs_71_3[1] = { +static const arc arcs_71_3[1] = { {171, 6}, }; -static arc arcs_71_4[1] = { +static const arc arcs_71_4[1] = { {0, 4}, }; -static arc arcs_71_5[1] = { +static const arc arcs_71_5[1] = { {50, 4}, }; -static arc arcs_71_6[1] = { +static const arc arcs_71_6[1] = { {167, 4}, }; static state states_71[7] = { @@ -1622,14 +1835,14 @@ static state states_71[7] = { {1, arcs_71_5}, {1, arcs_71_6}, }; -static arc arcs_72_0[1] = { +static const arc arcs_72_0[1] = { {172, 1}, }; -static arc arcs_72_1[2] = { +static const arc arcs_72_1[2] = { {66, 2}, {0, 1}, }; -static arc arcs_72_2[2] = { +static const arc arcs_72_2[2] = { {172, 1}, {0, 2}, }; @@ -1638,23 +1851,23 @@ static state states_72[3] = { {2, arcs_72_1}, {2, arcs_72_2}, }; -static arc arcs_73_0[2] = { +static const arc arcs_73_0[2] = { {59, 1}, {60, 2}, }; -static arc arcs_73_1[3] = { +static const arc arcs_73_1[3] = { {173, 3}, {60, 4}, {0, 1}, }; -static arc arcs_73_2[2] = { +static const arc arcs_73_2[2] = { {59, 1}, {0, 2}, }; -static arc arcs_73_3[1] = { +static const arc arcs_73_3[1] = { {0, 3}, }; -static arc arcs_73_4[2] = { +static const arc arcs_73_4[2] = { {173, 3}, {0, 4}, }; @@ -1665,14 +1878,14 @@ static state states_73[5] = { {1, arcs_73_3}, {2, arcs_73_4}, }; -static arc arcs_74_0[1] = { +static const arc arcs_74_0[1] = { {59, 1}, }; -static arc arcs_74_1[2] = { +static const arc arcs_74_1[2] = { {60, 2}, {0, 1}, }; -static arc arcs_74_2[1] = { +static const arc arcs_74_2[1] = { {0, 2}, }; static state states_74[3] = { @@ -1680,17 +1893,17 @@ static state states_74[3] = { {2, arcs_74_1}, {1, arcs_74_2}, }; -static arc arcs_75_0[2] = { - {126, 1}, - {84, 1}, +static const arc arcs_75_0[2] = { + {127, 1}, + {85, 1}, }; -static arc arcs_75_1[2] = { +static const arc arcs_75_1[2] = { {66, 2}, {0, 1}, }; -static arc arcs_75_2[3] = { - {126, 1}, - {84, 1}, +static const arc arcs_75_2[3] = { + {127, 1}, + {85, 1}, {0, 2}, }; static state states_75[3] = { @@ -1698,14 +1911,14 @@ static state states_75[3] = { {2, arcs_75_1}, {3, arcs_75_2}, }; -static arc arcs_76_0[1] = { +static const arc arcs_76_0[1] = { {60, 1}, }; -static arc arcs_76_1[2] = { +static const arc arcs_76_1[2] = { {66, 2}, {0, 1}, }; -static arc arcs_76_2[2] = { +static const arc arcs_76_2[2] = { {60, 1}, {0, 2}, }; @@ -1714,61 +1927,61 @@ static state states_76[3] = { {2, arcs_76_1}, {2, arcs_76_2}, }; -static arc arcs_77_0[3] = { +static const arc arcs_77_0[3] = { {64, 1}, - {84, 2}, + {85, 2}, {60, 3}, }; -static arc arcs_77_1[1] = { - {126, 4}, +static const arc arcs_77_1[1] = { + {127, 4}, }; -static arc arcs_77_2[3] = { +static const arc arcs_77_2[3] = { {66, 5}, {170, 6}, {0, 2}, }; -static arc arcs_77_3[4] = { +static const arc arcs_77_3[4] = { {66, 5}, {59, 7}, {170, 6}, {0, 3}, }; -static arc arcs_77_4[3] = { +static const arc arcs_77_4[3] = { {66, 8}, {170, 6}, {0, 4}, }; -static arc arcs_77_5[3] = { - {84, 9}, +static const arc arcs_77_5[3] = { + {85, 9}, {60, 9}, {0, 5}, }; -static arc arcs_77_6[1] = { +static const arc arcs_77_6[1] = { {0, 6}, }; -static arc arcs_77_7[1] = { +static const arc arcs_77_7[1] = { {60, 4}, }; -static arc arcs_77_8[3] = { +static const arc arcs_77_8[3] = { {64, 10}, {60, 11}, {0, 8}, }; -static arc arcs_77_9[2] = { +static const arc arcs_77_9[2] = { {66, 5}, {0, 9}, }; -static arc arcs_77_10[1] = { - {126, 12}, +static const arc arcs_77_10[1] = { + {127, 12}, }; -static arc arcs_77_11[1] = { +static const arc arcs_77_11[1] = { {59, 13}, }; -static arc arcs_77_12[2] = { +static const arc arcs_77_12[2] = { {66, 8}, {0, 12}, }; -static arc arcs_77_13[1] = { +static const arc arcs_77_13[1] = { {60, 12}, }; static state states_77[14] = { @@ -1787,30 +2000,30 @@ static state states_77[14] = { {2, arcs_77_12}, {1, arcs_77_13}, }; -static arc arcs_78_0[1] = { +static const arc arcs_78_0[1] = { {17, 1}, }; -static arc arcs_78_1[1] = { +static const arc arcs_78_1[1] = { {40, 2}, }; -static arc arcs_78_2[2] = { +static const arc arcs_78_2[2] = { {5, 3}, {59, 4}, }; -static arc arcs_78_3[2] = { +static const arc arcs_78_3[2] = { {50, 5}, {51, 6}, }; -static arc arcs_78_4[1] = { - {119, 7}, +static const arc arcs_78_4[1] = { + {120, 7}, }; -static arc arcs_78_5[1] = { +static const arc arcs_78_5[1] = { {59, 4}, }; -static arc arcs_78_6[1] = { +static const arc arcs_78_6[1] = { {50, 5}, }; -static arc arcs_78_7[1] = { +static const arc arcs_78_7[1] = { {0, 7}, }; static state states_78[8] = { @@ -1823,14 +2036,14 @@ static state states_78[8] = { {1, arcs_78_6}, {1, arcs_78_7}, }; -static arc arcs_79_0[1] = { +static const arc arcs_79_0[1] = { {174, 1}, }; -static arc arcs_79_1[2] = { +static const arc arcs_79_1[2] = { {66, 2}, {0, 1}, }; -static arc arcs_79_2[2] = { +static const arc arcs_79_2[2] = { {174, 1}, {0, 2}, }; @@ -1839,21 +2052,21 @@ static state states_79[3] = { {2, arcs_79_1}, {2, arcs_79_2}, }; -static arc arcs_80_0[3] = { +static const arc arcs_80_0[3] = { {6, 1}, {64, 1}, {60, 2}, }; -static arc arcs_80_1[1] = { +static const arc arcs_80_1[1] = { {60, 3}, }; -static arc arcs_80_2[4] = { - {130, 1}, +static const arc arcs_80_2[4] = { + {131, 1}, {67, 1}, {170, 3}, {0, 2}, }; -static arc arcs_80_3[1] = { +static const arc arcs_80_3[1] = { {0, 3}, }; static state states_80[4] = { @@ -1862,34 +2075,34 @@ static state states_80[4] = { {4, arcs_80_2}, {1, arcs_80_3}, }; -static arc arcs_81_0[2] = { +static const arc arcs_81_0[2] = { {170, 1}, {176, 1}, }; -static arc arcs_81_1[1] = { +static const arc arcs_81_1[1] = { {0, 1}, }; static state states_81[2] = { {2, arcs_81_0}, {1, arcs_81_1}, }; -static arc arcs_82_0[1] = { +static const arc arcs_82_0[1] = { {21, 1}, }; -static arc arcs_82_1[1] = { - {98, 2}, +static const arc arcs_82_1[1] = { + {99, 2}, }; -static arc arcs_82_2[1] = { - {122, 3}, +static const arc arcs_82_2[1] = { + {123, 3}, }; -static arc arcs_82_3[1] = { - {132, 4}, +static const arc arcs_82_3[1] = { + {133, 4}, }; -static arc arcs_82_4[2] = { +static const arc arcs_82_4[2] = { {175, 5}, {0, 4}, }; -static arc arcs_82_5[1] = { +static const arc arcs_82_5[1] = { {0, 5}, }; static state states_82[6] = { @@ -1900,14 +2113,14 @@ static state states_82[6] = { {2, arcs_82_4}, {1, arcs_82_5}, }; -static arc arcs_83_0[2] = { +static const arc arcs_83_0[2] = { {38, 1}, {177, 2}, }; -static arc arcs_83_1[1] = { +static const arc arcs_83_1[1] = { {177, 2}, }; -static arc arcs_83_2[1] = { +static const arc arcs_83_2[1] = { {0, 2}, }; static state states_83[3] = { @@ -1915,17 +2128,17 @@ static state states_83[3] = { {1, arcs_83_1}, {1, arcs_83_2}, }; -static arc arcs_84_0[1] = { +static const arc arcs_84_0[1] = { {24, 1}, }; -static arc arcs_84_1[1] = { - {133, 2}, +static const arc arcs_84_1[1] = { + {134, 2}, }; -static arc arcs_84_2[2] = { +static const arc arcs_84_2[2] = { {175, 3}, {0, 2}, }; -static arc arcs_84_3[1] = { +static const arc arcs_84_3[1] = { {0, 3}, }; static state states_84[4] = { @@ -1934,24 +2147,24 @@ static state states_84[4] = { {2, arcs_84_2}, {1, arcs_84_3}, }; -static arc arcs_85_0[1] = { +static const arc arcs_85_0[1] = { {40, 1}, }; -static arc arcs_85_1[1] = { +static const arc arcs_85_1[1] = { {0, 1}, }; static state states_85[2] = { {1, arcs_85_0}, {1, arcs_85_1}, }; -static arc arcs_86_0[1] = { +static const arc arcs_86_0[1] = { {35, 1}, }; -static arc arcs_86_1[2] = { +static const arc arcs_86_1[2] = { {179, 2}, {0, 1}, }; -static arc arcs_86_2[1] = { +static const arc arcs_86_2[1] = { {0, 2}, }; static state states_86[3] = { @@ -1959,14 +2172,14 @@ static state states_86[3] = { {2, arcs_86_1}, {1, arcs_86_2}, }; -static arc arcs_87_0[2] = { +static const arc arcs_87_0[2] = { {22, 1}, - {80, 2}, + {81, 2}, }; -static arc arcs_87_1[1] = { +static const arc arcs_87_1[1] = { {60, 2}, }; -static arc arcs_87_2[1] = { +static const arc arcs_87_2[1] = { {0, 2}, }; static state states_87[3] = { @@ -1974,29 +2187,29 @@ static state states_87[3] = { {1, arcs_87_1}, {1, arcs_87_2}, }; -static arc arcs_88_0[2] = { +static const arc arcs_88_0[2] = { {2, 1}, {4, 2}, }; -static arc arcs_88_1[2] = { - {128, 3}, +static const arc arcs_88_1[2] = { + {129, 3}, {61, 4}, }; -static arc arcs_88_2[1] = { +static const arc arcs_88_2[1] = { {0, 2}, }; -static arc arcs_88_3[1] = { +static const arc arcs_88_3[1] = { {45, 5}, }; -static arc arcs_88_4[1] = { +static const arc arcs_88_4[1] = { {2, 6}, }; -static arc arcs_88_5[2] = { - {129, 2}, +static const arc arcs_88_5[2] = { + {130, 2}, {45, 5}, }; -static arc arcs_88_6[1] = { - {128, 3}, +static const arc arcs_88_6[1] = { + {129, 3}, }; static state states_88[7] = { {2, arcs_88_0}, @@ -2007,14 +2220,14 @@ static state states_88[7] = { {2, arcs_88_5}, {1, arcs_88_6}, }; -static arc arcs_89_0[1] = { +static const arc arcs_89_0[1] = { {181, 1}, }; -static arc arcs_89_1[2] = { +static const arc arcs_89_1[2] = { {44, 2}, {2, 1}, }; -static arc arcs_89_2[1] = { +static const arc arcs_89_2[1] = { {0, 2}, }; static state states_89[3] = { @@ -2022,23 +2235,23 @@ static state states_89[3] = { {2, arcs_89_1}, {1, arcs_89_2}, }; -static arc arcs_90_0[1] = { +static const arc arcs_90_0[1] = { {5, 1}, }; -static arc arcs_90_1[2] = { +static const arc arcs_90_1[2] = { {50, 2}, {182, 3}, }; -static arc arcs_90_2[1] = { +static const arc arcs_90_2[1] = { {58, 4}, }; -static arc arcs_90_3[1] = { +static const arc arcs_90_3[1] = { {50, 2}, }; -static arc arcs_90_4[1] = { +static const arc arcs_90_4[1] = { {60, 5}, }; -static arc arcs_90_5[1] = { +static const arc arcs_90_5[1] = { {0, 5}, }; static state states_90[6] = { @@ -2049,50 +2262,50 @@ static state states_90[6] = { {1, arcs_90_4}, {1, arcs_90_5}, }; -static arc arcs_91_0[3] = { +static const arc arcs_91_0[3] = { {6, 1}, {64, 2}, {60, 3}, }; -static arc arcs_91_1[3] = { +static const arc arcs_91_1[3] = { {66, 4}, {60, 5}, {0, 1}, }; -static arc arcs_91_2[1] = { +static const arc arcs_91_2[1] = { {60, 6}, }; -static arc arcs_91_3[2] = { +static const arc arcs_91_3[2] = { {66, 7}, {0, 3}, }; -static arc arcs_91_4[2] = { +static const arc arcs_91_4[2] = { {64, 2}, {60, 5}, }; -static arc arcs_91_5[2] = { +static const arc arcs_91_5[2] = { {66, 4}, {0, 5}, }; -static arc arcs_91_6[1] = { +static const arc arcs_91_6[1] = { {0, 6}, }; -static arc arcs_91_7[4] = { +static const arc arcs_91_7[4] = { {6, 8}, {64, 2}, {60, 3}, {0, 7}, }; -static arc arcs_91_8[3] = { +static const arc arcs_91_8[3] = { {66, 9}, {60, 10}, {0, 8}, }; -static arc arcs_91_9[2] = { +static const arc arcs_91_9[2] = { {64, 2}, {60, 10}, }; -static arc arcs_91_10[2] = { +static const arc arcs_91_10[2] = { {66, 9}, {0, 10}, }; @@ -2109,7 +2322,7 @@ static state states_91[11] = { {2, arcs_91_9}, {2, arcs_91_10}, }; -static dfa dfas[92] = { +static const dfa dfas[92] = { {256, "single_input", 3, states_0, "\344\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {257, "file_input", 2, states_1, @@ -2128,11 +2341,11 @@ static dfa dfas[92] = { "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {264, "parameters", 4, states_8, "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {265, "typedargslist", 22, states_9, + {265, "typedargslist", 42, states_9, "\100\000\000\000\000\001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {266, "tfpdef", 4, states_10, "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {267, "varargslist", 18, states_11, + {267, "varargslist", 34, states_11, "\100\000\000\000\000\001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {268, "vfpdef", 2, states_12, "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, @@ -2149,7 +2362,7 @@ static dfa dfas[92] = { {274, "testlist_star_expr", 3, states_18, "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {275, "augassign", 2, states_19, - "\000\000\000\000\000\000\000\000\000\000\340\377\003\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\300\377\007\000\000\000\000\000\000\000\000\000\000"}, {276, "del_stmt", 3, states_20, "\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {277, "pass_stmt", 2, states_21, @@ -2205,7 +2418,7 @@ static dfa dfas[92] = { {302, "with_item", 4, states_46, "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {303, "except_clause", 5, states_47, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000"}, {304, "suite", 5, states_48, "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {305, "namedexpr_test", 4, states_49, @@ -2227,7 +2440,7 @@ static dfa dfas[92] = { {313, "comparison", 2, states_57, "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {314, "comp_op", 4, states_58, - "\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\004\000\340\017\000\000\000\000"}, + "\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\010\000\300\037\000\000\000\000"}, {315, "star_expr", 3, states_59, "\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {316, "expr", 2, states_60, @@ -2253,7 +2466,7 @@ static dfa dfas[92] = { {326, "testlist_comp", 5, states_70, "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {327, "trailer", 7, states_71, - "\040\100\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, + "\040\100\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, {328, "subscriptlist", 3, states_72, "\240\173\000\024\260\007\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {329, "subscript", 5, states_73, @@ -2295,7 +2508,7 @@ static dfa dfas[92] = { {347, "typelist", 11, states_91, "\340\173\000\024\260\007\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, }; -static label labels[183] = { +static const label labels[183] = { {0, "EMPTY"}, {256, 0}, {4, 0}, @@ -2364,6 +2577,7 @@ static label labels[183] = { {266, 0}, {12, 0}, {22, 0}, + {17, 0}, {267, 0}, {268, 0}, {271, 0}, @@ -2456,7 +2670,6 @@ static label labels[183] = { {321, 0}, {322, 0}, {24, 0}, - {17, 0}, {47, 0}, {323, 0}, {324, 0}, diff --git a/Python/import.c b/Python/import.c index bf3a99414fb..b03bc98773a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -535,7 +535,7 @@ PyImport_Cleanup(void) _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings machinery. */ - _PyGC_DumpShutdownStats(); + _PyGC_DumpShutdownStats(&_PyRuntime); /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end @@ -966,11 +966,10 @@ exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object Py_DECREF(v); m = PyImport_GetModule(name); - if (m == NULL) { + if (m == NULL && !PyErr_Occurred()) { PyErr_Format(PyExc_ImportError, "Loaded module %R not found in sys.modules", name); - return NULL; } return m; @@ -1735,6 +1734,10 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } mod = PyImport_GetModule(abs_name); + if (mod == NULL && PyErr_Occurred()) { + goto error; + } + if (mod != NULL && mod != Py_None) { _Py_IDENTIFIER(__spec__); _Py_IDENTIFIER(_lock_unlock_module); @@ -1810,9 +1813,11 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, final_mod = PyImport_GetModule(to_return); Py_DECREF(to_return); if (final_mod == NULL) { - PyErr_Format(PyExc_KeyError, - "%R not in sys.modules as expected", - to_return); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_KeyError, + "%R not in sys.modules as expected", + to_return); + } goto error; } } @@ -1875,6 +1880,10 @@ PyImport_ReloadModule(PyObject *m) PyObject *reloaded_module = NULL; PyObject *imp = _PyImport_GetModuleId(&PyId_imp); if (imp == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + imp = PyImport_ImportModule("imp"); if (imp == NULL) { return NULL; @@ -2296,7 +2305,7 @@ PyInit__imp(void) if (d == NULL) goto failure; _PyCoreConfig *config = &_PyInterpreterState_Get()->core_config; - PyObject *pyc_mode = PyUnicode_FromString(config->_check_hash_pycs_mode); + PyObject *pyc_mode = PyUnicode_FromWideChar(config->check_hash_pycs_mode, -1); if (pyc_mode == NULL) { goto failure; } diff --git a/Python/importlib.h b/Python/importlib.h index b5774f83de6..694984af806 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -1,83 +1,84 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_bootstrap[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,194,1,0,0,100,0,90,0,100,1, - 97,1,100,2,100,3,132,0,90,2,100,4,100,5,132,0, - 90,3,105,0,90,4,105,0,90,5,71,0,100,6,100,7, - 132,0,100,7,101,6,131,3,90,7,71,0,100,8,100,9, - 132,0,100,9,131,2,90,8,71,0,100,10,100,11,132,0, - 100,11,131,2,90,9,71,0,100,12,100,13,132,0,100,13, - 131,2,90,10,100,14,100,15,132,0,90,11,100,16,100,17, - 132,0,90,12,100,18,100,19,132,0,90,13,100,20,100,21, - 156,1,100,22,100,23,132,2,90,14,100,24,100,25,132,0, - 90,15,100,26,100,27,132,0,90,16,100,28,100,29,132,0, - 90,17,100,30,100,31,132,0,90,18,71,0,100,32,100,33, - 132,0,100,33,131,2,90,19,100,1,100,1,100,34,156,2, - 100,35,100,36,132,2,90,20,100,94,100,37,100,38,132,1, - 90,21,100,39,100,40,156,1,100,41,100,42,132,2,90,22, - 100,43,100,44,132,0,90,23,100,45,100,46,132,0,90,24, - 100,47,100,48,132,0,90,25,100,49,100,50,132,0,90,26, - 100,51,100,52,132,0,90,27,100,53,100,54,132,0,90,28, - 71,0,100,55,100,56,132,0,100,56,131,2,90,29,71,0, - 100,57,100,58,132,0,100,58,131,2,90,30,71,0,100,59, - 100,60,132,0,100,60,131,2,90,31,100,61,100,62,132,0, - 90,32,100,63,100,64,132,0,90,33,100,95,100,65,100,66, - 132,1,90,34,100,67,100,68,132,0,90,35,100,69,90,36, - 101,36,100,70,23,0,90,37,100,71,100,72,132,0,90,38, - 101,39,131,0,90,40,100,73,100,74,132,0,90,41,100,96, - 100,76,100,77,132,1,90,42,100,39,100,78,156,1,100,79, - 100,80,132,2,90,43,100,81,100,82,132,0,90,44,100,97, - 100,84,100,85,132,1,90,45,100,86,100,87,132,0,90,46, - 100,88,100,89,132,0,90,47,100,90,100,91,132,0,90,48, - 100,92,100,93,132,0,90,49,100,1,83,0,41,98,97,83, - 1,0,0,67,111,114,101,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,111,102,32,105,109,112,111,114,116, - 46,10,10,84,104,105,115,32,109,111,100,117,108,101,32,105, - 115,32,78,79,84,32,109,101,97,110,116,32,116,111,32,98, - 101,32,100,105,114,101,99,116,108,121,32,105,109,112,111,114, - 116,101,100,33,32,73,116,32,104,97,115,32,98,101,101,110, - 32,100,101,115,105,103,110,101,100,32,115,117,99,104,10,116, - 104,97,116,32,105,116,32,99,97,110,32,98,101,32,98,111, - 111,116,115,116,114,97,112,112,101,100,32,105,110,116,111,32, - 80,121,116,104,111,110,32,97,115,32,116,104,101,32,105,109, - 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, - 105,109,112,111,114,116,46,32,65,115,10,115,117,99,104,32, - 105,116,32,114,101,113,117,105,114,101,115,32,116,104,101,32, - 105,110,106,101,99,116,105,111,110,32,111,102,32,115,112,101, - 99,105,102,105,99,32,109,111,100,117,108,101,115,32,97,110, - 100,32,97,116,116,114,105,98,117,116,101,115,32,105,110,32, - 111,114,100,101,114,32,116,111,10,119,111,114,107,46,32,79, - 110,101,32,115,104,111,117,108,100,32,117,115,101,32,105,109, - 112,111,114,116,108,105,98,32,97,115,32,116,104,101,32,112, - 117,98,108,105,99,45,102,97,99,105,110,103,32,118,101,114, - 115,105,111,110,32,111,102,32,116,104,105,115,32,109,111,100, - 117,108,101,46,10,10,78,99,2,0,0,0,0,0,0,0, - 3,0,0,0,7,0,0,0,67,0,0,0,115,56,0,0, - 0,100,1,68,0,93,32,125,2,116,0,124,1,124,2,131, - 2,114,4,116,1,124,0,124,2,116,2,124,1,124,2,131, - 2,131,3,1,0,113,4,124,0,106,3,160,4,124,1,106, - 3,161,1,1,0,100,2,83,0,41,3,122,47,83,105,109, - 112,108,101,32,115,117,98,115,116,105,116,117,116,101,32,102, - 111,114,32,102,117,110,99,116,111,111,108,115,46,117,112,100, - 97,116,101,95,119,114,97,112,112,101,114,46,41,4,218,10, - 95,95,109,111,100,117,108,101,95,95,218,8,95,95,110,97, - 109,101,95,95,218,12,95,95,113,117,97,108,110,97,109,101, - 95,95,218,7,95,95,100,111,99,95,95,78,41,5,218,7, - 104,97,115,97,116,116,114,218,7,115,101,116,97,116,116,114, - 218,7,103,101,116,97,116,116,114,218,8,95,95,100,105,99, - 116,95,95,218,6,117,112,100,97,116,101,41,3,90,3,110, - 101,119,90,3,111,108,100,218,7,114,101,112,108,97,99,101, - 169,0,114,10,0,0,0,250,29,60,102,114,111,122,101,110, - 32,105,109,112,111,114,116,108,105,98,46,95,98,111,111,116, - 115,116,114,97,112,62,218,5,95,119,114,97,112,27,0,0, - 0,115,8,0,0,0,0,2,8,1,10,1,20,1,114,12, - 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, - 2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,116, - 1,131,1,124,0,131,1,83,0,169,1,78,41,2,218,4, - 116,121,112,101,218,3,115,121,115,169,1,218,4,110,97,109, - 101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,11,95,110,101,119,95,109,111,100,117,108,101,35,0,0, - 0,115,2,0,0,0,0,1,114,18,0,0,0,99,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,64,0,0,0,115,194,1,0,0,100,0, + 90,0,100,1,97,1,100,2,100,3,132,0,90,2,100,4, + 100,5,132,0,90,3,105,0,90,4,105,0,90,5,71,0, + 100,6,100,7,132,0,100,7,101,6,131,3,90,7,71,0, + 100,8,100,9,132,0,100,9,131,2,90,8,71,0,100,10, + 100,11,132,0,100,11,131,2,90,9,71,0,100,12,100,13, + 132,0,100,13,131,2,90,10,100,14,100,15,132,0,90,11, + 100,16,100,17,132,0,90,12,100,18,100,19,132,0,90,13, + 100,20,100,21,156,1,100,22,100,23,132,2,90,14,100,24, + 100,25,132,0,90,15,100,26,100,27,132,0,90,16,100,28, + 100,29,132,0,90,17,100,30,100,31,132,0,90,18,71,0, + 100,32,100,33,132,0,100,33,131,2,90,19,100,1,100,1, + 100,34,156,2,100,35,100,36,132,2,90,20,100,94,100,37, + 100,38,132,1,90,21,100,39,100,40,156,1,100,41,100,42, + 132,2,90,22,100,43,100,44,132,0,90,23,100,45,100,46, + 132,0,90,24,100,47,100,48,132,0,90,25,100,49,100,50, + 132,0,90,26,100,51,100,52,132,0,90,27,100,53,100,54, + 132,0,90,28,71,0,100,55,100,56,132,0,100,56,131,2, + 90,29,71,0,100,57,100,58,132,0,100,58,131,2,90,30, + 71,0,100,59,100,60,132,0,100,60,131,2,90,31,100,61, + 100,62,132,0,90,32,100,63,100,64,132,0,90,33,100,95, + 100,65,100,66,132,1,90,34,100,67,100,68,132,0,90,35, + 100,69,90,36,101,36,100,70,23,0,90,37,100,71,100,72, + 132,0,90,38,101,39,131,0,90,40,100,73,100,74,132,0, + 90,41,100,96,100,76,100,77,132,1,90,42,100,39,100,78, + 156,1,100,79,100,80,132,2,90,43,100,81,100,82,132,0, + 90,44,100,97,100,84,100,85,132,1,90,45,100,86,100,87, + 132,0,90,46,100,88,100,89,132,0,90,47,100,90,100,91, + 132,0,90,48,100,92,100,93,132,0,90,49,100,1,83,0, + 41,98,97,83,1,0,0,67,111,114,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,105,109, + 112,111,114,116,46,10,10,84,104,105,115,32,109,111,100,117, + 108,101,32,105,115,32,78,79,84,32,109,101,97,110,116,32, + 116,111,32,98,101,32,100,105,114,101,99,116,108,121,32,105, + 109,112,111,114,116,101,100,33,32,73,116,32,104,97,115,32, + 98,101,101,110,32,100,101,115,105,103,110,101,100,32,115,117, + 99,104,10,116,104,97,116,32,105,116,32,99,97,110,32,98, + 101,32,98,111,111,116,115,116,114,97,112,112,101,100,32,105, + 110,116,111,32,80,121,116,104,111,110,32,97,115,32,116,104, + 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,111,102,32,105,109,112,111,114,116,46,32,65,115,10,115, + 117,99,104,32,105,116,32,114,101,113,117,105,114,101,115,32, + 116,104,101,32,105,110,106,101,99,116,105,111,110,32,111,102, + 32,115,112,101,99,105,102,105,99,32,109,111,100,117,108,101, + 115,32,97,110,100,32,97,116,116,114,105,98,117,116,101,115, + 32,105,110,32,111,114,100,101,114,32,116,111,10,119,111,114, + 107,46,32,79,110,101,32,115,104,111,117,108,100,32,117,115, + 101,32,105,109,112,111,114,116,108,105,98,32,97,115,32,116, + 104,101,32,112,117,98,108,105,99,45,102,97,99,105,110,103, + 32,118,101,114,115,105,111,110,32,111,102,32,116,104,105,115, + 32,109,111,100,117,108,101,46,10,10,78,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,7,0,0,0, + 67,0,0,0,115,56,0,0,0,100,1,68,0,93,32,125, + 2,116,0,124,1,124,2,131,2,114,4,116,1,124,0,124, + 2,116,2,124,1,124,2,131,2,131,3,1,0,113,4,124, + 0,106,3,160,4,124,1,106,3,161,1,1,0,100,2,83, + 0,41,3,122,47,83,105,109,112,108,101,32,115,117,98,115, + 116,105,116,117,116,101,32,102,111,114,32,102,117,110,99,116, + 111,111,108,115,46,117,112,100,97,116,101,95,119,114,97,112, + 112,101,114,46,41,4,218,10,95,95,109,111,100,117,108,101, + 95,95,218,8,95,95,110,97,109,101,95,95,218,12,95,95, + 113,117,97,108,110,97,109,101,95,95,218,7,95,95,100,111, + 99,95,95,78,41,5,218,7,104,97,115,97,116,116,114,218, + 7,115,101,116,97,116,116,114,218,7,103,101,116,97,116,116, + 114,218,8,95,95,100,105,99,116,95,95,218,6,117,112,100, + 97,116,101,41,3,90,3,110,101,119,90,3,111,108,100,218, + 7,114,101,112,108,97,99,101,169,0,114,10,0,0,0,250, + 29,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, + 105,98,46,95,98,111,111,116,115,116,114,97,112,62,218,5, + 95,119,114,97,112,27,0,0,0,115,8,0,0,0,0,2, + 8,1,10,1,20,1,114,12,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, + 67,0,0,0,115,12,0,0,0,116,0,116,1,131,1,124, + 0,131,1,83,0,169,1,78,41,2,218,4,116,121,112,101, + 218,3,115,121,115,169,1,218,4,110,97,109,101,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,11,95,110, + 101,119,95,109,111,100,117,108,101,35,0,0,0,115,2,0, + 0,0,0,1,114,18,0,0,0,99,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0, 0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100, 1,83,0,41,2,218,14,95,68,101,97,100,108,111,99,107, @@ -85,52 +86,53 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,2,0,0,0,114,10,0,0,0,114,10,0,0, 0,114,10,0,0,0,114,11,0,0,0,114,19,0,0,0, 48,0,0,0,115,2,0,0,0,8,1,114,19,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,64,0,0,0,115,56,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4, - 100,5,132,0,90,5,100,6,100,7,132,0,90,6,100,8, - 100,9,132,0,90,7,100,10,100,11,132,0,90,8,100,12, - 83,0,41,13,218,11,95,77,111,100,117,108,101,76,111,99, - 107,122,169,65,32,114,101,99,117,114,115,105,118,101,32,108, - 111,99,107,32,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,32,119,104,105,99,104,32,105,115,32,97,98,108,101, - 32,116,111,32,100,101,116,101,99,116,32,100,101,97,100,108, - 111,99,107,115,10,32,32,32,32,40,101,46,103,46,32,116, - 104,114,101,97,100,32,49,32,116,114,121,105,110,103,32,116, - 111,32,116,97,107,101,32,108,111,99,107,115,32,65,32,116, - 104,101,110,32,66,44,32,97,110,100,32,116,104,114,101,97, - 100,32,50,32,116,114,121,105,110,103,32,116,111,10,32,32, - 32,32,116,97,107,101,32,108,111,99,107,115,32,66,32,116, - 104,101,110,32,65,41,46,10,32,32,32,32,99,2,0,0, - 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, - 0,115,48,0,0,0,116,0,160,1,161,0,124,0,95,2, - 116,0,160,1,161,0,124,0,95,3,124,1,124,0,95,4, - 100,0,124,0,95,5,100,1,124,0,95,6,100,1,124,0, - 95,7,100,0,83,0,169,2,78,233,0,0,0,0,41,8, - 218,7,95,116,104,114,101,97,100,90,13,97,108,108,111,99, - 97,116,101,95,108,111,99,107,218,4,108,111,99,107,218,6, - 119,97,107,101,117,112,114,17,0,0,0,218,5,111,119,110, - 101,114,218,5,99,111,117,110,116,218,7,119,97,105,116,101, - 114,115,169,2,218,4,115,101,108,102,114,17,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,95,105,110,105,116,95,95,58,0,0,0,115,12,0,0, - 0,0,1,10,1,10,1,6,1,6,1,6,1,122,20,95, - 77,111,100,117,108,101,76,111,99,107,46,95,95,105,110,105, - 116,95,95,99,1,0,0,0,0,0,0,0,4,0,0,0, - 3,0,0,0,67,0,0,0,115,60,0,0,0,116,0,160, - 1,161,0,125,1,124,0,106,2,125,2,116,3,160,4,124, - 2,161,1,125,3,124,3,100,0,107,8,114,36,100,1,83, - 0,124,3,106,2,125,2,124,2,124,1,107,2,114,14,100, - 2,83,0,113,14,100,0,83,0,41,3,78,70,84,41,5, - 114,23,0,0,0,218,9,103,101,116,95,105,100,101,110,116, - 114,26,0,0,0,218,12,95,98,108,111,99,107,105,110,103, - 95,111,110,218,3,103,101,116,41,4,114,30,0,0,0,90, - 2,109,101,218,3,116,105,100,114,24,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,12,104,97, - 115,95,100,101,97,100,108,111,99,107,66,0,0,0,115,16, - 0,0,0,0,2,8,1,6,2,10,1,8,1,4,1,6, - 1,8,1,122,24,95,77,111,100,117,108,101,76,111,99,107, - 46,104,97,115,95,100,101,97,100,108,111,99,107,99,1,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,56,0,0,0,101,0, + 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, + 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, + 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0, + 90,8,100,12,83,0,41,13,218,11,95,77,111,100,117,108, + 101,76,111,99,107,122,169,65,32,114,101,99,117,114,115,105, + 118,101,32,108,111,99,107,32,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,32,119,104,105,99,104,32,105,115,32, + 97,98,108,101,32,116,111,32,100,101,116,101,99,116,32,100, + 101,97,100,108,111,99,107,115,10,32,32,32,32,40,101,46, + 103,46,32,116,104,114,101,97,100,32,49,32,116,114,121,105, + 110,103,32,116,111,32,116,97,107,101,32,108,111,99,107,115, + 32,65,32,116,104,101,110,32,66,44,32,97,110,100,32,116, + 104,114,101,97,100,32,50,32,116,114,121,105,110,103,32,116, + 111,10,32,32,32,32,116,97,107,101,32,108,111,99,107,115, + 32,66,32,116,104,101,110,32,65,41,46,10,32,32,32,32, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,2,0,0,0,67,0,0,0,115,48,0,0,0,116,0, + 160,1,161,0,124,0,95,2,116,0,160,1,161,0,124,0, + 95,3,124,1,124,0,95,4,100,0,124,0,95,5,100,1, + 124,0,95,6,100,1,124,0,95,7,100,0,83,0,169,2, + 78,233,0,0,0,0,41,8,218,7,95,116,104,114,101,97, + 100,90,13,97,108,108,111,99,97,116,101,95,108,111,99,107, + 218,4,108,111,99,107,218,6,119,97,107,101,117,112,114,17, + 0,0,0,218,5,111,119,110,101,114,218,5,99,111,117,110, + 116,218,7,119,97,105,116,101,114,115,169,2,218,4,115,101, + 108,102,114,17,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,95,105,110,105,116,95,95, + 58,0,0,0,115,12,0,0,0,0,1,10,1,10,1,6, + 1,6,1,6,1,122,20,95,77,111,100,117,108,101,76,111, + 99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0, + 67,0,0,0,115,60,0,0,0,116,0,160,1,161,0,125, + 1,124,0,106,2,125,2,116,3,160,4,124,2,161,1,125, + 3,124,3,100,0,107,8,114,36,100,1,83,0,124,3,106, + 2,125,2,124,2,124,1,107,2,114,14,100,2,83,0,113, + 14,100,0,83,0,41,3,78,70,84,41,5,114,23,0,0, + 0,218,9,103,101,116,95,105,100,101,110,116,114,26,0,0, + 0,218,12,95,98,108,111,99,107,105,110,103,95,111,110,218, + 3,103,101,116,41,4,114,30,0,0,0,90,2,109,101,218, + 3,116,105,100,114,24,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,12,104,97,115,95,100,101, + 97,100,108,111,99,107,66,0,0,0,115,16,0,0,0,0, + 2,8,1,6,2,10,1,8,1,4,1,6,1,8,1,122, + 24,95,77,111,100,117,108,101,76,111,99,107,46,104,97,115, + 95,100,101,97,100,108,111,99,107,99,1,0,0,0,0,0, 0,0,0,0,0,0,2,0,0,0,9,0,0,0,67,0, 0,0,115,178,0,0,0,116,0,160,1,161,0,125,1,124, 0,116,2,124,1,60,0,122,148,124,0,106,3,143,110,1, @@ -168,55 +170,56 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 1,2,2,8,1,20,1,6,1,14,1,18,1,8,1,12, 1,12,1,24,2,10,1,16,2,122,19,95,77,111,100,117, 108,101,76,111,99,107,46,97,99,113,117,105,114,101,99,1, - 0,0,0,0,0,0,0,2,0,0,0,9,0,0,0,67, - 0,0,0,115,122,0,0,0,116,0,160,1,161,0,125,1, - 124,0,106,2,143,98,1,0,124,0,106,3,124,1,107,3, - 114,34,116,4,100,1,131,1,130,1,124,0,106,5,100,2, - 107,4,115,48,116,6,130,1,124,0,4,0,106,5,100,3, - 56,0,2,0,95,5,124,0,106,5,100,2,107,2,114,108, - 100,0,124,0,95,3,124,0,106,7,114,108,124,0,4,0, - 106,7,100,3,56,0,2,0,95,7,124,0,106,8,160,9, - 161,0,1,0,87,0,53,0,81,0,82,0,88,0,100,0, - 83,0,41,4,78,250,31,99,97,110,110,111,116,32,114,101, - 108,101,97,115,101,32,117,110,45,97,99,113,117,105,114,101, - 100,32,108,111,99,107,114,22,0,0,0,114,37,0,0,0, - 41,10,114,23,0,0,0,114,32,0,0,0,114,24,0,0, - 0,114,26,0,0,0,218,12,82,117,110,116,105,109,101,69, - 114,114,111,114,114,27,0,0,0,218,14,65,115,115,101,114, - 116,105,111,110,69,114,114,111,114,114,28,0,0,0,114,25, - 0,0,0,114,39,0,0,0,114,40,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,39,0,0, - 0,103,0,0,0,115,22,0,0,0,0,1,8,1,8,1, - 10,1,8,1,14,1,14,1,10,1,6,1,6,1,14,1, - 122,19,95,77,111,100,117,108,101,76,111,99,107,46,114,101, - 108,101,97,115,101,99,1,0,0,0,0,0,0,0,1,0, - 0,0,5,0,0,0,67,0,0,0,115,18,0,0,0,100, - 1,160,0,124,0,106,1,116,2,124,0,131,1,161,2,83, - 0,41,2,78,122,23,95,77,111,100,117,108,101,76,111,99, - 107,40,123,33,114,125,41,32,97,116,32,123,125,169,3,218, - 6,102,111,114,109,97,116,114,17,0,0,0,218,2,105,100, - 169,1,114,30,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,8,95,95,114,101,112,114,95,95, - 116,0,0,0,115,2,0,0,0,0,1,122,20,95,77,111, - 100,117,108,101,76,111,99,107,46,95,95,114,101,112,114,95, - 95,78,41,9,114,1,0,0,0,114,0,0,0,0,114,2, - 0,0,0,114,3,0,0,0,114,31,0,0,0,114,36,0, - 0,0,114,38,0,0,0,114,39,0,0,0,114,48,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,20,0,0,0,52,0,0,0,115,12, - 0,0,0,8,1,4,5,8,8,8,12,8,25,8,13,114, - 20,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,64,0,0,0,115,48,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, - 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, - 90,6,100,8,100,9,132,0,90,7,100,10,83,0,41,11, - 218,16,95,68,117,109,109,121,77,111,100,117,108,101,76,111, - 99,107,122,86,65,32,115,105,109,112,108,101,32,95,77,111, - 100,117,108,101,76,111,99,107,32,101,113,117,105,118,97,108, - 101,110,116,32,102,111,114,32,80,121,116,104,111,110,32,98, - 117,105,108,100,115,32,119,105,116,104,111,117,116,10,32,32, - 32,32,109,117,108,116,105,45,116,104,114,101,97,100,105,110, - 103,32,115,117,112,112,111,114,116,46,99,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,9, + 0,0,0,67,0,0,0,115,122,0,0,0,116,0,160,1, + 161,0,125,1,124,0,106,2,143,98,1,0,124,0,106,3, + 124,1,107,3,114,34,116,4,100,1,131,1,130,1,124,0, + 106,5,100,2,107,4,115,48,116,6,130,1,124,0,4,0, + 106,5,100,3,56,0,2,0,95,5,124,0,106,5,100,2, + 107,2,114,108,100,0,124,0,95,3,124,0,106,7,114,108, + 124,0,4,0,106,7,100,3,56,0,2,0,95,7,124,0, + 106,8,160,9,161,0,1,0,87,0,53,0,81,0,82,0, + 88,0,100,0,83,0,41,4,78,250,31,99,97,110,110,111, + 116,32,114,101,108,101,97,115,101,32,117,110,45,97,99,113, + 117,105,114,101,100,32,108,111,99,107,114,22,0,0,0,114, + 37,0,0,0,41,10,114,23,0,0,0,114,32,0,0,0, + 114,24,0,0,0,114,26,0,0,0,218,12,82,117,110,116, + 105,109,101,69,114,114,111,114,114,27,0,0,0,218,14,65, + 115,115,101,114,116,105,111,110,69,114,114,111,114,114,28,0, + 0,0,114,25,0,0,0,114,39,0,0,0,114,40,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,39,0,0,0,103,0,0,0,115,22,0,0,0,0,1, + 8,1,8,1,10,1,8,1,14,1,14,1,10,1,6,1, + 6,1,14,1,122,19,95,77,111,100,117,108,101,76,111,99, + 107,46,114,101,108,101,97,115,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,5,0,0,0,67,0, + 0,0,115,18,0,0,0,100,1,160,0,124,0,106,1,116, + 2,124,0,131,1,161,2,83,0,41,2,78,122,23,95,77, + 111,100,117,108,101,76,111,99,107,40,123,33,114,125,41,32, + 97,116,32,123,125,169,3,218,6,102,111,114,109,97,116,114, + 17,0,0,0,218,2,105,100,169,1,114,30,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 95,95,114,101,112,114,95,95,116,0,0,0,115,2,0,0, + 0,0,1,122,20,95,77,111,100,117,108,101,76,111,99,107, + 46,95,95,114,101,112,114,95,95,78,41,9,114,1,0,0, + 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, + 114,31,0,0,0,114,36,0,0,0,114,38,0,0,0,114, + 39,0,0,0,114,48,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,20,0, + 0,0,52,0,0,0,115,12,0,0,0,8,1,4,5,8, + 8,8,12,8,25,8,13,114,20,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,64,0,0,0,115,48,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4, + 100,5,132,0,90,5,100,6,100,7,132,0,90,6,100,8, + 100,9,132,0,90,7,100,10,83,0,41,11,218,16,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,122,86, + 65,32,115,105,109,112,108,101,32,95,77,111,100,117,108,101, + 76,111,99,107,32,101,113,117,105,118,97,108,101,110,116,32, + 102,111,114,32,80,121,116,104,111,110,32,98,117,105,108,100, + 115,32,119,105,116,104,111,117,116,10,32,32,32,32,109,117, + 108,116,105,45,116,104,114,101,97,100,105,110,103,32,115,117, + 112,112,111,114,116,46,99,2,0,0,0,0,0,0,0,0, 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, 16,0,0,0,124,1,124,0,95,0,100,1,124,0,95,1, 100,0,83,0,114,21,0,0,0,41,2,114,17,0,0,0, @@ -224,77 +227,79 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 10,0,0,0,114,11,0,0,0,114,31,0,0,0,124,0, 0,0,115,4,0,0,0,0,1,6,1,122,25,95,68,117, 109,109,121,77,111,100,117,108,101,76,111,99,107,46,95,95, - 105,110,105,116,95,95,99,1,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,115,18,0,0,0, - 124,0,4,0,106,0,100,1,55,0,2,0,95,0,100,2, - 83,0,41,3,78,114,37,0,0,0,84,41,1,114,27,0, - 0,0,114,47,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,38,0,0,0,128,0,0,0,115, - 4,0,0,0,0,1,14,1,122,24,95,68,117,109,109,121, - 77,111,100,117,108,101,76,111,99,107,46,97,99,113,117,105, - 114,101,99,1,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,36,0,0,0,124,0,106,0, - 100,1,107,2,114,18,116,1,100,2,131,1,130,1,124,0, - 4,0,106,0,100,3,56,0,2,0,95,0,100,0,83,0, - 41,4,78,114,22,0,0,0,114,41,0,0,0,114,37,0, - 0,0,41,2,114,27,0,0,0,114,42,0,0,0,114,47, + 105,110,105,116,95,95,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 18,0,0,0,124,0,4,0,106,0,100,1,55,0,2,0, + 95,0,100,2,83,0,41,3,78,114,37,0,0,0,84,41, + 1,114,27,0,0,0,114,47,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,38,0,0,0,128, + 0,0,0,115,4,0,0,0,0,1,14,1,122,24,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,46,97, + 99,113,117,105,114,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 36,0,0,0,124,0,106,0,100,1,107,2,114,18,116,1, + 100,2,131,1,130,1,124,0,4,0,106,0,100,3,56,0, + 2,0,95,0,100,0,83,0,41,4,78,114,22,0,0,0, + 114,41,0,0,0,114,37,0,0,0,41,2,114,27,0,0, + 0,114,42,0,0,0,114,47,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,39,0,0,0,132, + 0,0,0,115,6,0,0,0,0,1,10,1,8,1,122,24, + 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107, + 46,114,101,108,101,97,115,101,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,5,0,0,0,67,0,0, + 0,115,18,0,0,0,100,1,160,0,124,0,106,1,116,2, + 124,0,131,1,161,2,83,0,41,2,78,122,28,95,68,117, + 109,109,121,77,111,100,117,108,101,76,111,99,107,40,123,33, + 114,125,41,32,97,116,32,123,125,114,44,0,0,0,114,47, 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,39,0,0,0,132,0,0,0,115,6,0,0,0, - 0,1,10,1,8,1,122,24,95,68,117,109,109,121,77,111, - 100,117,108,101,76,111,99,107,46,114,101,108,101,97,115,101, - 99,1,0,0,0,0,0,0,0,1,0,0,0,5,0,0, - 0,67,0,0,0,115,18,0,0,0,100,1,160,0,124,0, - 106,1,116,2,124,0,131,1,161,2,83,0,41,2,78,122, - 28,95,68,117,109,109,121,77,111,100,117,108,101,76,111,99, - 107,40,123,33,114,125,41,32,97,116,32,123,125,114,44,0, - 0,0,114,47,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,48,0,0,0,137,0,0,0,115, - 2,0,0,0,0,1,122,25,95,68,117,109,109,121,77,111, - 100,117,108,101,76,111,99,107,46,95,95,114,101,112,114,95, - 95,78,41,8,114,1,0,0,0,114,0,0,0,0,114,2, - 0,0,0,114,3,0,0,0,114,31,0,0,0,114,38,0, - 0,0,114,39,0,0,0,114,48,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,49,0,0,0,120,0,0,0,115,10,0,0,0,8,1, - 4,3,8,4,8,4,8,5,114,49,0,0,0,99,0,0, + 0,0,114,48,0,0,0,137,0,0,0,115,2,0,0,0, + 0,1,122,25,95,68,117,109,109,121,77,111,100,117,108,101, + 76,111,99,107,46,95,95,114,101,112,114,95,95,78,41,8, + 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, + 3,0,0,0,114,31,0,0,0,114,38,0,0,0,114,39, + 0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,49,0,0, + 0,120,0,0,0,115,10,0,0,0,8,1,4,3,8,4, + 8,4,8,5,114,49,0,0,0,99,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, 0,0,115,36,0,0,0,101,0,90,1,100,0,90,2,100, 1,100,2,132,0,90,3,100,3,100,4,132,0,90,4,100, 5,100,6,132,0,90,5,100,7,83,0,41,8,218,18,95, 77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,101, - 114,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0, - 0,0,67,0,0,0,115,16,0,0,0,124,1,124,0,95, - 0,100,0,124,0,95,1,100,0,83,0,114,13,0,0,0, - 41,2,218,5,95,110,97,109,101,218,5,95,108,111,99,107, - 114,29,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,31,0,0,0,143,0,0,0,115,4,0, - 0,0,0,1,6,1,122,27,95,77,111,100,117,108,101,76, - 111,99,107,77,97,110,97,103,101,114,46,95,95,105,110,105, - 116,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, - 2,0,0,0,67,0,0,0,115,26,0,0,0,116,0,124, - 0,106,1,131,1,124,0,95,2,124,0,106,2,160,3,161, - 0,1,0,100,0,83,0,114,13,0,0,0,41,4,218,16, - 95,103,101,116,95,109,111,100,117,108,101,95,108,111,99,107, - 114,51,0,0,0,114,52,0,0,0,114,38,0,0,0,114, - 47,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,9,95,95,101,110,116,101,114,95,95,147,0, - 0,0,115,4,0,0,0,0,1,12,1,122,28,95,77,111, - 100,117,108,101,76,111,99,107,77,97,110,97,103,101,114,46, - 95,95,101,110,116,101,114,95,95,99,1,0,0,0,0,0, - 0,0,3,0,0,0,2,0,0,0,79,0,0,0,115,14, - 0,0,0,124,0,106,0,160,1,161,0,1,0,100,0,83, - 0,114,13,0,0,0,41,2,114,52,0,0,0,114,39,0, - 0,0,41,3,114,30,0,0,0,218,4,97,114,103,115,90, - 6,107,119,97,114,103,115,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,8,95,95,101,120,105,116,95,95, - 151,0,0,0,115,2,0,0,0,0,1,122,27,95,77,111, - 100,117,108,101,76,111,99,107,77,97,110,97,103,101,114,46, - 95,95,101,120,105,116,95,95,78,41,6,114,1,0,0,0, - 114,0,0,0,0,114,2,0,0,0,114,31,0,0,0,114, - 54,0,0,0,114,56,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,50,0, - 0,0,141,0,0,0,115,6,0,0,0,8,2,8,4,8, - 4,114,50,0,0,0,99,1,0,0,0,0,0,0,0,3, + 114,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124, + 1,124,0,95,0,100,0,124,0,95,1,100,0,83,0,114, + 13,0,0,0,41,2,218,5,95,110,97,109,101,218,5,95, + 108,111,99,107,114,29,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,31,0,0,0,143,0,0, + 0,115,4,0,0,0,0,1,6,1,122,27,95,77,111,100, + 117,108,101,76,111,99,107,77,97,110,97,103,101,114,46,95, + 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0, + 115,26,0,0,0,116,0,124,0,106,1,131,1,124,0,95, + 2,124,0,106,2,160,3,161,0,1,0,100,0,83,0,114, + 13,0,0,0,41,4,218,16,95,103,101,116,95,109,111,100, + 117,108,101,95,108,111,99,107,114,51,0,0,0,114,52,0, + 0,0,114,38,0,0,0,114,47,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,9,95,95,101, + 110,116,101,114,95,95,147,0,0,0,115,4,0,0,0,0, + 1,12,1,122,28,95,77,111,100,117,108,101,76,111,99,107, + 77,97,110,97,103,101,114,46,95,95,101,110,116,101,114,95, + 95,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,2,0,0,0,79,0,0,0,115,14,0,0,0,124, + 0,106,0,160,1,161,0,1,0,100,0,83,0,114,13,0, + 0,0,41,2,114,52,0,0,0,114,39,0,0,0,41,3, + 114,30,0,0,0,218,4,97,114,103,115,90,6,107,119,97, + 114,103,115,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,8,95,95,101,120,105,116,95,95,151,0,0,0, + 115,2,0,0,0,0,1,122,27,95,77,111,100,117,108,101, + 76,111,99,107,77,97,110,97,103,101,114,46,95,95,101,120, + 105,116,95,95,78,41,6,114,1,0,0,0,114,0,0,0, + 0,114,2,0,0,0,114,31,0,0,0,114,54,0,0,0, + 114,56,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,50,0,0,0,141,0, + 0,0,115,6,0,0,0,8,2,8,4,8,4,114,50,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,3, 0,0,0,8,0,0,0,67,0,0,0,115,130,0,0,0, 116,0,160,1,161,0,1,0,122,106,122,14,116,2,124,0, 25,0,131,0,125,1,87,0,110,24,4,0,116,3,107,10, @@ -313,80 +318,81 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 32,103,108,111,98,97,108,32,105,109,112,111,114,116,32,108, 111,99,107,32,116,111,32,112,114,111,116,101,99,116,10,32, 32,32,32,95,109,111,100,117,108,101,95,108,111,99,107,115, - 46,78,99,2,0,0,0,0,0,0,0,2,0,0,0,8, - 0,0,0,83,0,0,0,115,48,0,0,0,116,0,160,1, - 161,0,1,0,122,24,116,2,160,3,124,1,161,1,124,0, - 107,8,114,30,116,2,124,1,61,0,87,0,53,0,116,0, - 160,4,161,0,1,0,88,0,100,0,83,0,114,13,0,0, - 0,41,5,218,4,95,105,109,112,218,12,97,99,113,117,105, - 114,101,95,108,111,99,107,218,13,95,109,111,100,117,108,101, - 95,108,111,99,107,115,114,34,0,0,0,218,12,114,101,108, - 101,97,115,101,95,108,111,99,107,41,2,218,3,114,101,102, - 114,17,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,2,99,98,176,0,0,0,115,10,0,0, - 0,0,1,8,1,2,4,14,1,10,2,122,28,95,103,101, - 116,95,109,111,100,117,108,101,95,108,111,99,107,46,60,108, - 111,99,97,108,115,62,46,99,98,41,10,114,57,0,0,0, - 114,58,0,0,0,114,59,0,0,0,218,8,75,101,121,69, - 114,114,111,114,114,23,0,0,0,114,49,0,0,0,114,20, - 0,0,0,218,8,95,119,101,97,107,114,101,102,114,61,0, - 0,0,114,60,0,0,0,41,3,114,17,0,0,0,114,24, - 0,0,0,114,62,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,53,0,0,0,157,0,0,0, - 115,28,0,0,0,0,6,8,1,2,1,2,1,14,1,14, - 1,10,2,8,1,8,1,10,2,8,2,12,11,20,2,10, - 2,114,53,0,0,0,99,1,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,67,0,0,0,115,54,0,0,0, - 116,0,124,0,131,1,125,1,122,12,124,1,160,1,161,0, - 1,0,87,0,110,20,4,0,116,2,107,10,114,40,1,0, - 1,0,1,0,89,0,110,10,88,0,124,1,160,3,161,0, - 1,0,100,1,83,0,41,2,122,189,65,99,113,117,105,114, - 101,115,32,116,104,101,110,32,114,101,108,101,97,115,101,115, - 32,116,104,101,32,109,111,100,117,108,101,32,108,111,99,107, - 32,102,111,114,32,97,32,103,105,118,101,110,32,109,111,100, - 117,108,101,32,110,97,109,101,46,10,10,32,32,32,32,84, - 104,105,115,32,105,115,32,117,115,101,100,32,116,111,32,101, - 110,115,117,114,101,32,97,32,109,111,100,117,108,101,32,105, - 115,32,99,111,109,112,108,101,116,101,108,121,32,105,110,105, - 116,105,97,108,105,122,101,100,44,32,105,110,32,116,104,101, - 10,32,32,32,32,101,118,101,110,116,32,105,116,32,105,115, - 32,98,101,105,110,103,32,105,109,112,111,114,116,101,100,32, - 98,121,32,97,110,111,116,104,101,114,32,116,104,114,101,97, - 100,46,10,32,32,32,32,78,41,4,114,53,0,0,0,114, - 38,0,0,0,114,19,0,0,0,114,39,0,0,0,41,2, - 114,17,0,0,0,114,24,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,19,95,108,111,99,107, - 95,117,110,108,111,99,107,95,109,111,100,117,108,101,194,0, - 0,0,115,12,0,0,0,0,6,8,1,2,1,12,1,14, - 3,6,2,114,65,0,0,0,99,1,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,79,0,0,0,115,10,0, - 0,0,124,0,124,1,124,2,142,1,83,0,41,1,97,46, - 1,0,0,114,101,109,111,118,101,95,105,109,112,111,114,116, - 108,105,98,95,102,114,97,109,101,115,32,105,110,32,105,109, - 112,111,114,116,46,99,32,119,105,108,108,32,97,108,119,97, - 121,115,32,114,101,109,111,118,101,32,115,101,113,117,101,110, - 99,101,115,10,32,32,32,32,111,102,32,105,109,112,111,114, - 116,108,105,98,32,102,114,97,109,101,115,32,116,104,97,116, - 32,101,110,100,32,119,105,116,104,32,97,32,99,97,108,108, - 32,116,111,32,116,104,105,115,32,102,117,110,99,116,105,111, - 110,10,10,32,32,32,32,85,115,101,32,105,116,32,105,110, - 115,116,101,97,100,32,111,102,32,97,32,110,111,114,109,97, - 108,32,99,97,108,108,32,105,110,32,112,108,97,99,101,115, - 32,119,104,101,114,101,32,105,110,99,108,117,100,105,110,103, - 32,116,104,101,32,105,109,112,111,114,116,108,105,98,10,32, - 32,32,32,102,114,97,109,101,115,32,105,110,116,114,111,100, - 117,99,101,115,32,117,110,119,97,110,116,101,100,32,110,111, - 105,115,101,32,105,110,116,111,32,116,104,101,32,116,114,97, - 99,101,98,97,99,107,32,40,101,46,103,46,32,119,104,101, - 110,32,101,120,101,99,117,116,105,110,103,10,32,32,32,32, - 109,111,100,117,108,101,32,99,111,100,101,41,10,32,32,32, - 32,114,10,0,0,0,41,3,218,1,102,114,55,0,0,0, - 90,4,107,119,100,115,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,25,95,99,97,108,108,95,119,105,116, - 104,95,102,114,97,109,101,115,95,114,101,109,111,118,101,100, - 211,0,0,0,115,2,0,0,0,0,8,114,67,0,0,0, - 114,37,0,0,0,41,1,218,9,118,101,114,98,111,115,105, - 116,121,99,1,0,0,0,1,0,0,0,3,0,0,0,4, + 46,78,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,8,0,0,0,83,0,0,0,115,48,0,0,0, + 116,0,160,1,161,0,1,0,122,24,116,2,160,3,124,1, + 161,1,124,0,107,8,114,30,116,2,124,1,61,0,87,0, + 53,0,116,0,160,4,161,0,1,0,88,0,100,0,83,0, + 114,13,0,0,0,41,5,218,4,95,105,109,112,218,12,97, + 99,113,117,105,114,101,95,108,111,99,107,218,13,95,109,111, + 100,117,108,101,95,108,111,99,107,115,114,34,0,0,0,218, + 12,114,101,108,101,97,115,101,95,108,111,99,107,41,2,218, + 3,114,101,102,114,17,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,2,99,98,176,0,0,0, + 115,10,0,0,0,0,1,8,1,2,4,14,1,10,2,122, + 28,95,103,101,116,95,109,111,100,117,108,101,95,108,111,99, + 107,46,60,108,111,99,97,108,115,62,46,99,98,41,10,114, + 57,0,0,0,114,58,0,0,0,114,59,0,0,0,218,8, + 75,101,121,69,114,114,111,114,114,23,0,0,0,114,49,0, + 0,0,114,20,0,0,0,218,8,95,119,101,97,107,114,101, + 102,114,61,0,0,0,114,60,0,0,0,41,3,114,17,0, + 0,0,114,24,0,0,0,114,62,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,53,0,0,0, + 157,0,0,0,115,28,0,0,0,0,6,8,1,2,1,2, + 1,14,1,14,1,10,2,8,1,8,1,10,2,8,2,12, + 11,20,2,10,2,114,53,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,8,0,0,0,67, + 0,0,0,115,54,0,0,0,116,0,124,0,131,1,125,1, + 122,12,124,1,160,1,161,0,1,0,87,0,110,20,4,0, + 116,2,107,10,114,40,1,0,1,0,1,0,89,0,110,10, + 88,0,124,1,160,3,161,0,1,0,100,1,83,0,41,2, + 122,189,65,99,113,117,105,114,101,115,32,116,104,101,110,32, + 114,101,108,101,97,115,101,115,32,116,104,101,32,109,111,100, + 117,108,101,32,108,111,99,107,32,102,111,114,32,97,32,103, + 105,118,101,110,32,109,111,100,117,108,101,32,110,97,109,101, + 46,10,10,32,32,32,32,84,104,105,115,32,105,115,32,117, + 115,101,100,32,116,111,32,101,110,115,117,114,101,32,97,32, + 109,111,100,117,108,101,32,105,115,32,99,111,109,112,108,101, + 116,101,108,121,32,105,110,105,116,105,97,108,105,122,101,100, + 44,32,105,110,32,116,104,101,10,32,32,32,32,101,118,101, + 110,116,32,105,116,32,105,115,32,98,101,105,110,103,32,105, + 109,112,111,114,116,101,100,32,98,121,32,97,110,111,116,104, + 101,114,32,116,104,114,101,97,100,46,10,32,32,32,32,78, + 41,4,114,53,0,0,0,114,38,0,0,0,114,19,0,0, + 0,114,39,0,0,0,41,2,114,17,0,0,0,114,24,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,19,95,108,111,99,107,95,117,110,108,111,99,107,95, + 109,111,100,117,108,101,194,0,0,0,115,12,0,0,0,0, + 6,8,1,2,1,12,1,14,3,6,2,114,65,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,3,0,0,0,79,0,0,0,115,10,0,0,0,124,0, + 124,1,124,2,142,1,83,0,41,1,97,46,1,0,0,114, + 101,109,111,118,101,95,105,109,112,111,114,116,108,105,98,95, + 102,114,97,109,101,115,32,105,110,32,105,109,112,111,114,116, + 46,99,32,119,105,108,108,32,97,108,119,97,121,115,32,114, + 101,109,111,118,101,32,115,101,113,117,101,110,99,101,115,10, + 32,32,32,32,111,102,32,105,109,112,111,114,116,108,105,98, + 32,102,114,97,109,101,115,32,116,104,97,116,32,101,110,100, + 32,119,105,116,104,32,97,32,99,97,108,108,32,116,111,32, + 116,104,105,115,32,102,117,110,99,116,105,111,110,10,10,32, + 32,32,32,85,115,101,32,105,116,32,105,110,115,116,101,97, + 100,32,111,102,32,97,32,110,111,114,109,97,108,32,99,97, + 108,108,32,105,110,32,112,108,97,99,101,115,32,119,104,101, + 114,101,32,105,110,99,108,117,100,105,110,103,32,116,104,101, + 32,105,109,112,111,114,116,108,105,98,10,32,32,32,32,102, + 114,97,109,101,115,32,105,110,116,114,111,100,117,99,101,115, + 32,117,110,119,97,110,116,101,100,32,110,111,105,115,101,32, + 105,110,116,111,32,116,104,101,32,116,114,97,99,101,98,97, + 99,107,32,40,101,46,103,46,32,119,104,101,110,32,101,120, + 101,99,117,116,105,110,103,10,32,32,32,32,109,111,100,117, + 108,101,32,99,111,100,101,41,10,32,32,32,32,114,10,0, + 0,0,41,3,218,1,102,114,55,0,0,0,90,4,107,119, + 100,115,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,25,95,99,97,108,108,95,119,105,116,104,95,102,114, + 97,109,101,115,95,114,101,109,111,118,101,100,211,0,0,0, + 115,2,0,0,0,0,8,114,67,0,0,0,114,37,0,0, + 0,41,1,218,9,118,101,114,98,111,115,105,116,121,99,1, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,4, 0,0,0,71,0,0,0,115,54,0,0,0,116,0,106,1, 106,2,124,1,107,5,114,50,124,0,160,3,100,1,161,1, 115,30,100,2,124,0,23,0,125,0,116,4,124,0,106,5, @@ -405,42 +411,43 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 10,0,0,0,114,11,0,0,0,218,16,95,118,101,114,98, 111,115,101,95,109,101,115,115,97,103,101,222,0,0,0,115, 8,0,0,0,0,2,12,1,10,1,8,1,114,76,0,0, - 0,99,1,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,3,0,0,0,115,26,0,0,0,135,0,102,1,100, - 1,100,2,132,8,125,1,116,0,124,1,136,0,131,2,1, - 0,124,1,83,0,41,3,122,49,68,101,99,111,114,97,116, - 111,114,32,116,111,32,118,101,114,105,102,121,32,116,104,101, - 32,110,97,109,101,100,32,109,111,100,117,108,101,32,105,115, - 32,98,117,105,108,116,45,105,110,46,99,2,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,19,0,0,0,115, - 38,0,0,0,124,1,116,0,106,1,107,7,114,28,116,2, - 100,1,160,3,124,1,161,1,124,1,100,2,141,2,130,1, - 136,0,124,0,124,1,131,2,83,0,41,3,78,250,29,123, - 33,114,125,32,105,115,32,110,111,116,32,97,32,98,117,105, - 108,116,45,105,110,32,109,111,100,117,108,101,114,16,0,0, - 0,41,4,114,15,0,0,0,218,20,98,117,105,108,116,105, - 110,95,109,111,100,117,108,101,95,110,97,109,101,115,218,11, - 73,109,112,111,114,116,69,114,114,111,114,114,45,0,0,0, - 169,2,114,30,0,0,0,218,8,102,117,108,108,110,97,109, - 101,169,1,218,3,102,120,110,114,10,0,0,0,114,11,0, - 0,0,218,25,95,114,101,113,117,105,114,101,115,95,98,117, - 105,108,116,105,110,95,119,114,97,112,112,101,114,232,0,0, - 0,115,10,0,0,0,0,1,10,1,10,1,2,255,6,2, - 122,52,95,114,101,113,117,105,114,101,115,95,98,117,105,108, - 116,105,110,46,60,108,111,99,97,108,115,62,46,95,114,101, - 113,117,105,114,101,115,95,98,117,105,108,116,105,110,95,119, - 114,97,112,112,101,114,169,1,114,12,0,0,0,41,2,114, - 83,0,0,0,114,84,0,0,0,114,10,0,0,0,114,82, - 0,0,0,114,11,0,0,0,218,17,95,114,101,113,117,105, - 114,101,115,95,98,117,105,108,116,105,110,230,0,0,0,115, - 6,0,0,0,0,2,12,5,10,1,114,86,0,0,0,99, - 1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 3,0,0,0,115,26,0,0,0,135,0,102,1,100,1,100, - 2,132,8,125,1,116,0,124,1,136,0,131,2,1,0,124, - 1,83,0,41,3,122,47,68,101,99,111,114,97,116,111,114, - 32,116,111,32,118,101,114,105,102,121,32,116,104,101,32,110, - 97,109,101,100,32,109,111,100,117,108,101,32,105,115,32,102, - 114,111,122,101,110,46,99,2,0,0,0,0,0,0,0,2, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,3,0,0,0,115,26,0,0,0,135, + 0,102,1,100,1,100,2,132,8,125,1,116,0,124,1,136, + 0,131,2,1,0,124,1,83,0,41,3,122,49,68,101,99, + 111,114,97,116,111,114,32,116,111,32,118,101,114,105,102,121, + 32,116,104,101,32,110,97,109,101,100,32,109,111,100,117,108, + 101,32,105,115,32,98,117,105,108,116,45,105,110,46,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,19,0,0,0,115,38,0,0,0,124,1,116,0, + 106,1,107,7,114,28,116,2,100,1,160,3,124,1,161,1, + 124,1,100,2,141,2,130,1,136,0,124,0,124,1,131,2, + 83,0,41,3,78,250,29,123,33,114,125,32,105,115,32,110, + 111,116,32,97,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,114,16,0,0,0,41,4,114,15,0,0,0, + 218,20,98,117,105,108,116,105,110,95,109,111,100,117,108,101, + 95,110,97,109,101,115,218,11,73,109,112,111,114,116,69,114, + 114,111,114,114,45,0,0,0,169,2,114,30,0,0,0,218, + 8,102,117,108,108,110,97,109,101,169,1,218,3,102,120,110, + 114,10,0,0,0,114,11,0,0,0,218,25,95,114,101,113, + 117,105,114,101,115,95,98,117,105,108,116,105,110,95,119,114, + 97,112,112,101,114,232,0,0,0,115,10,0,0,0,0,1, + 10,1,10,1,2,255,6,2,122,52,95,114,101,113,117,105, + 114,101,115,95,98,117,105,108,116,105,110,46,60,108,111,99, + 97,108,115,62,46,95,114,101,113,117,105,114,101,115,95,98, + 117,105,108,116,105,110,95,119,114,97,112,112,101,114,169,1, + 114,12,0,0,0,41,2,114,83,0,0,0,114,84,0,0, + 0,114,10,0,0,0,114,82,0,0,0,114,11,0,0,0, + 218,17,95,114,101,113,117,105,114,101,115,95,98,117,105,108, + 116,105,110,230,0,0,0,115,6,0,0,0,0,2,12,5, + 10,1,114,86,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0, + 115,26,0,0,0,135,0,102,1,100,1,100,2,132,8,125, + 1,116,0,124,1,136,0,131,2,1,0,124,1,83,0,41, + 3,122,47,68,101,99,111,114,97,116,111,114,32,116,111,32, + 118,101,114,105,102,121,32,116,104,101,32,110,97,109,101,100, + 32,109,111,100,117,108,101,32,105,115,32,102,114,111,122,101, + 110,46,99,2,0,0,0,0,0,0,0,0,0,0,0,2, 0,0,0,4,0,0,0,19,0,0,0,115,38,0,0,0, 116,0,160,1,124,1,161,1,115,28,116,2,100,1,160,3, 124,1,161,1,124,1,100,2,141,2,130,1,136,0,124,0, @@ -460,170 +467,171 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,82,0,0,0,114,11,0,0,0,218,16,95,114, 101,113,117,105,114,101,115,95,102,114,111,122,101,110,241,0, 0,0,115,6,0,0,0,0,2,12,5,10,1,114,90,0, - 0,0,99,2,0,0,0,0,0,0,0,4,0,0,0,3, - 0,0,0,67,0,0,0,115,62,0,0,0,116,0,124,1, - 124,0,131,2,125,2,124,1,116,1,106,2,107,6,114,50, - 116,1,106,2,124,1,25,0,125,3,116,3,124,2,124,3, - 131,2,1,0,116,1,106,2,124,1,25,0,83,0,116,4, - 124,2,131,1,83,0,100,1,83,0,41,2,122,128,76,111, - 97,100,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,32,105,110,116,111,32,115,121,115, - 46,109,111,100,117,108,101,115,32,97,110,100,32,114,101,116, - 117,114,110,32,105,116,46,10,10,32,32,32,32,84,104,105, - 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, - 101,99,97,116,101,100,46,32,32,85,115,101,32,108,111,97, - 100,101,114,46,101,120,101,99,95,109,111,100,117,108,101,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,78,41, - 5,218,16,115,112,101,99,95,102,114,111,109,95,108,111,97, - 100,101,114,114,15,0,0,0,218,7,109,111,100,117,108,101, - 115,218,5,95,101,120,101,99,218,5,95,108,111,97,100,41, - 4,114,30,0,0,0,114,81,0,0,0,218,4,115,112,101, - 99,218,6,109,111,100,117,108,101,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,17,95,108,111,97,100,95, - 109,111,100,117,108,101,95,115,104,105,109,253,0,0,0,115, - 12,0,0,0,0,6,10,1,10,1,10,1,10,1,10,2, - 114,97,0,0,0,99,1,0,0,0,0,0,0,0,5,0, - 0,0,8,0,0,0,67,0,0,0,115,226,0,0,0,116, - 0,124,0,100,1,100,0,131,3,125,1,116,1,124,1,100, - 2,131,2,114,56,122,12,124,1,160,2,124,0,161,1,87, - 0,83,0,4,0,116,3,107,10,114,54,1,0,1,0,1, - 0,89,0,110,2,88,0,122,10,124,0,106,4,125,2,87, - 0,110,20,4,0,116,5,107,10,114,86,1,0,1,0,1, - 0,89,0,110,18,88,0,124,2,100,0,107,9,114,104,116, - 6,124,2,131,1,83,0,122,10,124,0,106,7,125,3,87, - 0,110,24,4,0,116,5,107,10,114,138,1,0,1,0,1, - 0,100,3,125,3,89,0,110,2,88,0,122,10,124,0,106, - 8,125,4,87,0,110,58,4,0,116,5,107,10,114,208,1, - 0,1,0,1,0,124,1,100,0,107,8,114,188,100,4,160, - 9,124,3,161,1,6,0,89,0,83,0,100,5,160,9,124, - 3,124,1,161,2,6,0,89,0,83,0,89,0,110,14,88, - 0,100,6,160,9,124,3,124,4,161,2,83,0,100,0,83, - 0,41,7,78,218,10,95,95,108,111,97,100,101,114,95,95, - 218,11,109,111,100,117,108,101,95,114,101,112,114,250,1,63, - 250,13,60,109,111,100,117,108,101,32,123,33,114,125,62,250, - 20,60,109,111,100,117,108,101,32,123,33,114,125,32,40,123, - 33,114,125,41,62,250,23,60,109,111,100,117,108,101,32,123, - 33,114,125,32,102,114,111,109,32,123,33,114,125,62,41,10, - 114,6,0,0,0,114,4,0,0,0,114,99,0,0,0,218, - 9,69,120,99,101,112,116,105,111,110,218,8,95,95,115,112, - 101,99,95,95,218,14,65,116,116,114,105,98,117,116,101,69, - 114,114,111,114,218,22,95,109,111,100,117,108,101,95,114,101, - 112,114,95,102,114,111,109,95,115,112,101,99,114,1,0,0, - 0,218,8,95,95,102,105,108,101,95,95,114,45,0,0,0, - 41,5,114,96,0,0,0,218,6,108,111,97,100,101,114,114, - 95,0,0,0,114,17,0,0,0,218,8,102,105,108,101,110, - 97,109,101,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,12,95,109,111,100,117,108,101,95,114,101,112,114, - 13,1,0,0,115,46,0,0,0,0,2,12,1,10,4,2, - 1,12,1,14,1,6,1,2,1,10,1,14,1,6,2,8, - 1,8,4,2,1,10,1,14,1,10,1,2,1,10,1,14, - 1,8,1,14,2,22,2,114,111,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0, - 0,115,114,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,2,100,2,100,3,156,3,100,4,100,5, - 132,2,90,4,100,6,100,7,132,0,90,5,100,8,100,9, - 132,0,90,6,101,7,100,10,100,11,132,0,131,1,90,8, - 101,8,106,9,100,12,100,11,132,0,131,1,90,8,101,7, - 100,13,100,14,132,0,131,1,90,10,101,7,100,15,100,16, - 132,0,131,1,90,11,101,11,106,9,100,17,100,16,132,0, - 131,1,90,11,100,2,83,0,41,18,218,10,77,111,100,117, - 108,101,83,112,101,99,97,208,5,0,0,84,104,101,32,115, - 112,101,99,105,102,105,99,97,116,105,111,110,32,102,111,114, - 32,97,32,109,111,100,117,108,101,44,32,117,115,101,100,32, - 102,111,114,32,108,111,97,100,105,110,103,46,10,10,32,32, - 32,32,65,32,109,111,100,117,108,101,39,115,32,115,112,101, - 99,32,105,115,32,116,104,101,32,115,111,117,114,99,101,32, - 102,111,114,32,105,110,102,111,114,109,97,116,105,111,110,32, - 97,98,111,117,116,32,116,104,101,32,109,111,100,117,108,101, - 46,32,32,70,111,114,10,32,32,32,32,100,97,116,97,32, - 97,115,115,111,99,105,97,116,101,100,32,119,105,116,104,32, - 116,104,101,32,109,111,100,117,108,101,44,32,105,110,99,108, - 117,100,105,110,103,32,115,111,117,114,99,101,44,32,117,115, - 101,32,116,104,101,32,115,112,101,99,39,115,10,32,32,32, - 32,108,111,97,100,101,114,46,10,10,32,32,32,32,96,110, - 97,109,101,96,32,105,115,32,116,104,101,32,97,98,115,111, - 108,117,116,101,32,110,97,109,101,32,111,102,32,116,104,101, - 32,109,111,100,117,108,101,46,32,32,96,108,111,97,100,101, - 114,96,32,105,115,32,116,104,101,32,108,111,97,100,101,114, - 10,32,32,32,32,116,111,32,117,115,101,32,119,104,101,110, - 32,108,111,97,100,105,110,103,32,116,104,101,32,109,111,100, - 117,108,101,46,32,32,96,112,97,114,101,110,116,96,32,105, - 115,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,10,32,32,32,32,112,97,99,107,97,103,101,32,116,104, - 101,32,109,111,100,117,108,101,32,105,115,32,105,110,46,32, - 32,84,104,101,32,112,97,114,101,110,116,32,105,115,32,100, - 101,114,105,118,101,100,32,102,114,111,109,32,116,104,101,32, - 110,97,109,101,46,10,10,32,32,32,32,96,105,115,95,112, - 97,99,107,97,103,101,96,32,100,101,116,101,114,109,105,110, - 101,115,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,105,115,32,99,111,110,115,105,100,101,114,101,100,32,97, - 32,112,97,99,107,97,103,101,32,111,114,10,32,32,32,32, - 110,111,116,46,32,32,79,110,32,109,111,100,117,108,101,115, - 32,116,104,105,115,32,105,115,32,114,101,102,108,101,99,116, - 101,100,32,98,121,32,116,104,101,32,96,95,95,112,97,116, - 104,95,95,96,32,97,116,116,114,105,98,117,116,101,46,10, - 10,32,32,32,32,96,111,114,105,103,105,110,96,32,105,115, - 32,116,104,101,32,115,112,101,99,105,102,105,99,32,108,111, - 99,97,116,105,111,110,32,117,115,101,100,32,98,121,32,116, - 104,101,32,108,111,97,100,101,114,32,102,114,111,109,32,119, - 104,105,99,104,32,116,111,10,32,32,32,32,108,111,97,100, - 32,116,104,101,32,109,111,100,117,108,101,44,32,105,102,32, - 116,104,97,116,32,105,110,102,111,114,109,97,116,105,111,110, - 32,105,115,32,97,118,97,105,108,97,98,108,101,46,32,32, - 87,104,101,110,32,102,105,108,101,110,97,109,101,32,105,115, - 10,32,32,32,32,115,101,116,44,32,111,114,105,103,105,110, - 32,119,105,108,108,32,109,97,116,99,104,46,10,10,32,32, - 32,32,96,104,97,115,95,108,111,99,97,116,105,111,110,96, - 32,105,110,100,105,99,97,116,101,115,32,116,104,97,116,32, - 97,32,115,112,101,99,39,115,32,34,111,114,105,103,105,110, - 34,32,114,101,102,108,101,99,116,115,32,97,32,108,111,99, - 97,116,105,111,110,46,10,32,32,32,32,87,104,101,110,32, - 116,104,105,115,32,105,115,32,84,114,117,101,44,32,96,95, - 95,102,105,108,101,95,95,96,32,97,116,116,114,105,98,117, - 116,101,32,111,102,32,116,104,101,32,109,111,100,117,108,101, - 32,105,115,32,115,101,116,46,10,10,32,32,32,32,96,99, - 97,99,104,101,100,96,32,105,115,32,116,104,101,32,108,111, - 99,97,116,105,111,110,32,111,102,32,116,104,101,32,99,97, - 99,104,101,100,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,44,32,105,102,32,97,110,121,46,32,32,73,116,10, - 32,32,32,32,99,111,114,114,101,115,112,111,110,100,115,32, - 116,111,32,116,104,101,32,96,95,95,99,97,99,104,101,100, - 95,95,96,32,97,116,116,114,105,98,117,116,101,46,10,10, - 32,32,32,32,96,115,117,98,109,111,100,117,108,101,95,115, - 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,96, - 32,105,115,32,116,104,101,32,115,101,113,117,101,110,99,101, - 32,111,102,32,112,97,116,104,32,101,110,116,114,105,101,115, - 32,116,111,10,32,32,32,32,115,101,97,114,99,104,32,119, - 104,101,110,32,105,109,112,111,114,116,105,110,103,32,115,117, - 98,109,111,100,117,108,101,115,46,32,32,73,102,32,115,101, - 116,44,32,105,115,95,112,97,99,107,97,103,101,32,115,104, - 111,117,108,100,32,98,101,10,32,32,32,32,84,114,117,101, - 45,45,97,110,100,32,70,97,108,115,101,32,111,116,104,101, - 114,119,105,115,101,46,10,10,32,32,32,32,80,97,99,107, - 97,103,101,115,32,97,114,101,32,115,105,109,112,108,121,32, - 109,111,100,117,108,101,115,32,116,104,97,116,32,40,109,97, - 121,41,32,104,97,118,101,32,115,117,98,109,111,100,117,108, - 101,115,46,32,32,73,102,32,97,32,115,112,101,99,10,32, - 32,32,32,104,97,115,32,97,32,110,111,110,45,78,111,110, - 101,32,118,97,108,117,101,32,105,110,32,96,115,117,98,109, - 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, - 97,116,105,111,110,115,96,44,32,116,104,101,32,105,109,112, - 111,114,116,10,32,32,32,32,115,121,115,116,101,109,32,119, - 105,108,108,32,99,111,110,115,105,100,101,114,32,109,111,100, - 117,108,101,115,32,108,111,97,100,101,100,32,102,114,111,109, - 32,116,104,101,32,115,112,101,99,32,97,115,32,112,97,99, - 107,97,103,101,115,46,10,10,32,32,32,32,79,110,108,121, - 32,102,105,110,100,101,114,115,32,40,115,101,101,32,105,109, - 112,111,114,116,108,105,98,46,97,98,99,46,77,101,116,97, - 80,97,116,104,70,105,110,100,101,114,32,97,110,100,10,32, - 32,32,32,105,109,112,111,114,116,108,105,98,46,97,98,99, - 46,80,97,116,104,69,110,116,114,121,70,105,110,100,101,114, - 41,32,115,104,111,117,108,100,32,109,111,100,105,102,121,32, - 77,111,100,117,108,101,83,112,101,99,32,105,110,115,116,97, - 110,99,101,115,46,10,10,32,32,32,32,78,41,3,218,6, - 111,114,105,103,105,110,218,12,108,111,97,100,101,114,95,115, - 116,97,116,101,218,10,105,115,95,112,97,99,107,97,103,101, - 99,3,0,0,0,3,0,0,0,6,0,0,0,2,0,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,62,0,0,0, + 116,0,124,1,124,0,131,2,125,2,124,1,116,1,106,2, + 107,6,114,50,116,1,106,2,124,1,25,0,125,3,116,3, + 124,2,124,3,131,2,1,0,116,1,106,2,124,1,25,0, + 83,0,116,4,124,2,131,1,83,0,100,1,83,0,41,2, + 122,128,76,111,97,100,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,109,111,100,117,108,101,32,105,110,116,111, + 32,115,121,115,46,109,111,100,117,108,101,115,32,97,110,100, + 32,114,101,116,117,114,110,32,105,116,46,10,10,32,32,32, + 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, + 32,108,111,97,100,101,114,46,101,120,101,99,95,109,111,100, + 117,108,101,32,105,110,115,116,101,97,100,46,10,10,32,32, + 32,32,78,41,5,218,16,115,112,101,99,95,102,114,111,109, + 95,108,111,97,100,101,114,114,15,0,0,0,218,7,109,111, + 100,117,108,101,115,218,5,95,101,120,101,99,218,5,95,108, + 111,97,100,41,4,114,30,0,0,0,114,81,0,0,0,218, + 4,115,112,101,99,218,6,109,111,100,117,108,101,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,17,95,108, + 111,97,100,95,109,111,100,117,108,101,95,115,104,105,109,253, + 0,0,0,115,12,0,0,0,0,6,10,1,10,1,10,1, + 10,1,10,2,114,97,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,8,0,0,0,67,0, + 0,0,115,226,0,0,0,116,0,124,0,100,1,100,0,131, + 3,125,1,116,1,124,1,100,2,131,2,114,56,122,12,124, + 1,160,2,124,0,161,1,87,0,83,0,4,0,116,3,107, + 10,114,54,1,0,1,0,1,0,89,0,110,2,88,0,122, + 10,124,0,106,4,125,2,87,0,110,20,4,0,116,5,107, + 10,114,86,1,0,1,0,1,0,89,0,110,18,88,0,124, + 2,100,0,107,9,114,104,116,6,124,2,131,1,83,0,122, + 10,124,0,106,7,125,3,87,0,110,24,4,0,116,5,107, + 10,114,138,1,0,1,0,1,0,100,3,125,3,89,0,110, + 2,88,0,122,10,124,0,106,8,125,4,87,0,110,58,4, + 0,116,5,107,10,114,208,1,0,1,0,1,0,124,1,100, + 0,107,8,114,188,100,4,160,9,124,3,161,1,6,0,89, + 0,83,0,100,5,160,9,124,3,124,1,161,2,6,0,89, + 0,83,0,89,0,110,14,88,0,100,6,160,9,124,3,124, + 4,161,2,83,0,100,0,83,0,41,7,78,218,10,95,95, + 108,111,97,100,101,114,95,95,218,11,109,111,100,117,108,101, + 95,114,101,112,114,250,1,63,250,13,60,109,111,100,117,108, + 101,32,123,33,114,125,62,250,20,60,109,111,100,117,108,101, + 32,123,33,114,125,32,40,123,33,114,125,41,62,250,23,60, + 109,111,100,117,108,101,32,123,33,114,125,32,102,114,111,109, + 32,123,33,114,125,62,41,10,114,6,0,0,0,114,4,0, + 0,0,114,99,0,0,0,218,9,69,120,99,101,112,116,105, + 111,110,218,8,95,95,115,112,101,99,95,95,218,14,65,116, + 116,114,105,98,117,116,101,69,114,114,111,114,218,22,95,109, + 111,100,117,108,101,95,114,101,112,114,95,102,114,111,109,95, + 115,112,101,99,114,1,0,0,0,218,8,95,95,102,105,108, + 101,95,95,114,45,0,0,0,41,5,114,96,0,0,0,218, + 6,108,111,97,100,101,114,114,95,0,0,0,114,17,0,0, + 0,218,8,102,105,108,101,110,97,109,101,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,12,95,109,111,100, + 117,108,101,95,114,101,112,114,13,1,0,0,115,46,0,0, + 0,0,2,12,1,10,4,2,1,12,1,14,1,6,1,2, + 1,10,1,14,1,6,2,8,1,8,4,2,1,10,1,14, + 1,10,1,2,1,10,1,14,1,8,1,14,2,22,2,114, + 111,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,114,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,2,100,2,100,3,156,3,100,4,100,5,132,2,90,4, + 100,6,100,7,132,0,90,5,100,8,100,9,132,0,90,6, + 101,7,100,10,100,11,132,0,131,1,90,8,101,8,106,9, + 100,12,100,11,132,0,131,1,90,8,101,7,100,13,100,14, + 132,0,131,1,90,10,101,7,100,15,100,16,132,0,131,1, + 90,11,101,11,106,9,100,17,100,16,132,0,131,1,90,11, + 100,2,83,0,41,18,218,10,77,111,100,117,108,101,83,112, + 101,99,97,208,5,0,0,84,104,101,32,115,112,101,99,105, + 102,105,99,97,116,105,111,110,32,102,111,114,32,97,32,109, + 111,100,117,108,101,44,32,117,115,101,100,32,102,111,114,32, + 108,111,97,100,105,110,103,46,10,10,32,32,32,32,65,32, + 109,111,100,117,108,101,39,115,32,115,112,101,99,32,105,115, + 32,116,104,101,32,115,111,117,114,99,101,32,102,111,114,32, + 105,110,102,111,114,109,97,116,105,111,110,32,97,98,111,117, + 116,32,116,104,101,32,109,111,100,117,108,101,46,32,32,70, + 111,114,10,32,32,32,32,100,97,116,97,32,97,115,115,111, + 99,105,97,116,101,100,32,119,105,116,104,32,116,104,101,32, + 109,111,100,117,108,101,44,32,105,110,99,108,117,100,105,110, + 103,32,115,111,117,114,99,101,44,32,117,115,101,32,116,104, + 101,32,115,112,101,99,39,115,10,32,32,32,32,108,111,97, + 100,101,114,46,10,10,32,32,32,32,96,110,97,109,101,96, + 32,105,115,32,116,104,101,32,97,98,115,111,108,117,116,101, + 32,110,97,109,101,32,111,102,32,116,104,101,32,109,111,100, + 117,108,101,46,32,32,96,108,111,97,100,101,114,96,32,105, + 115,32,116,104,101,32,108,111,97,100,101,114,10,32,32,32, + 32,116,111,32,117,115,101,32,119,104,101,110,32,108,111,97, + 100,105,110,103,32,116,104,101,32,109,111,100,117,108,101,46, + 32,32,96,112,97,114,101,110,116,96,32,105,115,32,116,104, + 101,32,110,97,109,101,32,111,102,32,116,104,101,10,32,32, + 32,32,112,97,99,107,97,103,101,32,116,104,101,32,109,111, + 100,117,108,101,32,105,115,32,105,110,46,32,32,84,104,101, + 32,112,97,114,101,110,116,32,105,115,32,100,101,114,105,118, + 101,100,32,102,114,111,109,32,116,104,101,32,110,97,109,101, + 46,10,10,32,32,32,32,96,105,115,95,112,97,99,107,97, + 103,101,96,32,100,101,116,101,114,109,105,110,101,115,32,105, + 102,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, + 99,111,110,115,105,100,101,114,101,100,32,97,32,112,97,99, + 107,97,103,101,32,111,114,10,32,32,32,32,110,111,116,46, + 32,32,79,110,32,109,111,100,117,108,101,115,32,116,104,105, + 115,32,105,115,32,114,101,102,108,101,99,116,101,100,32,98, + 121,32,116,104,101,32,96,95,95,112,97,116,104,95,95,96, + 32,97,116,116,114,105,98,117,116,101,46,10,10,32,32,32, + 32,96,111,114,105,103,105,110,96,32,105,115,32,116,104,101, + 32,115,112,101,99,105,102,105,99,32,108,111,99,97,116,105, + 111,110,32,117,115,101,100,32,98,121,32,116,104,101,32,108, + 111,97,100,101,114,32,102,114,111,109,32,119,104,105,99,104, + 32,116,111,10,32,32,32,32,108,111,97,100,32,116,104,101, + 32,109,111,100,117,108,101,44,32,105,102,32,116,104,97,116, + 32,105,110,102,111,114,109,97,116,105,111,110,32,105,115,32, + 97,118,97,105,108,97,98,108,101,46,32,32,87,104,101,110, + 32,102,105,108,101,110,97,109,101,32,105,115,10,32,32,32, + 32,115,101,116,44,32,111,114,105,103,105,110,32,119,105,108, + 108,32,109,97,116,99,104,46,10,10,32,32,32,32,96,104, + 97,115,95,108,111,99,97,116,105,111,110,96,32,105,110,100, + 105,99,97,116,101,115,32,116,104,97,116,32,97,32,115,112, + 101,99,39,115,32,34,111,114,105,103,105,110,34,32,114,101, + 102,108,101,99,116,115,32,97,32,108,111,99,97,116,105,111, + 110,46,10,32,32,32,32,87,104,101,110,32,116,104,105,115, + 32,105,115,32,84,114,117,101,44,32,96,95,95,102,105,108, + 101,95,95,96,32,97,116,116,114,105,98,117,116,101,32,111, + 102,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, + 115,101,116,46,10,10,32,32,32,32,96,99,97,99,104,101, + 100,96,32,105,115,32,116,104,101,32,108,111,99,97,116,105, + 111,110,32,111,102,32,116,104,101,32,99,97,99,104,101,100, + 32,98,121,116,101,99,111,100,101,32,102,105,108,101,44,32, + 105,102,32,97,110,121,46,32,32,73,116,10,32,32,32,32, + 99,111,114,114,101,115,112,111,110,100,115,32,116,111,32,116, + 104,101,32,96,95,95,99,97,99,104,101,100,95,95,96,32, + 97,116,116,114,105,98,117,116,101,46,10,10,32,32,32,32, + 96,115,117,98,109,111,100,117,108,101,95,115,101,97,114,99, + 104,95,108,111,99,97,116,105,111,110,115,96,32,105,115,32, + 116,104,101,32,115,101,113,117,101,110,99,101,32,111,102,32, + 112,97,116,104,32,101,110,116,114,105,101,115,32,116,111,10, + 32,32,32,32,115,101,97,114,99,104,32,119,104,101,110,32, + 105,109,112,111,114,116,105,110,103,32,115,117,98,109,111,100, + 117,108,101,115,46,32,32,73,102,32,115,101,116,44,32,105, + 115,95,112,97,99,107,97,103,101,32,115,104,111,117,108,100, + 32,98,101,10,32,32,32,32,84,114,117,101,45,45,97,110, + 100,32,70,97,108,115,101,32,111,116,104,101,114,119,105,115, + 101,46,10,10,32,32,32,32,80,97,99,107,97,103,101,115, + 32,97,114,101,32,115,105,109,112,108,121,32,109,111,100,117, + 108,101,115,32,116,104,97,116,32,40,109,97,121,41,32,104, + 97,118,101,32,115,117,98,109,111,100,117,108,101,115,46,32, + 32,73,102,32,97,32,115,112,101,99,10,32,32,32,32,104, + 97,115,32,97,32,110,111,110,45,78,111,110,101,32,118,97, + 108,117,101,32,105,110,32,96,115,117,98,109,111,100,117,108, + 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, + 110,115,96,44,32,116,104,101,32,105,109,112,111,114,116,10, + 32,32,32,32,115,121,115,116,101,109,32,119,105,108,108,32, + 99,111,110,115,105,100,101,114,32,109,111,100,117,108,101,115, + 32,108,111,97,100,101,100,32,102,114,111,109,32,116,104,101, + 32,115,112,101,99,32,97,115,32,112,97,99,107,97,103,101, + 115,46,10,10,32,32,32,32,79,110,108,121,32,102,105,110, + 100,101,114,115,32,40,115,101,101,32,105,109,112,111,114,116, + 108,105,98,46,97,98,99,46,77,101,116,97,80,97,116,104, + 70,105,110,100,101,114,32,97,110,100,10,32,32,32,32,105, + 109,112,111,114,116,108,105,98,46,97,98,99,46,80,97,116, + 104,69,110,116,114,121,70,105,110,100,101,114,41,32,115,104, + 111,117,108,100,32,109,111,100,105,102,121,32,77,111,100,117, + 108,101,83,112,101,99,32,105,110,115,116,97,110,99,101,115, + 46,10,10,32,32,32,32,78,41,3,218,6,111,114,105,103, + 105,110,218,12,108,111,97,100,101,114,95,115,116,97,116,101, + 218,10,105,115,95,112,97,99,107,97,103,101,99,3,0,0, + 0,0,0,0,0,3,0,0,0,6,0,0,0,2,0,0, 0,67,0,0,0,115,54,0,0,0,124,1,124,0,95,0, 124,2,124,0,95,1,124,3,124,0,95,2,124,4,124,0, 95,3,124,5,114,32,103,0,110,2,100,0,124,0,95,4, @@ -639,101 +647,103 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,86,1,0,0,115,14,0,0,0,0,2,6,1,6, 1,6,1,6,1,14,3,6,1,122,19,77,111,100,117,108, 101,83,112,101,99,46,95,95,105,110,105,116,95,95,99,1, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,67, - 0,0,0,115,102,0,0,0,100,1,160,0,124,0,106,1, - 161,1,100,2,160,0,124,0,106,2,161,1,103,2,125,1, - 124,0,106,3,100,0,107,9,114,52,124,1,160,4,100,3, - 160,0,124,0,106,3,161,1,161,1,1,0,124,0,106,5, - 100,0,107,9,114,80,124,1,160,4,100,4,160,0,124,0, - 106,5,161,1,161,1,1,0,100,5,160,0,124,0,106,6, - 106,7,100,6,160,8,124,1,161,1,161,2,83,0,41,7, - 78,122,9,110,97,109,101,61,123,33,114,125,122,11,108,111, - 97,100,101,114,61,123,33,114,125,122,11,111,114,105,103,105, - 110,61,123,33,114,125,122,29,115,117,98,109,111,100,117,108, - 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, - 110,115,61,123,125,122,6,123,125,40,123,125,41,122,2,44, - 32,41,9,114,45,0,0,0,114,17,0,0,0,114,109,0, - 0,0,114,113,0,0,0,218,6,97,112,112,101,110,100,114, - 117,0,0,0,218,9,95,95,99,108,97,115,115,95,95,114, - 1,0,0,0,218,4,106,111,105,110,41,2,114,30,0,0, - 0,114,55,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,48,0,0,0,98,1,0,0,115,20, - 0,0,0,0,1,10,1,10,255,4,2,10,1,18,1,10, - 1,8,1,4,255,6,2,122,19,77,111,100,117,108,101,83, - 112,101,99,46,95,95,114,101,112,114,95,95,99,2,0,0, - 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, - 0,115,114,0,0,0,124,0,106,0,125,2,122,76,124,0, - 106,1,124,1,106,1,107,2,111,76,124,0,106,2,124,1, - 106,2,107,2,111,76,124,0,106,3,124,1,106,3,107,2, - 111,76,124,2,124,1,106,0,107,2,111,76,124,0,106,4, - 124,1,106,4,107,2,111,76,124,0,106,5,124,1,106,5, - 107,2,87,0,83,0,87,0,110,26,4,0,116,6,107,10, - 114,108,1,0,1,0,1,0,89,0,100,1,83,0,89,0, - 110,2,88,0,100,0,83,0,114,116,0,0,0,41,7,114, - 117,0,0,0,114,17,0,0,0,114,109,0,0,0,114,113, - 0,0,0,218,6,99,97,99,104,101,100,218,12,104,97,115, - 95,108,111,99,97,116,105,111,110,114,106,0,0,0,41,3, - 114,30,0,0,0,90,5,111,116,104,101,114,90,4,115,109, - 115,108,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,6,95,95,101,113,95,95,108,1,0,0,115,30,0, - 0,0,0,1,6,1,2,1,12,1,10,255,2,2,10,254, - 2,3,8,253,2,4,10,252,2,5,10,251,8,6,14,1, - 122,17,77,111,100,117,108,101,83,112,101,99,46,95,95,101, - 113,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,115,58,0,0,0,124,0,106, - 0,100,0,107,8,114,52,124,0,106,1,100,0,107,9,114, - 52,124,0,106,2,114,52,116,3,100,0,107,8,114,38,116, - 4,130,1,116,3,160,5,124,0,106,1,161,1,124,0,95, - 0,124,0,106,0,83,0,114,13,0,0,0,41,6,114,119, - 0,0,0,114,113,0,0,0,114,118,0,0,0,218,19,95, - 98,111,111,116,115,116,114,97,112,95,101,120,116,101,114,110, - 97,108,218,19,78,111,116,73,109,112,108,101,109,101,110,116, - 101,100,69,114,114,111,114,90,11,95,103,101,116,95,99,97, - 99,104,101,100,114,47,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,123,0,0,0,120,1,0, - 0,115,12,0,0,0,0,2,10,1,16,1,8,1,4,1, - 14,1,122,17,77,111,100,117,108,101,83,112,101,99,46,99, - 97,99,104,101,100,99,2,0,0,0,0,0,0,0,2,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,6, + 0,0,0,67,0,0,0,115,102,0,0,0,100,1,160,0, + 124,0,106,1,161,1,100,2,160,0,124,0,106,2,161,1, + 103,2,125,1,124,0,106,3,100,0,107,9,114,52,124,1, + 160,4,100,3,160,0,124,0,106,3,161,1,161,1,1,0, + 124,0,106,5,100,0,107,9,114,80,124,1,160,4,100,4, + 160,0,124,0,106,5,161,1,161,1,1,0,100,5,160,0, + 124,0,106,6,106,7,100,6,160,8,124,1,161,1,161,2, + 83,0,41,7,78,122,9,110,97,109,101,61,123,33,114,125, + 122,11,108,111,97,100,101,114,61,123,33,114,125,122,11,111, + 114,105,103,105,110,61,123,33,114,125,122,29,115,117,98,109, + 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, + 97,116,105,111,110,115,61,123,125,122,6,123,125,40,123,125, + 41,122,2,44,32,41,9,114,45,0,0,0,114,17,0,0, + 0,114,109,0,0,0,114,113,0,0,0,218,6,97,112,112, + 101,110,100,114,117,0,0,0,218,9,95,95,99,108,97,115, + 115,95,95,114,1,0,0,0,218,4,106,111,105,110,41,2, + 114,30,0,0,0,114,55,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,48,0,0,0,98,1, + 0,0,115,20,0,0,0,0,1,10,1,10,255,4,2,10, + 1,18,1,10,1,8,1,4,255,6,2,122,19,77,111,100, + 117,108,101,83,112,101,99,46,95,95,114,101,112,114,95,95, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,114,0,0,0,124,0, + 106,0,125,2,122,76,124,0,106,1,124,1,106,1,107,2, + 111,76,124,0,106,2,124,1,106,2,107,2,111,76,124,0, + 106,3,124,1,106,3,107,2,111,76,124,2,124,1,106,0, + 107,2,111,76,124,0,106,4,124,1,106,4,107,2,111,76, + 124,0,106,5,124,1,106,5,107,2,87,0,83,0,87,0, + 110,26,4,0,116,6,107,10,114,108,1,0,1,0,1,0, + 89,0,100,1,83,0,89,0,110,2,88,0,100,0,83,0, + 114,116,0,0,0,41,7,114,117,0,0,0,114,17,0,0, + 0,114,109,0,0,0,114,113,0,0,0,218,6,99,97,99, + 104,101,100,218,12,104,97,115,95,108,111,99,97,116,105,111, + 110,114,106,0,0,0,41,3,114,30,0,0,0,90,5,111, + 116,104,101,114,90,4,115,109,115,108,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,6,95,95,101,113,95, + 95,108,1,0,0,115,30,0,0,0,0,1,6,1,2,1, + 12,1,10,255,2,2,10,254,2,3,8,253,2,4,10,252, + 2,5,10,251,8,6,14,1,122,17,77,111,100,117,108,101, + 83,112,101,99,46,95,95,101,113,95,95,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, + 67,0,0,0,115,58,0,0,0,124,0,106,0,100,0,107, + 8,114,52,124,0,106,1,100,0,107,9,114,52,124,0,106, + 2,114,52,116,3,100,0,107,8,114,38,116,4,130,1,116, + 3,160,5,124,0,106,1,161,1,124,0,95,0,124,0,106, + 0,83,0,114,13,0,0,0,41,6,114,119,0,0,0,114, + 113,0,0,0,114,118,0,0,0,218,19,95,98,111,111,116, + 115,116,114,97,112,95,101,120,116,101,114,110,97,108,218,19, + 78,111,116,73,109,112,108,101,109,101,110,116,101,100,69,114, + 114,111,114,90,11,95,103,101,116,95,99,97,99,104,101,100, + 114,47,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,123,0,0,0,120,1,0,0,115,12,0, + 0,0,0,2,10,1,16,1,8,1,4,1,14,1,122,17, + 77,111,100,117,108,101,83,112,101,99,46,99,97,99,104,101, + 100,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, 0,0,2,0,0,0,67,0,0,0,115,10,0,0,0,124, 1,124,0,95,0,100,0,83,0,114,13,0,0,0,41,1, 114,119,0,0,0,41,2,114,30,0,0,0,114,123,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, 114,123,0,0,0,129,1,0,0,115,2,0,0,0,0,2, - 99,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,36,0,0,0,124,0,106,0,100,1, - 107,8,114,26,124,0,106,1,160,2,100,2,161,1,100,3, - 25,0,83,0,124,0,106,1,83,0,100,1,83,0,41,4, - 122,32,84,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,32,109,111,100,117,108,101,39,115,32,112,97,114,101,110, - 116,46,78,218,1,46,114,22,0,0,0,41,3,114,117,0, - 0,0,114,17,0,0,0,218,10,114,112,97,114,116,105,116, - 105,111,110,114,47,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,6,112,97,114,101,110,116,133, - 1,0,0,115,6,0,0,0,0,3,10,1,16,2,122,17, - 77,111,100,117,108,101,83,112,101,99,46,112,97,114,101,110, - 116,99,1,0,0,0,0,0,0,0,1,0,0,0,1,0, - 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, - 0,114,13,0,0,0,41,1,114,118,0,0,0,114,47,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,124,0,0,0,141,1,0,0,115,2,0,0,0,0, - 2,122,23,77,111,100,117,108,101,83,112,101,99,46,104,97, - 115,95,108,111,99,97,116,105,111,110,99,2,0,0,0,0, - 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, - 14,0,0,0,116,0,124,1,131,1,124,0,95,1,100,0, - 83,0,114,13,0,0,0,41,2,218,4,98,111,111,108,114, - 118,0,0,0,41,2,114,30,0,0,0,218,5,118,97,108, - 117,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,124,0,0,0,145,1,0,0,115,2,0,0,0,0, - 2,41,12,114,1,0,0,0,114,0,0,0,0,114,2,0, - 0,0,114,3,0,0,0,114,31,0,0,0,114,48,0,0, - 0,114,125,0,0,0,218,8,112,114,111,112,101,114,116,121, - 114,123,0,0,0,218,6,115,101,116,116,101,114,114,130,0, - 0,0,114,124,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,112,0,0,0, - 49,1,0,0,115,32,0,0,0,8,1,4,36,4,1,2, - 255,12,12,8,10,8,12,2,1,10,8,4,1,10,3,2, - 1,10,7,2,1,10,3,4,1,114,112,0,0,0,169,2, - 114,113,0,0,0,114,115,0,0,0,99,2,0,0,0,2, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,115,36,0,0,0,124,0, + 106,0,100,1,107,8,114,26,124,0,106,1,160,2,100,2, + 161,1,100,3,25,0,83,0,124,0,106,1,83,0,100,1, + 83,0,41,4,122,32,84,104,101,32,110,97,109,101,32,111, + 102,32,116,104,101,32,109,111,100,117,108,101,39,115,32,112, + 97,114,101,110,116,46,78,218,1,46,114,22,0,0,0,41, + 3,114,117,0,0,0,114,17,0,0,0,218,10,114,112,97, + 114,116,105,116,105,111,110,114,47,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,6,112,97,114, + 101,110,116,133,1,0,0,115,6,0,0,0,0,3,10,1, + 16,2,122,17,77,111,100,117,108,101,83,112,101,99,46,112, + 97,114,101,110,116,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,1,0,0,0,67,0,0,0,115,6, + 0,0,0,124,0,106,0,83,0,114,13,0,0,0,41,1, + 114,118,0,0,0,114,47,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,124,0,0,0,141,1, + 0,0,115,2,0,0,0,0,2,122,23,77,111,100,117,108, + 101,83,112,101,99,46,104,97,115,95,108,111,99,97,116,105, + 111,110,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,2,0,0,0,67,0,0,0,115,14,0,0,0, + 116,0,124,1,131,1,124,0,95,1,100,0,83,0,114,13, + 0,0,0,41,2,218,4,98,111,111,108,114,118,0,0,0, + 41,2,114,30,0,0,0,218,5,118,97,108,117,101,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,124,0, + 0,0,145,1,0,0,115,2,0,0,0,0,2,41,12,114, + 1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3, + 0,0,0,114,31,0,0,0,114,48,0,0,0,114,125,0, + 0,0,218,8,112,114,111,112,101,114,116,121,114,123,0,0, + 0,218,6,115,101,116,116,101,114,114,130,0,0,0,114,124, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,112,0,0,0,49,1,0,0, + 115,32,0,0,0,8,1,4,36,4,1,2,255,12,12,8, + 10,8,12,2,1,10,8,4,1,10,3,2,1,10,7,2, + 1,10,3,4,1,114,112,0,0,0,169,2,114,113,0,0, + 0,114,115,0,0,0,99,2,0,0,0,0,0,0,0,2, 0,0,0,6,0,0,0,8,0,0,0,67,0,0,0,115, 154,0,0,0,116,0,124,1,100,1,131,2,114,74,116,1, 100,2,107,8,114,22,116,2,130,1,116,1,106,3,125,4, @@ -761,121 +771,122 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 91,0,0,0,150,1,0,0,115,36,0,0,0,0,2,10, 1,8,1,4,1,6,2,8,1,12,1,12,1,6,1,2, 255,6,3,8,1,10,1,2,1,14,1,14,1,12,3,4, - 2,114,91,0,0,0,99,3,0,0,0,0,0,0,0,8, - 0,0,0,8,0,0,0,67,0,0,0,115,56,1,0,0, - 122,10,124,0,106,0,125,3,87,0,110,20,4,0,116,1, - 107,10,114,30,1,0,1,0,1,0,89,0,110,14,88,0, - 124,3,100,0,107,9,114,44,124,3,83,0,124,0,106,2, - 125,4,124,1,100,0,107,8,114,90,122,10,124,0,106,3, - 125,1,87,0,110,20,4,0,116,1,107,10,114,88,1,0, - 1,0,1,0,89,0,110,2,88,0,122,10,124,0,106,4, - 125,5,87,0,110,24,4,0,116,1,107,10,114,124,1,0, - 1,0,1,0,100,0,125,5,89,0,110,2,88,0,124,2, - 100,0,107,8,114,184,124,5,100,0,107,8,114,180,122,10, - 124,1,106,5,125,2,87,0,113,184,4,0,116,1,107,10, - 114,176,1,0,1,0,1,0,100,0,125,2,89,0,113,184, - 88,0,110,4,124,5,125,2,122,10,124,0,106,6,125,6, - 87,0,110,24,4,0,116,1,107,10,114,218,1,0,1,0, - 1,0,100,0,125,6,89,0,110,2,88,0,122,14,116,7, - 124,0,106,8,131,1,125,7,87,0,110,26,4,0,116,1, - 107,10,144,1,114,4,1,0,1,0,1,0,100,0,125,7, - 89,0,110,2,88,0,116,9,124,4,124,1,124,2,100,1, - 141,3,125,3,124,5,100,0,107,8,144,1,114,34,100,2, - 110,2,100,3,124,3,95,10,124,6,124,3,95,11,124,7, - 124,3,95,12,124,3,83,0,41,4,78,169,1,114,113,0, - 0,0,70,84,41,13,114,105,0,0,0,114,106,0,0,0, - 114,1,0,0,0,114,98,0,0,0,114,108,0,0,0,218, - 7,95,79,82,73,71,73,78,218,10,95,95,99,97,99,104, - 101,100,95,95,218,4,108,105,115,116,218,8,95,95,112,97, - 116,104,95,95,114,112,0,0,0,114,118,0,0,0,114,123, - 0,0,0,114,117,0,0,0,41,8,114,96,0,0,0,114, - 109,0,0,0,114,113,0,0,0,114,95,0,0,0,114,17, - 0,0,0,90,8,108,111,99,97,116,105,111,110,114,123,0, - 0,0,114,117,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,17,95,115,112,101,99,95,102,114, - 111,109,95,109,111,100,117,108,101,176,1,0,0,115,72,0, - 0,0,0,2,2,1,10,1,14,1,6,2,8,1,4,2, - 6,1,8,1,2,1,10,1,14,2,6,1,2,1,10,1, - 14,1,10,1,8,1,8,1,2,1,10,1,14,1,12,2, - 4,1,2,1,10,1,14,1,10,1,2,1,14,1,16,1, - 10,2,14,1,20,1,6,1,6,1,114,142,0,0,0,70, - 169,1,218,8,111,118,101,114,114,105,100,101,99,2,0,0, - 0,1,0,0,0,5,0,0,0,8,0,0,0,67,0,0, - 0,115,226,1,0,0,124,2,115,20,116,0,124,1,100,1, - 100,0,131,3,100,0,107,8,114,54,122,12,124,0,106,1, - 124,1,95,2,87,0,110,20,4,0,116,3,107,10,114,52, - 1,0,1,0,1,0,89,0,110,2,88,0,124,2,115,74, - 116,0,124,1,100,2,100,0,131,3,100,0,107,8,114,178, - 124,0,106,4,125,3,124,3,100,0,107,8,114,146,124,0, - 106,5,100,0,107,9,114,146,116,6,100,0,107,8,114,110, - 116,7,130,1,116,6,106,8,125,4,124,4,160,9,124,4, - 161,1,125,3,124,0,106,5,124,3,95,10,124,3,124,0, - 95,4,100,0,124,1,95,11,122,10,124,3,124,1,95,12, - 87,0,110,20,4,0,116,3,107,10,114,176,1,0,1,0, - 1,0,89,0,110,2,88,0,124,2,115,198,116,0,124,1, - 100,3,100,0,131,3,100,0,107,8,114,232,122,12,124,0, - 106,13,124,1,95,14,87,0,110,20,4,0,116,3,107,10, - 114,230,1,0,1,0,1,0,89,0,110,2,88,0,122,10, - 124,0,124,1,95,15,87,0,110,22,4,0,116,3,107,10, - 144,1,114,8,1,0,1,0,1,0,89,0,110,2,88,0, - 124,2,144,1,115,34,116,0,124,1,100,4,100,0,131,3, - 100,0,107,8,144,1,114,82,124,0,106,5,100,0,107,9, - 144,1,114,82,122,12,124,0,106,5,124,1,95,16,87,0, - 110,22,4,0,116,3,107,10,144,1,114,80,1,0,1,0, - 1,0,89,0,110,2,88,0,124,0,106,17,144,1,114,222, - 124,2,144,1,115,114,116,0,124,1,100,5,100,0,131,3, - 100,0,107,8,144,1,114,150,122,12,124,0,106,18,124,1, - 95,11,87,0,110,22,4,0,116,3,107,10,144,1,114,148, - 1,0,1,0,1,0,89,0,110,2,88,0,124,2,144,1, - 115,174,116,0,124,1,100,6,100,0,131,3,100,0,107,8, - 144,1,114,222,124,0,106,19,100,0,107,9,144,1,114,222, - 122,12,124,0,106,19,124,1,95,20,87,0,110,22,4,0, - 116,3,107,10,144,1,114,220,1,0,1,0,1,0,89,0, - 110,2,88,0,124,1,83,0,41,7,78,114,1,0,0,0, - 114,98,0,0,0,218,11,95,95,112,97,99,107,97,103,101, - 95,95,114,141,0,0,0,114,108,0,0,0,114,139,0,0, - 0,41,21,114,6,0,0,0,114,17,0,0,0,114,1,0, - 0,0,114,106,0,0,0,114,109,0,0,0,114,117,0,0, - 0,114,126,0,0,0,114,127,0,0,0,218,16,95,78,97, - 109,101,115,112,97,99,101,76,111,97,100,101,114,218,7,95, - 95,110,101,119,95,95,90,5,95,112,97,116,104,114,108,0, - 0,0,114,98,0,0,0,114,130,0,0,0,114,145,0,0, - 0,114,105,0,0,0,114,141,0,0,0,114,124,0,0,0, - 114,113,0,0,0,114,123,0,0,0,114,139,0,0,0,41, - 5,114,95,0,0,0,114,96,0,0,0,114,144,0,0,0, - 114,109,0,0,0,114,146,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,18,95,105,110,105,116, - 95,109,111,100,117,108,101,95,97,116,116,114,115,221,1,0, - 0,115,96,0,0,0,0,4,20,1,2,1,12,1,14,1, - 6,2,20,1,6,1,8,2,10,1,8,1,4,1,6,2, - 10,1,8,1,6,11,6,1,2,1,10,1,14,1,6,2, - 20,1,2,1,12,1,14,1,6,2,2,1,10,1,16,1, - 6,2,24,1,12,1,2,1,12,1,16,1,6,2,8,1, - 24,1,2,1,12,1,16,1,6,2,24,1,12,1,2,1, - 12,1,16,1,6,1,114,148,0,0,0,99,1,0,0,0, - 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, - 115,82,0,0,0,100,1,125,1,116,0,124,0,106,1,100, - 2,131,2,114,30,124,0,106,1,160,2,124,0,161,1,125, - 1,110,20,116,0,124,0,106,1,100,3,131,2,114,50,116, - 3,100,4,131,1,130,1,124,1,100,1,107,8,114,68,116, - 4,124,0,106,5,131,1,125,1,116,6,124,0,124,1,131, - 2,1,0,124,1,83,0,41,5,122,43,67,114,101,97,116, - 101,32,97,32,109,111,100,117,108,101,32,98,97,115,101,100, - 32,111,110,32,116,104,101,32,112,114,111,118,105,100,101,100, - 32,115,112,101,99,46,78,218,13,99,114,101,97,116,101,95, - 109,111,100,117,108,101,218,11,101,120,101,99,95,109,111,100, - 117,108,101,122,66,108,111,97,100,101,114,115,32,116,104,97, - 116,32,100,101,102,105,110,101,32,101,120,101,99,95,109,111, - 100,117,108,101,40,41,32,109,117,115,116,32,97,108,115,111, - 32,100,101,102,105,110,101,32,99,114,101,97,116,101,95,109, - 111,100,117,108,101,40,41,41,7,114,4,0,0,0,114,109, - 0,0,0,114,149,0,0,0,114,79,0,0,0,114,18,0, - 0,0,114,17,0,0,0,114,148,0,0,0,169,2,114,95, - 0,0,0,114,96,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,16,109,111,100,117,108,101,95, - 102,114,111,109,95,115,112,101,99,37,2,0,0,115,18,0, - 0,0,0,3,4,1,12,3,14,1,12,1,8,2,8,1, - 10,1,10,1,114,152,0,0,0,99,1,0,0,0,0,0, + 2,114,91,0,0,0,99,3,0,0,0,0,0,0,0,0, + 0,0,0,8,0,0,0,8,0,0,0,67,0,0,0,115, + 56,1,0,0,122,10,124,0,106,0,125,3,87,0,110,20, + 4,0,116,1,107,10,114,30,1,0,1,0,1,0,89,0, + 110,14,88,0,124,3,100,0,107,9,114,44,124,3,83,0, + 124,0,106,2,125,4,124,1,100,0,107,8,114,90,122,10, + 124,0,106,3,125,1,87,0,110,20,4,0,116,1,107,10, + 114,88,1,0,1,0,1,0,89,0,110,2,88,0,122,10, + 124,0,106,4,125,5,87,0,110,24,4,0,116,1,107,10, + 114,124,1,0,1,0,1,0,100,0,125,5,89,0,110,2, + 88,0,124,2,100,0,107,8,114,184,124,5,100,0,107,8, + 114,180,122,10,124,1,106,5,125,2,87,0,113,184,4,0, + 116,1,107,10,114,176,1,0,1,0,1,0,100,0,125,2, + 89,0,113,184,88,0,110,4,124,5,125,2,122,10,124,0, + 106,6,125,6,87,0,110,24,4,0,116,1,107,10,114,218, + 1,0,1,0,1,0,100,0,125,6,89,0,110,2,88,0, + 122,14,116,7,124,0,106,8,131,1,125,7,87,0,110,26, + 4,0,116,1,107,10,144,1,114,4,1,0,1,0,1,0, + 100,0,125,7,89,0,110,2,88,0,116,9,124,4,124,1, + 124,2,100,1,141,3,125,3,124,5,100,0,107,8,144,1, + 114,34,100,2,110,2,100,3,124,3,95,10,124,6,124,3, + 95,11,124,7,124,3,95,12,124,3,83,0,41,4,78,169, + 1,114,113,0,0,0,70,84,41,13,114,105,0,0,0,114, + 106,0,0,0,114,1,0,0,0,114,98,0,0,0,114,108, + 0,0,0,218,7,95,79,82,73,71,73,78,218,10,95,95, + 99,97,99,104,101,100,95,95,218,4,108,105,115,116,218,8, + 95,95,112,97,116,104,95,95,114,112,0,0,0,114,118,0, + 0,0,114,123,0,0,0,114,117,0,0,0,41,8,114,96, + 0,0,0,114,109,0,0,0,114,113,0,0,0,114,95,0, + 0,0,114,17,0,0,0,90,8,108,111,99,97,116,105,111, + 110,114,123,0,0,0,114,117,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,17,95,115,112,101, + 99,95,102,114,111,109,95,109,111,100,117,108,101,176,1,0, + 0,115,72,0,0,0,0,2,2,1,10,1,14,1,6,2, + 8,1,4,2,6,1,8,1,2,1,10,1,14,2,6,1, + 2,1,10,1,14,1,10,1,8,1,8,1,2,1,10,1, + 14,1,12,2,4,1,2,1,10,1,14,1,10,1,2,1, + 14,1,16,1,10,2,14,1,20,1,6,1,6,1,114,142, + 0,0,0,70,169,1,218,8,111,118,101,114,114,105,100,101, + 99,2,0,0,0,0,0,0,0,1,0,0,0,5,0,0, + 0,8,0,0,0,67,0,0,0,115,226,1,0,0,124,2, + 115,20,116,0,124,1,100,1,100,0,131,3,100,0,107,8, + 114,54,122,12,124,0,106,1,124,1,95,2,87,0,110,20, + 4,0,116,3,107,10,114,52,1,0,1,0,1,0,89,0, + 110,2,88,0,124,2,115,74,116,0,124,1,100,2,100,0, + 131,3,100,0,107,8,114,178,124,0,106,4,125,3,124,3, + 100,0,107,8,114,146,124,0,106,5,100,0,107,9,114,146, + 116,6,100,0,107,8,114,110,116,7,130,1,116,6,106,8, + 125,4,124,4,160,9,124,4,161,1,125,3,124,0,106,5, + 124,3,95,10,124,3,124,0,95,4,100,0,124,1,95,11, + 122,10,124,3,124,1,95,12,87,0,110,20,4,0,116,3, + 107,10,114,176,1,0,1,0,1,0,89,0,110,2,88,0, + 124,2,115,198,116,0,124,1,100,3,100,0,131,3,100,0, + 107,8,114,232,122,12,124,0,106,13,124,1,95,14,87,0, + 110,20,4,0,116,3,107,10,114,230,1,0,1,0,1,0, + 89,0,110,2,88,0,122,10,124,0,124,1,95,15,87,0, + 110,22,4,0,116,3,107,10,144,1,114,8,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,144,1,115,34,116,0, + 124,1,100,4,100,0,131,3,100,0,107,8,144,1,114,82, + 124,0,106,5,100,0,107,9,144,1,114,82,122,12,124,0, + 106,5,124,1,95,16,87,0,110,22,4,0,116,3,107,10, + 144,1,114,80,1,0,1,0,1,0,89,0,110,2,88,0, + 124,0,106,17,144,1,114,222,124,2,144,1,115,114,116,0, + 124,1,100,5,100,0,131,3,100,0,107,8,144,1,114,150, + 122,12,124,0,106,18,124,1,95,11,87,0,110,22,4,0, + 116,3,107,10,144,1,114,148,1,0,1,0,1,0,89,0, + 110,2,88,0,124,2,144,1,115,174,116,0,124,1,100,6, + 100,0,131,3,100,0,107,8,144,1,114,222,124,0,106,19, + 100,0,107,9,144,1,114,222,122,12,124,0,106,19,124,1, + 95,20,87,0,110,22,4,0,116,3,107,10,144,1,114,220, + 1,0,1,0,1,0,89,0,110,2,88,0,124,1,83,0, + 41,7,78,114,1,0,0,0,114,98,0,0,0,218,11,95, + 95,112,97,99,107,97,103,101,95,95,114,141,0,0,0,114, + 108,0,0,0,114,139,0,0,0,41,21,114,6,0,0,0, + 114,17,0,0,0,114,1,0,0,0,114,106,0,0,0,114, + 109,0,0,0,114,117,0,0,0,114,126,0,0,0,114,127, + 0,0,0,218,16,95,78,97,109,101,115,112,97,99,101,76, + 111,97,100,101,114,218,7,95,95,110,101,119,95,95,90,5, + 95,112,97,116,104,114,108,0,0,0,114,98,0,0,0,114, + 130,0,0,0,114,145,0,0,0,114,105,0,0,0,114,141, + 0,0,0,114,124,0,0,0,114,113,0,0,0,114,123,0, + 0,0,114,139,0,0,0,41,5,114,95,0,0,0,114,96, + 0,0,0,114,144,0,0,0,114,109,0,0,0,114,146,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,18,95,105,110,105,116,95,109,111,100,117,108,101,95, + 97,116,116,114,115,221,1,0,0,115,96,0,0,0,0,4, + 20,1,2,1,12,1,14,1,6,2,20,1,6,1,8,2, + 10,1,8,1,4,1,6,2,10,1,8,1,6,11,6,1, + 2,1,10,1,14,1,6,2,20,1,2,1,12,1,14,1, + 6,2,2,1,10,1,16,1,6,2,24,1,12,1,2,1, + 12,1,16,1,6,2,8,1,24,1,2,1,12,1,16,1, + 6,2,24,1,12,1,2,1,12,1,16,1,6,1,114,148, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,67,0,0,0,115,82,0,0, + 0,100,1,125,1,116,0,124,0,106,1,100,2,131,2,114, + 30,124,0,106,1,160,2,124,0,161,1,125,1,110,20,116, + 0,124,0,106,1,100,3,131,2,114,50,116,3,100,4,131, + 1,130,1,124,1,100,1,107,8,114,68,116,4,124,0,106, + 5,131,1,125,1,116,6,124,0,124,1,131,2,1,0,124, + 1,83,0,41,5,122,43,67,114,101,97,116,101,32,97,32, + 109,111,100,117,108,101,32,98,97,115,101,100,32,111,110,32, + 116,104,101,32,112,114,111,118,105,100,101,100,32,115,112,101, + 99,46,78,218,13,99,114,101,97,116,101,95,109,111,100,117, + 108,101,218,11,101,120,101,99,95,109,111,100,117,108,101,122, + 66,108,111,97,100,101,114,115,32,116,104,97,116,32,100,101, + 102,105,110,101,32,101,120,101,99,95,109,111,100,117,108,101, + 40,41,32,109,117,115,116,32,97,108,115,111,32,100,101,102, + 105,110,101,32,99,114,101,97,116,101,95,109,111,100,117,108, + 101,40,41,41,7,114,4,0,0,0,114,109,0,0,0,114, + 149,0,0,0,114,79,0,0,0,114,18,0,0,0,114,17, + 0,0,0,114,148,0,0,0,169,2,114,95,0,0,0,114, + 96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,16,109,111,100,117,108,101,95,102,114,111,109, + 95,115,112,101,99,37,2,0,0,115,18,0,0,0,0,3, + 4,1,12,3,14,1,12,1,8,2,8,1,10,1,10,1, + 114,152,0,0,0,99,1,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,106, 0,0,0,124,0,106,0,100,1,107,8,114,14,100,2,110, 4,124,0,106,0,125,1,124,0,106,1,100,1,107,8,114, @@ -895,102 +906,103 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,114,11,0,0,0,114,107,0,0,0,54,2,0,0,115, 16,0,0,0,0,3,20,1,10,1,10,1,10,2,16,2, 6,1,14,2,114,107,0,0,0,99,2,0,0,0,0,0, - 0,0,4,0,0,0,10,0,0,0,67,0,0,0,115,204, - 0,0,0,124,0,106,0,125,2,116,1,124,2,131,1,143, - 180,1,0,116,2,106,3,160,4,124,2,161,1,124,1,107, - 9,114,54,100,1,160,5,124,2,161,1,125,3,116,6,124, - 3,124,2,100,2,141,2,130,1,122,106,124,0,106,7,100, - 3,107,8,114,106,124,0,106,8,100,3,107,8,114,90,116, - 6,100,4,124,0,106,0,100,2,141,2,130,1,116,9,124, - 0,124,1,100,5,100,6,141,3,1,0,110,52,116,9,124, - 0,124,1,100,5,100,6,141,3,1,0,116,10,124,0,106, - 7,100,7,131,2,115,146,124,0,106,7,160,11,124,2,161, - 1,1,0,110,12,124,0,106,7,160,12,124,1,161,1,1, - 0,87,0,53,0,116,2,106,3,160,13,124,0,106,0,161, - 1,125,1,124,1,116,2,106,3,124,0,106,0,60,0,88, - 0,87,0,53,0,81,0,82,0,88,0,124,1,83,0,41, - 8,122,70,69,120,101,99,117,116,101,32,116,104,101,32,115, - 112,101,99,39,115,32,115,112,101,99,105,102,105,101,100,32, - 109,111,100,117,108,101,32,105,110,32,97,110,32,101,120,105, - 115,116,105,110,103,32,109,111,100,117,108,101,39,115,32,110, - 97,109,101,115,112,97,99,101,46,122,30,109,111,100,117,108, - 101,32,123,33,114,125,32,110,111,116,32,105,110,32,115,121, - 115,46,109,111,100,117,108,101,115,114,16,0,0,0,78,250, - 14,109,105,115,115,105,110,103,32,108,111,97,100,101,114,84, - 114,143,0,0,0,114,150,0,0,0,41,14,114,17,0,0, - 0,114,50,0,0,0,114,15,0,0,0,114,92,0,0,0, - 114,34,0,0,0,114,45,0,0,0,114,79,0,0,0,114, - 109,0,0,0,114,117,0,0,0,114,148,0,0,0,114,4, - 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, - 114,150,0,0,0,218,3,112,111,112,41,4,114,95,0,0, - 0,114,96,0,0,0,114,17,0,0,0,218,3,109,115,103, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 93,0,0,0,71,2,0,0,115,34,0,0,0,0,2,6, - 1,10,1,16,1,10,1,12,1,2,1,10,1,10,1,14, - 2,16,2,14,1,12,4,14,2,16,4,14,1,24,1,114, - 93,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, - 0,8,0,0,0,67,0,0,0,115,26,1,0,0,122,18, - 124,0,106,0,160,1,124,0,106,2,161,1,1,0,87,0, - 110,52,1,0,1,0,1,0,124,0,106,2,116,3,106,4, - 107,6,114,64,116,3,106,4,160,5,124,0,106,2,161,1, - 125,1,124,1,116,3,106,4,124,0,106,2,60,0,130,0, - 89,0,110,2,88,0,116,3,106,4,160,5,124,0,106,2, - 161,1,125,1,124,1,116,3,106,4,124,0,106,2,60,0, - 116,6,124,1,100,1,100,0,131,3,100,0,107,8,114,148, - 122,12,124,0,106,0,124,1,95,7,87,0,110,20,4,0, - 116,8,107,10,114,146,1,0,1,0,1,0,89,0,110,2, - 88,0,116,6,124,1,100,2,100,0,131,3,100,0,107,8, - 114,226,122,40,124,1,106,9,124,1,95,10,116,11,124,1, - 100,3,131,2,115,202,124,0,106,2,160,12,100,4,161,1, - 100,5,25,0,124,1,95,10,87,0,110,20,4,0,116,8, - 107,10,114,224,1,0,1,0,1,0,89,0,110,2,88,0, - 116,6,124,1,100,6,100,0,131,3,100,0,107,8,144,1, - 114,22,122,10,124,0,124,1,95,13,87,0,110,22,4,0, - 116,8,107,10,144,1,114,20,1,0,1,0,1,0,89,0, - 110,2,88,0,124,1,83,0,41,7,78,114,98,0,0,0, - 114,145,0,0,0,114,141,0,0,0,114,128,0,0,0,114, - 22,0,0,0,114,105,0,0,0,41,14,114,109,0,0,0, - 114,155,0,0,0,114,17,0,0,0,114,15,0,0,0,114, - 92,0,0,0,114,156,0,0,0,114,6,0,0,0,114,98, - 0,0,0,114,106,0,0,0,114,1,0,0,0,114,145,0, - 0,0,114,4,0,0,0,114,129,0,0,0,114,105,0,0, - 0,114,151,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99, - 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, - 101,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6, - 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2, - 1,12,1,14,1,6,1,16,1,2,4,8,1,10,1,22, - 1,14,1,6,1,18,1,2,1,10,1,16,1,6,1,114, - 158,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, - 0,11,0,0,0,67,0,0,0,115,220,0,0,0,124,0, - 106,0,100,0,107,9,114,30,116,1,124,0,106,0,100,1, - 131,2,115,30,116,2,124,0,131,1,83,0,116,3,124,0, - 131,1,125,1,100,2,124,0,95,4,122,162,124,1,116,5, - 106,6,124,0,106,7,60,0,122,52,124,0,106,0,100,0, - 107,8,114,96,124,0,106,8,100,0,107,8,114,108,116,9, - 100,3,124,0,106,7,100,4,141,2,130,1,110,12,124,0, - 106,0,160,10,124,1,161,1,1,0,87,0,110,50,1,0, - 1,0,1,0,122,14,116,5,106,6,124,0,106,7,61,0, - 87,0,110,20,4,0,116,11,107,10,114,152,1,0,1,0, - 1,0,89,0,110,2,88,0,130,0,89,0,110,2,88,0, - 116,5,106,6,160,12,124,0,106,7,161,1,125,1,124,1, - 116,5,106,6,124,0,106,7,60,0,116,13,100,5,124,0, - 106,7,124,0,106,0,131,3,1,0,87,0,53,0,100,6, - 124,0,95,4,88,0,124,1,83,0,41,7,78,114,150,0, - 0,0,84,114,154,0,0,0,114,16,0,0,0,122,18,105, - 109,112,111,114,116,32,123,33,114,125,32,35,32,123,33,114, - 125,70,41,14,114,109,0,0,0,114,4,0,0,0,114,158, - 0,0,0,114,152,0,0,0,90,13,95,105,110,105,116,105, - 97,108,105,122,105,110,103,114,15,0,0,0,114,92,0,0, - 0,114,17,0,0,0,114,117,0,0,0,114,79,0,0,0, - 114,150,0,0,0,114,63,0,0,0,114,156,0,0,0,114, - 76,0,0,0,114,151,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,14,95,108,111,97,100,95, - 117,110,108,111,99,107,101,100,138,2,0,0,115,46,0,0, - 0,0,2,10,2,12,1,8,2,8,5,6,1,2,1,12, - 1,2,1,10,1,10,1,16,3,16,1,6,1,2,1,14, - 1,14,1,6,1,8,5,14,1,12,1,20,2,8,2,114, - 159,0,0,0,99,1,0,0,0,0,0,0,0,1,0,0, + 0,0,0,0,0,0,4,0,0,0,10,0,0,0,67,0, + 0,0,115,204,0,0,0,124,0,106,0,125,2,116,1,124, + 2,131,1,143,180,1,0,116,2,106,3,160,4,124,2,161, + 1,124,1,107,9,114,54,100,1,160,5,124,2,161,1,125, + 3,116,6,124,3,124,2,100,2,141,2,130,1,122,106,124, + 0,106,7,100,3,107,8,114,106,124,0,106,8,100,3,107, + 8,114,90,116,6,100,4,124,0,106,0,100,2,141,2,130, + 1,116,9,124,0,124,1,100,5,100,6,141,3,1,0,110, + 52,116,9,124,0,124,1,100,5,100,6,141,3,1,0,116, + 10,124,0,106,7,100,7,131,2,115,146,124,0,106,7,160, + 11,124,2,161,1,1,0,110,12,124,0,106,7,160,12,124, + 1,161,1,1,0,87,0,53,0,116,2,106,3,160,13,124, + 0,106,0,161,1,125,1,124,1,116,2,106,3,124,0,106, + 0,60,0,88,0,87,0,53,0,81,0,82,0,88,0,124, + 1,83,0,41,8,122,70,69,120,101,99,117,116,101,32,116, + 104,101,32,115,112,101,99,39,115,32,115,112,101,99,105,102, + 105,101,100,32,109,111,100,117,108,101,32,105,110,32,97,110, + 32,101,120,105,115,116,105,110,103,32,109,111,100,117,108,101, + 39,115,32,110,97,109,101,115,112,97,99,101,46,122,30,109, + 111,100,117,108,101,32,123,33,114,125,32,110,111,116,32,105, + 110,32,115,121,115,46,109,111,100,117,108,101,115,114,16,0, + 0,0,78,250,14,109,105,115,115,105,110,103,32,108,111,97, + 100,101,114,84,114,143,0,0,0,114,150,0,0,0,41,14, + 114,17,0,0,0,114,50,0,0,0,114,15,0,0,0,114, + 92,0,0,0,114,34,0,0,0,114,45,0,0,0,114,79, + 0,0,0,114,109,0,0,0,114,117,0,0,0,114,148,0, + 0,0,114,4,0,0,0,218,11,108,111,97,100,95,109,111, + 100,117,108,101,114,150,0,0,0,218,3,112,111,112,41,4, + 114,95,0,0,0,114,96,0,0,0,114,17,0,0,0,218, + 3,109,115,103,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,93,0,0,0,71,2,0,0,115,34,0,0, + 0,0,2,6,1,10,1,16,1,10,1,12,1,2,1,10, + 1,10,1,14,2,16,2,14,1,12,4,14,2,16,4,14, + 1,24,1,114,93,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,8,0,0,0,67,0,0, + 0,115,26,1,0,0,122,18,124,0,106,0,160,1,124,0, + 106,2,161,1,1,0,87,0,110,52,1,0,1,0,1,0, + 124,0,106,2,116,3,106,4,107,6,114,64,116,3,106,4, + 160,5,124,0,106,2,161,1,125,1,124,1,116,3,106,4, + 124,0,106,2,60,0,130,0,89,0,110,2,88,0,116,3, + 106,4,160,5,124,0,106,2,161,1,125,1,124,1,116,3, + 106,4,124,0,106,2,60,0,116,6,124,1,100,1,100,0, + 131,3,100,0,107,8,114,148,122,12,124,0,106,0,124,1, + 95,7,87,0,110,20,4,0,116,8,107,10,114,146,1,0, + 1,0,1,0,89,0,110,2,88,0,116,6,124,1,100,2, + 100,0,131,3,100,0,107,8,114,226,122,40,124,1,106,9, + 124,1,95,10,116,11,124,1,100,3,131,2,115,202,124,0, + 106,2,160,12,100,4,161,1,100,5,25,0,124,1,95,10, + 87,0,110,20,4,0,116,8,107,10,114,224,1,0,1,0, + 1,0,89,0,110,2,88,0,116,6,124,1,100,6,100,0, + 131,3,100,0,107,8,144,1,114,22,122,10,124,0,124,1, + 95,13,87,0,110,22,4,0,116,8,107,10,144,1,114,20, + 1,0,1,0,1,0,89,0,110,2,88,0,124,1,83,0, + 41,7,78,114,98,0,0,0,114,145,0,0,0,114,141,0, + 0,0,114,128,0,0,0,114,22,0,0,0,114,105,0,0, + 0,41,14,114,109,0,0,0,114,155,0,0,0,114,17,0, + 0,0,114,15,0,0,0,114,92,0,0,0,114,156,0,0, + 0,114,6,0,0,0,114,98,0,0,0,114,106,0,0,0, + 114,1,0,0,0,114,145,0,0,0,114,4,0,0,0,114, + 129,0,0,0,114,105,0,0,0,114,151,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,25,95, + 108,111,97,100,95,98,97,99,107,119,97,114,100,95,99,111, + 109,112,97,116,105,98,108,101,101,2,0,0,115,54,0,0, + 0,0,4,2,1,18,1,6,1,12,1,14,1,12,1,8, + 3,14,1,12,1,16,1,2,1,12,1,14,1,6,1,16, + 1,2,4,8,1,10,1,22,1,14,1,6,1,18,1,2, + 1,10,1,16,1,6,1,114,158,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,11,0,0, + 0,67,0,0,0,115,220,0,0,0,124,0,106,0,100,0, + 107,9,114,30,116,1,124,0,106,0,100,1,131,2,115,30, + 116,2,124,0,131,1,83,0,116,3,124,0,131,1,125,1, + 100,2,124,0,95,4,122,162,124,1,116,5,106,6,124,0, + 106,7,60,0,122,52,124,0,106,0,100,0,107,8,114,96, + 124,0,106,8,100,0,107,8,114,108,116,9,100,3,124,0, + 106,7,100,4,141,2,130,1,110,12,124,0,106,0,160,10, + 124,1,161,1,1,0,87,0,110,50,1,0,1,0,1,0, + 122,14,116,5,106,6,124,0,106,7,61,0,87,0,110,20, + 4,0,116,11,107,10,114,152,1,0,1,0,1,0,89,0, + 110,2,88,0,130,0,89,0,110,2,88,0,116,5,106,6, + 160,12,124,0,106,7,161,1,125,1,124,1,116,5,106,6, + 124,0,106,7,60,0,116,13,100,5,124,0,106,7,124,0, + 106,0,131,3,1,0,87,0,53,0,100,6,124,0,95,4, + 88,0,124,1,83,0,41,7,78,114,150,0,0,0,84,114, + 154,0,0,0,114,16,0,0,0,122,18,105,109,112,111,114, + 116,32,123,33,114,125,32,35,32,123,33,114,125,70,41,14, + 114,109,0,0,0,114,4,0,0,0,114,158,0,0,0,114, + 152,0,0,0,90,13,95,105,110,105,116,105,97,108,105,122, + 105,110,103,114,15,0,0,0,114,92,0,0,0,114,17,0, + 0,0,114,117,0,0,0,114,79,0,0,0,114,150,0,0, + 0,114,63,0,0,0,114,156,0,0,0,114,76,0,0,0, + 114,151,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,14,95,108,111,97,100,95,117,110,108,111, + 99,107,101,100,138,2,0,0,115,46,0,0,0,0,2,10, + 2,12,1,8,2,8,5,6,1,2,1,12,1,2,1,10, + 1,10,1,16,3,16,1,6,1,2,1,14,1,14,1,6, + 1,8,5,14,1,12,1,20,2,8,2,114,159,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, 0,10,0,0,0,67,0,0,0,115,42,0,0,0,116,0, 124,0,106,1,131,1,143,22,1,0,116,2,124,0,131,1, 87,0,2,0,53,0,81,0,82,0,163,0,83,0,81,0, @@ -1011,56 +1023,57 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 95,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, 0,0,0,114,94,0,0,0,180,2,0,0,115,4,0,0, 0,0,9,12,1,114,94,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, - 136,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 101,4,100,2,100,3,132,0,131,1,90,5,101,6,100,19, - 100,5,100,6,132,1,131,1,90,7,101,6,100,20,100,7, - 100,8,132,1,131,1,90,8,101,6,100,9,100,10,132,0, - 131,1,90,9,101,6,100,11,100,12,132,0,131,1,90,10, - 101,6,101,11,100,13,100,14,132,0,131,1,131,1,90,12, - 101,6,101,11,100,15,100,16,132,0,131,1,131,1,90,13, - 101,6,101,11,100,17,100,18,132,0,131,1,131,1,90,14, - 101,6,101,15,131,1,90,16,100,4,83,0,41,21,218,15, - 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,122, - 144,77,101,116,97,32,112,97,116,104,32,105,109,112,111,114, - 116,32,102,111,114,32,98,117,105,108,116,45,105,110,32,109, - 111,100,117,108,101,115,46,10,10,32,32,32,32,65,108,108, - 32,109,101,116,104,111,100,115,32,97,114,101,32,101,105,116, - 104,101,114,32,99,108,97,115,115,32,111,114,32,115,116,97, - 116,105,99,32,109,101,116,104,111,100,115,32,116,111,32,97, - 118,111,105,100,32,116,104,101,32,110,101,101,100,32,116,111, - 10,32,32,32,32,105,110,115,116,97,110,116,105,97,116,101, - 32,116,104,101,32,99,108,97,115,115,46,10,10,32,32,32, - 32,99,1,0,0,0,0,0,0,0,1,0,0,0,3,0, - 0,0,67,0,0,0,115,12,0,0,0,100,1,160,0,124, - 0,106,1,161,1,83,0,41,2,250,115,82,101,116,117,114, - 110,32,114,101,112,114,32,102,111,114,32,116,104,101,32,109, - 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, - 84,104,101,32,109,101,116,104,111,100,32,105,115,32,100,101, - 112,114,101,99,97,116,101,100,46,32,32,84,104,101,32,105, - 109,112,111,114,116,32,109,97,99,104,105,110,101,114,121,32, - 100,111,101,115,32,116,104,101,32,106,111,98,32,105,116,115, - 101,108,102,46,10,10,32,32,32,32,32,32,32,32,122,24, - 60,109,111,100,117,108,101,32,123,33,114,125,32,40,98,117, - 105,108,116,45,105,110,41,62,41,2,114,45,0,0,0,114, - 1,0,0,0,41,1,114,96,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,99,0,0,0,204, - 2,0,0,115,2,0,0,0,0,7,122,27,66,117,105,108, - 116,105,110,73,109,112,111,114,116,101,114,46,109,111,100,117, - 108,101,95,114,101,112,114,78,99,4,0,0,0,0,0,0, - 0,4,0,0,0,5,0,0,0,67,0,0,0,115,44,0, - 0,0,124,2,100,0,107,9,114,12,100,0,83,0,116,0, - 160,1,124,1,161,1,114,36,116,2,124,1,124,0,100,1, - 100,2,141,3,83,0,100,0,83,0,100,0,83,0,41,3, - 78,122,8,98,117,105,108,116,45,105,110,114,137,0,0,0, - 41,3,114,57,0,0,0,90,10,105,115,95,98,117,105,108, - 116,105,110,114,91,0,0,0,169,4,218,3,99,108,115,114, - 81,0,0,0,218,4,112,97,116,104,218,6,116,97,114,103, - 101,116,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,9,102,105,110,100,95,115,112,101,99,213,2,0,0, - 115,10,0,0,0,0,2,8,1,4,1,10,1,14,2,122, - 25,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,64, + 0,0,0,115,136,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,101,4,100,2,100,3,132,0,131,1,90,5, + 101,6,100,19,100,5,100,6,132,1,131,1,90,7,101,6, + 100,20,100,7,100,8,132,1,131,1,90,8,101,6,100,9, + 100,10,132,0,131,1,90,9,101,6,100,11,100,12,132,0, + 131,1,90,10,101,6,101,11,100,13,100,14,132,0,131,1, + 131,1,90,12,101,6,101,11,100,15,100,16,132,0,131,1, + 131,1,90,13,101,6,101,11,100,17,100,18,132,0,131,1, + 131,1,90,14,101,6,101,15,131,1,90,16,100,4,83,0, + 41,21,218,15,66,117,105,108,116,105,110,73,109,112,111,114, + 116,101,114,122,144,77,101,116,97,32,112,97,116,104,32,105, + 109,112,111,114,116,32,102,111,114,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32, + 32,65,108,108,32,109,101,116,104,111,100,115,32,97,114,101, + 32,101,105,116,104,101,114,32,99,108,97,115,115,32,111,114, + 32,115,116,97,116,105,99,32,109,101,116,104,111,100,115,32, + 116,111,32,97,118,111,105,100,32,116,104,101,32,110,101,101, + 100,32,116,111,10,32,32,32,32,105,110,115,116,97,110,116, + 105,97,116,101,32,116,104,101,32,99,108,97,115,115,46,10, + 10,32,32,32,32,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,12, + 0,0,0,100,1,160,0,124,0,106,1,161,1,83,0,41, + 2,250,115,82,101,116,117,114,110,32,114,101,112,114,32,102, + 111,114,32,116,104,101,32,109,111,100,117,108,101,46,10,10, + 32,32,32,32,32,32,32,32,84,104,101,32,109,101,116,104, + 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 46,32,32,84,104,101,32,105,109,112,111,114,116,32,109,97, + 99,104,105,110,101,114,121,32,100,111,101,115,32,116,104,101, + 32,106,111,98,32,105,116,115,101,108,102,46,10,10,32,32, + 32,32,32,32,32,32,122,24,60,109,111,100,117,108,101,32, + 123,33,114,125,32,40,98,117,105,108,116,45,105,110,41,62, + 41,2,114,45,0,0,0,114,1,0,0,0,41,1,114,96, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,99,0,0,0,204,2,0,0,115,2,0,0,0, + 0,7,122,27,66,117,105,108,116,105,110,73,109,112,111,114, + 116,101,114,46,109,111,100,117,108,101,95,114,101,112,114,78, + 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,5,0,0,0,67,0,0,0,115,44,0,0,0,124,2, + 100,0,107,9,114,12,100,0,83,0,116,0,160,1,124,1, + 161,1,114,36,116,2,124,1,124,0,100,1,100,2,141,3, + 83,0,100,0,83,0,100,0,83,0,41,3,78,122,8,98, + 117,105,108,116,45,105,110,114,137,0,0,0,41,3,114,57, + 0,0,0,90,10,105,115,95,98,117,105,108,116,105,110,114, + 91,0,0,0,169,4,218,3,99,108,115,114,81,0,0,0, + 218,4,112,97,116,104,218,6,116,97,114,103,101,116,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,9,102, + 105,110,100,95,115,112,101,99,213,2,0,0,115,10,0,0, + 0,0,2,8,1,4,1,10,1,14,2,122,25,66,117,105, + 108,116,105,110,73,109,112,111,114,116,101,114,46,102,105,110, + 100,95,115,112,101,99,99,3,0,0,0,0,0,0,0,0, 0,0,0,4,0,0,0,4,0,0,0,67,0,0,0,115, 30,0,0,0,124,0,160,0,124,1,124,2,161,2,125,3, 124,3,100,1,107,9,114,26,124,3,106,1,83,0,100,1, @@ -1082,43 +1095,44 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 100,117,108,101,222,2,0,0,115,4,0,0,0,0,9,12, 1,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116, 101,114,46,102,105,110,100,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, - 0,0,0,115,46,0,0,0,124,1,106,0,116,1,106,2, - 107,7,114,34,116,3,100,1,160,4,124,1,106,0,161,1, - 124,1,106,0,100,2,141,2,130,1,116,5,116,6,106,7, - 124,1,131,2,83,0,41,3,122,24,67,114,101,97,116,101, - 32,97,32,98,117,105,108,116,45,105,110,32,109,111,100,117, - 108,101,114,77,0,0,0,114,16,0,0,0,41,8,114,17, - 0,0,0,114,15,0,0,0,114,78,0,0,0,114,79,0, - 0,0,114,45,0,0,0,114,67,0,0,0,114,57,0,0, - 0,90,14,99,114,101,97,116,101,95,98,117,105,108,116,105, - 110,41,2,114,30,0,0,0,114,95,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,149,0,0, - 0,234,2,0,0,115,10,0,0,0,0,3,12,1,12,1, - 4,255,6,2,122,29,66,117,105,108,116,105,110,73,109,112, - 111,114,116,101,114,46,99,114,101,97,116,101,95,109,111,100, - 117,108,101,99,2,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,67,0,0,0,115,16,0,0,0,116,0,116, - 1,106,2,124,1,131,2,1,0,100,1,83,0,41,2,122, - 22,69,120,101,99,32,97,32,98,117,105,108,116,45,105,110, - 32,109,111,100,117,108,101,78,41,3,114,67,0,0,0,114, - 57,0,0,0,90,12,101,120,101,99,95,98,117,105,108,116, - 105,110,41,2,114,30,0,0,0,114,96,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,0, - 0,0,242,2,0,0,115,2,0,0,0,0,3,122,27,66, - 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,101, - 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,41,2,122,57,82,101,116,117, - 114,110,32,78,111,110,101,32,97,115,32,98,117,105,108,116, - 45,105,110,32,109,111,100,117,108,101,115,32,100,111,32,110, - 111,116,32,104,97,118,101,32,99,111,100,101,32,111,98,106, - 101,99,116,115,46,78,114,10,0,0,0,169,2,114,163,0, - 0,0,114,81,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,8,103,101,116,95,99,111,100,101, - 247,2,0,0,115,2,0,0,0,0,4,122,24,66,117,105, - 108,116,105,110,73,109,112,111,114,116,101,114,46,103,101,116, - 95,99,111,100,101,99,2,0,0,0,0,0,0,0,2,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,67,0,0,0,115,46,0,0,0,124,1,106,0, + 116,1,106,2,107,7,114,34,116,3,100,1,160,4,124,1, + 106,0,161,1,124,1,106,0,100,2,141,2,130,1,116,5, + 116,6,106,7,124,1,131,2,83,0,41,3,122,24,67,114, + 101,97,116,101,32,97,32,98,117,105,108,116,45,105,110,32, + 109,111,100,117,108,101,114,77,0,0,0,114,16,0,0,0, + 41,8,114,17,0,0,0,114,15,0,0,0,114,78,0,0, + 0,114,79,0,0,0,114,45,0,0,0,114,67,0,0,0, + 114,57,0,0,0,90,14,99,114,101,97,116,101,95,98,117, + 105,108,116,105,110,41,2,114,30,0,0,0,114,95,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,149,0,0,0,234,2,0,0,115,10,0,0,0,0,3, + 12,1,12,1,4,255,6,2,122,29,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,99,114,101,97,116,101, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,16,0,0,0,116,0,116,1,106,2,124,1,131,2,1, + 0,100,1,83,0,41,2,122,22,69,120,101,99,32,97,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,78, + 41,3,114,67,0,0,0,114,57,0,0,0,90,12,101,120, + 101,99,95,98,117,105,108,116,105,110,41,2,114,30,0,0, + 0,114,96,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,150,0,0,0,242,2,0,0,115,2, + 0,0,0,0,3,122,27,66,117,105,108,116,105,110,73,109, + 112,111,114,116,101,114,46,101,120,101,99,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,1,83,0,41,2,122,57,82,101,116,117,114,110,32,78, + 111,110,101,32,97,115,32,98,117,105,108,116,45,105,110,32, + 109,111,100,117,108,101,115,32,100,111,32,110,111,116,32,104, + 97,118,101,32,99,111,100,101,32,111,98,106,101,99,116,115, + 46,78,114,10,0,0,0,169,2,114,163,0,0,0,114,81, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,8,103,101,116,95,99,111,100,101,247,2,0,0, + 115,2,0,0,0,0,4,122,24,66,117,105,108,116,105,110, + 73,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, 1,83,0,41,2,122,56,82,101,116,117,114,110,32,78,111, 110,101,32,97,115,32,98,117,105,108,116,45,105,110,32,109, @@ -1129,58 +1143,59 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 111,117,114,99,101,253,2,0,0,115,2,0,0,0,0,4, 122,26,66,117,105,108,116,105,110,73,109,112,111,114,116,101, 114,46,103,101,116,95,115,111,117,114,99,101,99,2,0,0, - 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, - 0,115,4,0,0,0,100,1,83,0,41,2,122,52,82,101, - 116,117,114,110,32,70,97,108,115,101,32,97,115,32,98,117, - 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,97, - 114,101,32,110,101,118,101,114,32,112,97,99,107,97,103,101, - 115,46,70,114,10,0,0,0,114,168,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,115,0,0, - 0,3,3,0,0,115,2,0,0,0,0,4,122,26,66,117, - 105,108,116,105,110,73,109,112,111,114,116,101,114,46,105,115, - 95,112,97,99,107,97,103,101,41,2,78,78,41,1,78,41, - 17,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0, - 114,3,0,0,0,218,12,115,116,97,116,105,99,109,101,116, - 104,111,100,114,99,0,0,0,218,11,99,108,97,115,115,109, - 101,116,104,111,100,114,166,0,0,0,114,167,0,0,0,114, - 149,0,0,0,114,150,0,0,0,114,86,0,0,0,114,169, - 0,0,0,114,170,0,0,0,114,115,0,0,0,114,97,0, - 0,0,114,155,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,160,0,0,0, - 195,2,0,0,115,42,0,0,0,8,2,4,7,2,1,10, - 8,2,1,12,8,2,1,12,11,2,1,10,7,2,1,10, - 4,2,1,2,1,12,4,2,1,2,1,12,4,2,1,2, - 1,12,4,114,160,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,64,0,0,0,115,144,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 90,4,101,5,100,3,100,4,132,0,131,1,90,6,101,7, - 100,22,100,6,100,7,132,1,131,1,90,8,101,7,100,23, - 100,8,100,9,132,1,131,1,90,9,101,7,100,10,100,11, - 132,0,131,1,90,10,101,5,100,12,100,13,132,0,131,1, - 90,11,101,7,100,14,100,15,132,0,131,1,90,12,101,7, - 101,13,100,16,100,17,132,0,131,1,131,1,90,14,101,7, - 101,13,100,18,100,19,132,0,131,1,131,1,90,15,101,7, - 101,13,100,20,100,21,132,0,131,1,131,1,90,16,100,5, - 83,0,41,24,218,14,70,114,111,122,101,110,73,109,112,111, - 114,116,101,114,122,142,77,101,116,97,32,112,97,116,104,32, - 105,109,112,111,114,116,32,102,111,114,32,102,114,111,122,101, - 110,32,109,111,100,117,108,101,115,46,10,10,32,32,32,32, - 65,108,108,32,109,101,116,104,111,100,115,32,97,114,101,32, - 101,105,116,104,101,114,32,99,108,97,115,115,32,111,114,32, - 115,116,97,116,105,99,32,109,101,116,104,111,100,115,32,116, - 111,32,97,118,111,105,100,32,116,104,101,32,110,101,101,100, - 32,116,111,10,32,32,32,32,105,110,115,116,97,110,116,105, - 97,116,101,32,116,104,101,32,99,108,97,115,115,46,10,10, - 32,32,32,32,90,6,102,114,111,122,101,110,99,1,0,0, - 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, - 0,115,16,0,0,0,100,1,160,0,124,0,106,1,116,2, - 106,3,161,2,83,0,41,2,114,161,0,0,0,114,153,0, - 0,0,41,4,114,45,0,0,0,114,1,0,0,0,114,173, - 0,0,0,114,138,0,0,0,41,1,218,1,109,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,99,0,0, - 0,23,3,0,0,115,2,0,0,0,0,7,122,26,70,114, - 111,122,101,110,73,109,112,111,114,116,101,114,46,109,111,100, - 117,108,101,95,114,101,112,114,78,99,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2, + 122,52,82,101,116,117,114,110,32,70,97,108,115,101,32,97, + 115,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,115,32,97,114,101,32,110,101,118,101,114,32,112,97,99, + 107,97,103,101,115,46,70,114,10,0,0,0,114,168,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,115,0,0,0,3,3,0,0,115,2,0,0,0,0,4, + 122,26,66,117,105,108,116,105,110,73,109,112,111,114,116,101, + 114,46,105,115,95,112,97,99,107,97,103,101,41,2,78,78, + 41,1,78,41,17,114,1,0,0,0,114,0,0,0,0,114, + 2,0,0,0,114,3,0,0,0,218,12,115,116,97,116,105, + 99,109,101,116,104,111,100,114,99,0,0,0,218,11,99,108, + 97,115,115,109,101,116,104,111,100,114,166,0,0,0,114,167, + 0,0,0,114,149,0,0,0,114,150,0,0,0,114,86,0, + 0,0,114,169,0,0,0,114,170,0,0,0,114,115,0,0, + 0,114,97,0,0,0,114,155,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 160,0,0,0,195,2,0,0,115,42,0,0,0,8,2,4, + 7,2,1,10,8,2,1,12,8,2,1,12,11,2,1,10, + 7,2,1,10,4,2,1,2,1,12,4,2,1,2,1,12, + 4,2,1,2,1,12,4,114,160,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,64,0,0,0,115,144,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,90,4,101,5,100,3,100,4, + 132,0,131,1,90,6,101,7,100,22,100,6,100,7,132,1, + 131,1,90,8,101,7,100,23,100,8,100,9,132,1,131,1, + 90,9,101,7,100,10,100,11,132,0,131,1,90,10,101,5, + 100,12,100,13,132,0,131,1,90,11,101,7,100,14,100,15, + 132,0,131,1,90,12,101,7,101,13,100,16,100,17,132,0, + 131,1,131,1,90,14,101,7,101,13,100,18,100,19,132,0, + 131,1,131,1,90,15,101,7,101,13,100,20,100,21,132,0, + 131,1,131,1,90,16,100,5,83,0,41,24,218,14,70,114, + 111,122,101,110,73,109,112,111,114,116,101,114,122,142,77,101, + 116,97,32,112,97,116,104,32,105,109,112,111,114,116,32,102, + 111,114,32,102,114,111,122,101,110,32,109,111,100,117,108,101, + 115,46,10,10,32,32,32,32,65,108,108,32,109,101,116,104, + 111,100,115,32,97,114,101,32,101,105,116,104,101,114,32,99, + 108,97,115,115,32,111,114,32,115,116,97,116,105,99,32,109, + 101,116,104,111,100,115,32,116,111,32,97,118,111,105,100,32, + 116,104,101,32,110,101,101,100,32,116,111,10,32,32,32,32, + 105,110,115,116,97,110,116,105,97,116,101,32,116,104,101,32, + 99,108,97,115,115,46,10,10,32,32,32,32,90,6,102,114, + 111,122,101,110,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,4,0,0,0,67,0,0,0,115,16,0, + 0,0,100,1,160,0,124,0,106,1,116,2,106,3,161,2, + 83,0,41,2,114,161,0,0,0,114,153,0,0,0,41,4, + 114,45,0,0,0,114,1,0,0,0,114,173,0,0,0,114, + 138,0,0,0,41,1,218,1,109,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,99,0,0,0,23,3,0, + 0,115,2,0,0,0,0,7,122,26,70,114,111,122,101,110, + 73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,95, + 114,101,112,114,78,99,4,0,0,0,0,0,0,0,0,0, 0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,34, 0,0,0,116,0,160,1,124,1,161,1,114,26,116,2,124, 1,124,0,124,0,106,3,100,1,141,3,83,0,100,0,83, @@ -1190,47 +1205,48 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,11,0,0,0,114,166,0,0,0,32,3,0,0, 115,6,0,0,0,0,2,10,1,16,2,122,24,70,114,111, 122,101,110,73,109,112,111,114,116,101,114,46,102,105,110,100, - 95,115,112,101,99,99,3,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,18,0,0,0,116, - 0,160,1,124,1,161,1,114,14,124,0,83,0,100,1,83, - 0,41,2,122,93,70,105,110,100,32,97,32,102,114,111,122, - 101,110,32,109,111,100,117,108,101,46,10,10,32,32,32,32, - 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, - 85,115,101,32,102,105,110,100,95,115,112,101,99,40,41,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, - 32,32,78,41,2,114,57,0,0,0,114,88,0,0,0,41, - 3,114,163,0,0,0,114,81,0,0,0,114,164,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 167,0,0,0,39,3,0,0,115,2,0,0,0,0,7,122, - 26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, - 102,105,110,100,95,109,111,100,117,108,101,99,2,0,0,0, - 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, - 115,4,0,0,0,100,1,83,0,41,2,122,42,85,115,101, - 32,100,101,102,97,117,108,116,32,115,101,109,97,110,116,105, - 99,115,32,102,111,114,32,109,111,100,117,108,101,32,99,114, - 101,97,116,105,111,110,46,78,114,10,0,0,0,41,2,114, - 163,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,149,0,0,0,48,3,0, - 0,115,2,0,0,0,0,2,122,28,70,114,111,122,101,110, - 73,109,112,111,114,116,101,114,46,99,114,101,97,116,101,95, - 109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,3, - 0,0,0,4,0,0,0,67,0,0,0,115,64,0,0,0, - 124,0,106,0,106,1,125,1,116,2,160,3,124,1,161,1, - 115,36,116,4,100,1,160,5,124,1,161,1,124,1,100,2, - 141,2,130,1,116,6,116,2,106,7,124,1,131,2,125,2, - 116,8,124,2,124,0,106,9,131,2,1,0,100,0,83,0, - 114,87,0,0,0,41,10,114,105,0,0,0,114,17,0,0, - 0,114,57,0,0,0,114,88,0,0,0,114,79,0,0,0, - 114,45,0,0,0,114,67,0,0,0,218,17,103,101,116,95, - 102,114,111,122,101,110,95,111,98,106,101,99,116,218,4,101, - 120,101,99,114,7,0,0,0,41,3,114,96,0,0,0,114, - 17,0,0,0,218,4,99,111,100,101,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,150,0,0,0,52,3, - 0,0,115,14,0,0,0,0,2,8,1,10,1,10,1,2, - 255,6,2,12,1,122,26,70,114,111,122,101,110,73,109,112, - 111,114,116,101,114,46,101,120,101,99,95,109,111,100,117,108, - 101,99,2,0,0,0,0,0,0,0,2,0,0,0,3,0, + 95,115,112,101,99,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,18, + 0,0,0,116,0,160,1,124,1,161,1,114,14,124,0,83, + 0,100,1,83,0,41,2,122,93,70,105,110,100,32,97,32, + 102,114,111,122,101,110,32,109,111,100,117,108,101,46,10,10, + 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, + 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, + 100,46,32,32,85,115,101,32,102,105,110,100,95,115,112,101, + 99,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, + 32,32,32,32,32,32,78,41,2,114,57,0,0,0,114,88, + 0,0,0,41,3,114,163,0,0,0,114,81,0,0,0,114, + 164,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,167,0,0,0,39,3,0,0,115,2,0,0, + 0,0,7,122,26,70,114,111,122,101,110,73,109,112,111,114, + 116,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, + 0,41,2,122,42,85,115,101,32,100,101,102,97,117,108,116, + 32,115,101,109,97,110,116,105,99,115,32,102,111,114,32,109, + 111,100,117,108,101,32,99,114,101,97,116,105,111,110,46,78, + 114,10,0,0,0,41,2,114,163,0,0,0,114,95,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,149,0,0,0,48,3,0,0,115,2,0,0,0,0,2, + 122,28,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,1, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, + 0,0,0,67,0,0,0,115,64,0,0,0,124,0,106,0, + 106,1,125,1,116,2,160,3,124,1,161,1,115,36,116,4, + 100,1,160,5,124,1,161,1,124,1,100,2,141,2,130,1, + 116,6,116,2,106,7,124,1,131,2,125,2,116,8,124,2, + 124,0,106,9,131,2,1,0,100,0,83,0,114,87,0,0, + 0,41,10,114,105,0,0,0,114,17,0,0,0,114,57,0, + 0,0,114,88,0,0,0,114,79,0,0,0,114,45,0,0, + 0,114,67,0,0,0,218,17,103,101,116,95,102,114,111,122, + 101,110,95,111,98,106,101,99,116,218,4,101,120,101,99,114, + 7,0,0,0,41,3,114,96,0,0,0,114,17,0,0,0, + 218,4,99,111,100,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,150,0,0,0,52,3,0,0,115,14, + 0,0,0,0,2,8,1,10,1,10,1,2,255,6,2,12, + 1,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101, + 114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, 0,0,67,0,0,0,115,10,0,0,0,116,0,124,0,124, 1,131,2,83,0,41,1,122,95,76,111,97,100,32,97,32, 102,114,111,122,101,110,32,109,111,100,117,108,101,46,10,10, @@ -1243,48 +1259,49 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,114,155,0,0,0,61,3,0,0,115,2,0,0, 0,0,7,122,26,70,114,111,122,101,110,73,109,112,111,114, 116,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, - 2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,10,0,0,0,116,0,160,1,124,1,161, - 1,83,0,41,1,122,45,82,101,116,117,114,110,32,116,104, - 101,32,99,111,100,101,32,111,98,106,101,99,116,32,102,111, - 114,32,116,104,101,32,102,114,111,122,101,110,32,109,111,100, - 117,108,101,46,41,2,114,57,0,0,0,114,175,0,0,0, - 114,168,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,169,0,0,0,70,3,0,0,115,2,0, - 0,0,0,4,122,23,70,114,111,122,101,110,73,109,112,111, - 114,116,101,114,46,103,101,116,95,99,111,100,101,99,2,0, - 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, - 0,0,115,4,0,0,0,100,1,83,0,41,2,122,54,82, - 101,116,117,114,110,32,78,111,110,101,32,97,115,32,102,114, - 111,122,101,110,32,109,111,100,117,108,101,115,32,100,111,32, - 110,111,116,32,104,97,118,101,32,115,111,117,114,99,101,32, - 99,111,100,101,46,78,114,10,0,0,0,114,168,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 170,0,0,0,76,3,0,0,115,2,0,0,0,0,4,122, - 25,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, - 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, - 10,0,0,0,116,0,160,1,124,1,161,1,83,0,41,1, - 122,46,82,101,116,117,114,110,32,84,114,117,101,32,105,102, - 32,116,104,101,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,32,105,115,32,97,32,112,97,99,107,97,103,101,46, - 41,2,114,57,0,0,0,90,17,105,115,95,102,114,111,122, - 101,110,95,112,97,99,107,97,103,101,114,168,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,115, - 0,0,0,82,3,0,0,115,2,0,0,0,0,4,122,25, - 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,105, - 115,95,112,97,99,107,97,103,101,41,2,78,78,41,1,78, - 41,17,114,1,0,0,0,114,0,0,0,0,114,2,0,0, - 0,114,3,0,0,0,114,138,0,0,0,114,171,0,0,0, - 114,99,0,0,0,114,172,0,0,0,114,166,0,0,0,114, - 167,0,0,0,114,149,0,0,0,114,150,0,0,0,114,155, - 0,0,0,114,90,0,0,0,114,169,0,0,0,114,170,0, - 0,0,114,115,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,173,0,0,0, - 12,3,0,0,115,46,0,0,0,8,2,4,7,4,2,2, - 1,10,8,2,1,12,6,2,1,12,8,2,1,10,3,2, - 1,10,8,2,1,10,8,2,1,2,1,12,4,2,1,2, - 1,12,4,2,1,2,1,114,173,0,0,0,99,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 3,0,0,0,67,0,0,0,115,10,0,0,0,116,0,160, + 1,124,1,161,1,83,0,41,1,122,45,82,101,116,117,114, + 110,32,116,104,101,32,99,111,100,101,32,111,98,106,101,99, + 116,32,102,111,114,32,116,104,101,32,102,114,111,122,101,110, + 32,109,111,100,117,108,101,46,41,2,114,57,0,0,0,114, + 175,0,0,0,114,168,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,169,0,0,0,70,3,0, + 0,115,2,0,0,0,0,4,122,23,70,114,111,122,101,110, + 73,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, + 1,83,0,41,2,122,54,82,101,116,117,114,110,32,78,111, + 110,101,32,97,115,32,102,114,111,122,101,110,32,109,111,100, + 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,10, + 0,0,0,114,168,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,170,0,0,0,76,3,0,0, + 115,2,0,0,0,0,4,122,25,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,103,101,116,95,115,111,117,114, + 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,10,0,0,0, + 116,0,160,1,124,1,161,1,83,0,41,1,122,46,82,101, + 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, + 32,102,114,111,122,101,110,32,109,111,100,117,108,101,32,105, + 115,32,97,32,112,97,99,107,97,103,101,46,41,2,114,57, + 0,0,0,90,17,105,115,95,102,114,111,122,101,110,95,112, + 97,99,107,97,103,101,114,168,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,115,0,0,0,82, + 3,0,0,115,2,0,0,0,0,4,122,25,70,114,111,122, + 101,110,73,109,112,111,114,116,101,114,46,105,115,95,112,97, + 99,107,97,103,101,41,2,78,78,41,1,78,41,17,114,1, + 0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,0, + 0,0,114,138,0,0,0,114,171,0,0,0,114,99,0,0, + 0,114,172,0,0,0,114,166,0,0,0,114,167,0,0,0, + 114,149,0,0,0,114,150,0,0,0,114,155,0,0,0,114, + 90,0,0,0,114,169,0,0,0,114,170,0,0,0,114,115, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,173,0,0,0,12,3,0,0, + 115,46,0,0,0,8,2,4,7,4,2,2,1,10,8,2, + 1,12,6,2,1,12,8,2,1,10,3,2,1,10,8,2, + 1,10,8,2,1,2,1,12,4,2,1,2,1,12,4,2, + 1,2,1,114,173,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, 0,115,32,0,0,0,101,0,90,1,100,0,90,2,100,1, 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, @@ -1292,55 +1309,56 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 116,76,111,99,107,67,111,110,116,101,120,116,122,36,67,111, 110,116,101,120,116,32,109,97,110,97,103,101,114,32,102,111, 114,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, - 107,46,99,1,0,0,0,0,0,0,0,1,0,0,0,2, - 0,0,0,67,0,0,0,115,12,0,0,0,116,0,160,1, - 161,0,1,0,100,1,83,0,41,2,122,24,65,99,113,117, - 105,114,101,32,116,104,101,32,105,109,112,111,114,116,32,108, - 111,99,107,46,78,41,2,114,57,0,0,0,114,58,0,0, - 0,114,47,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,54,0,0,0,95,3,0,0,115,2, - 0,0,0,0,2,122,28,95,73,109,112,111,114,116,76,111, - 99,107,67,111,110,116,101,120,116,46,95,95,101,110,116,101, - 114,95,95,99,4,0,0,0,0,0,0,0,4,0,0,0, - 2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,160, - 1,161,0,1,0,100,1,83,0,41,2,122,60,82,101,108, - 101,97,115,101,32,116,104,101,32,105,109,112,111,114,116,32, - 108,111,99,107,32,114,101,103,97,114,100,108,101,115,115,32, - 111,102,32,97,110,121,32,114,97,105,115,101,100,32,101,120, - 99,101,112,116,105,111,110,115,46,78,41,2,114,57,0,0, - 0,114,60,0,0,0,41,4,114,30,0,0,0,90,8,101, - 120,99,95,116,121,112,101,90,9,101,120,99,95,118,97,108, - 117,101,90,13,101,120,99,95,116,114,97,99,101,98,97,99, - 107,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,56,0,0,0,99,3,0,0,115,2,0,0,0,0,2, - 122,27,95,73,109,112,111,114,116,76,111,99,107,67,111,110, - 116,101,120,116,46,95,95,101,120,105,116,95,95,78,41,6, - 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, - 3,0,0,0,114,54,0,0,0,114,56,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,178,0,0,0,91,3,0,0,115,6,0,0,0, - 8,2,4,2,8,4,114,178,0,0,0,99,3,0,0,0, - 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,64,0,0,0,124,1,160,0,100,1,124,2,100,2,24, - 0,161,2,125,3,116,1,124,3,131,1,124,2,107,0,114, - 36,116,2,100,3,131,1,130,1,124,3,100,4,25,0,125, - 4,124,0,114,60,100,5,160,3,124,4,124,0,161,2,83, - 0,124,4,83,0,41,6,122,50,82,101,115,111,108,118,101, - 32,97,32,114,101,108,97,116,105,118,101,32,109,111,100,117, - 108,101,32,110,97,109,101,32,116,111,32,97,110,32,97,98, - 115,111,108,117,116,101,32,111,110,101,46,114,128,0,0,0, - 114,37,0,0,0,122,50,97,116,116,101,109,112,116,101,100, - 32,114,101,108,97,116,105,118,101,32,105,109,112,111,114,116, - 32,98,101,121,111,110,100,32,116,111,112,45,108,101,118,101, - 108,32,112,97,99,107,97,103,101,114,22,0,0,0,250,5, - 123,125,46,123,125,41,4,218,6,114,115,112,108,105,116,218, - 3,108,101,110,218,10,86,97,108,117,101,69,114,114,111,114, - 114,45,0,0,0,41,5,114,17,0,0,0,218,7,112,97, - 99,107,97,103,101,218,5,108,101,118,101,108,90,4,98,105, - 116,115,90,4,98,97,115,101,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,13,95,114,101,115,111,108,118, - 101,95,110,97,109,101,104,3,0,0,115,10,0,0,0,0, - 2,16,1,12,1,8,1,8,1,114,185,0,0,0,99,3, + 107,46,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,2,0,0,0,67,0,0,0,115,12,0,0,0, + 116,0,160,1,161,0,1,0,100,1,83,0,41,2,122,24, + 65,99,113,117,105,114,101,32,116,104,101,32,105,109,112,111, + 114,116,32,108,111,99,107,46,78,41,2,114,57,0,0,0, + 114,58,0,0,0,114,47,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,54,0,0,0,95,3, + 0,0,115,2,0,0,0,0,2,122,28,95,73,109,112,111, + 114,116,76,111,99,107,67,111,110,116,101,120,116,46,95,95, + 101,110,116,101,114,95,95,99,4,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,2,0,0,0,67,0,0,0, + 115,12,0,0,0,116,0,160,1,161,0,1,0,100,1,83, + 0,41,2,122,60,82,101,108,101,97,115,101,32,116,104,101, + 32,105,109,112,111,114,116,32,108,111,99,107,32,114,101,103, + 97,114,100,108,101,115,115,32,111,102,32,97,110,121,32,114, + 97,105,115,101,100,32,101,120,99,101,112,116,105,111,110,115, + 46,78,41,2,114,57,0,0,0,114,60,0,0,0,41,4, + 114,30,0,0,0,90,8,101,120,99,95,116,121,112,101,90, + 9,101,120,99,95,118,97,108,117,101,90,13,101,120,99,95, + 116,114,97,99,101,98,97,99,107,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,56,0,0,0,99,3,0, + 0,115,2,0,0,0,0,2,122,27,95,73,109,112,111,114, + 116,76,111,99,107,67,111,110,116,101,120,116,46,95,95,101, + 120,105,116,95,95,78,41,6,114,1,0,0,0,114,0,0, + 0,0,114,2,0,0,0,114,3,0,0,0,114,54,0,0, + 0,114,56,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,178,0,0,0,91, + 3,0,0,115,6,0,0,0,8,2,4,2,8,4,114,178, + 0,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, + 5,0,0,0,5,0,0,0,67,0,0,0,115,64,0,0, + 0,124,1,160,0,100,1,124,2,100,2,24,0,161,2,125, + 3,116,1,124,3,131,1,124,2,107,0,114,36,116,2,100, + 3,131,1,130,1,124,3,100,4,25,0,125,4,124,0,114, + 60,100,5,160,3,124,4,124,0,161,2,83,0,124,4,83, + 0,41,6,122,50,82,101,115,111,108,118,101,32,97,32,114, + 101,108,97,116,105,118,101,32,109,111,100,117,108,101,32,110, + 97,109,101,32,116,111,32,97,110,32,97,98,115,111,108,117, + 116,101,32,111,110,101,46,114,128,0,0,0,114,37,0,0, + 0,122,50,97,116,116,101,109,112,116,101,100,32,114,101,108, + 97,116,105,118,101,32,105,109,112,111,114,116,32,98,101,121, + 111,110,100,32,116,111,112,45,108,101,118,101,108,32,112,97, + 99,107,97,103,101,114,22,0,0,0,250,5,123,125,46,123, + 125,41,4,218,6,114,115,112,108,105,116,218,3,108,101,110, + 218,10,86,97,108,117,101,69,114,114,111,114,114,45,0,0, + 0,41,5,114,17,0,0,0,218,7,112,97,99,107,97,103, + 101,218,5,108,101,118,101,108,90,4,98,105,116,115,90,4, + 98,97,115,101,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,13,95,114,101,115,111,108,118,101,95,110,97, + 109,101,104,3,0,0,115,10,0,0,0,0,2,16,1,12, + 1,8,1,8,1,114,185,0,0,0,99,3,0,0,0,0, 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, 0,0,0,115,34,0,0,0,124,0,160,0,124,1,124,2, 161,2,125,3,124,3,100,0,107,8,114,24,100,0,83,0, @@ -1351,110 +1369,111 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,218,17,95,102,105,110,100,95,115,112,101,99,95, 108,101,103,97,99,121,113,3,0,0,115,8,0,0,0,0, 3,12,1,8,1,4,1,114,187,0,0,0,99,3,0,0, - 0,0,0,0,0,10,0,0,0,10,0,0,0,67,0,0, - 0,115,12,1,0,0,116,0,106,1,125,3,124,3,100,1, - 107,8,114,22,116,2,100,2,131,1,130,1,124,3,115,38, - 116,3,160,4,100,3,116,5,161,2,1,0,124,0,116,0, - 106,6,107,6,125,4,124,3,68,0,93,210,125,5,116,7, - 131,0,143,84,1,0,122,10,124,5,106,8,125,6,87,0, - 110,54,4,0,116,9,107,10,114,128,1,0,1,0,1,0, - 116,10,124,5,124,0,124,1,131,3,125,7,124,7,100,1, - 107,8,114,124,89,0,87,0,53,0,81,0,82,0,163,0, - 113,52,89,0,110,14,88,0,124,6,124,0,124,1,124,2, - 131,3,125,7,87,0,53,0,81,0,82,0,88,0,124,7, - 100,1,107,9,114,52,124,4,144,0,115,254,124,0,116,0, - 106,6,107,6,144,0,114,254,116,0,106,6,124,0,25,0, - 125,8,122,10,124,8,106,11,125,9,87,0,110,28,4,0, - 116,9,107,10,114,226,1,0,1,0,1,0,124,7,6,0, - 89,0,2,0,1,0,83,0,88,0,124,9,100,1,107,8, - 114,244,124,7,2,0,1,0,83,0,124,9,2,0,1,0, - 83,0,113,52,124,7,2,0,1,0,83,0,113,52,100,1, - 83,0,41,4,122,21,70,105,110,100,32,97,32,109,111,100, - 117,108,101,39,115,32,115,112,101,99,46,78,122,53,115,121, - 115,46,109,101,116,97,95,112,97,116,104,32,105,115,32,78, - 111,110,101,44,32,80,121,116,104,111,110,32,105,115,32,108, - 105,107,101,108,121,32,115,104,117,116,116,105,110,103,32,100, - 111,119,110,122,22,115,121,115,46,109,101,116,97,95,112,97, - 116,104,32,105,115,32,101,109,112,116,121,41,12,114,15,0, - 0,0,218,9,109,101,116,97,95,112,97,116,104,114,79,0, - 0,0,218,9,95,119,97,114,110,105,110,103,115,218,4,119, - 97,114,110,218,13,73,109,112,111,114,116,87,97,114,110,105, - 110,103,114,92,0,0,0,114,178,0,0,0,114,166,0,0, - 0,114,106,0,0,0,114,187,0,0,0,114,105,0,0,0, - 41,10,114,17,0,0,0,114,164,0,0,0,114,165,0,0, - 0,114,188,0,0,0,90,9,105,115,95,114,101,108,111,97, - 100,114,186,0,0,0,114,166,0,0,0,114,95,0,0,0, - 114,96,0,0,0,114,105,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,10,95,102,105,110,100, - 95,115,112,101,99,122,3,0,0,115,54,0,0,0,0,2, - 6,1,8,2,8,3,4,1,12,5,10,1,8,1,8,1, - 2,1,10,1,14,1,12,1,8,1,20,2,22,1,8,2, - 18,1,10,1,2,1,10,1,14,4,14,2,8,1,8,2, - 10,2,10,2,114,192,0,0,0,99,3,0,0,0,0,0, - 0,0,3,0,0,0,5,0,0,0,67,0,0,0,115,108, - 0,0,0,116,0,124,0,116,1,131,2,115,28,116,2,100, - 1,160,3,116,4,124,0,131,1,161,1,131,1,130,1,124, - 2,100,2,107,0,114,44,116,5,100,3,131,1,130,1,124, - 2,100,2,107,4,114,84,116,0,124,1,116,1,131,2,115, - 72,116,2,100,4,131,1,130,1,110,12,124,1,115,84,116, - 6,100,5,131,1,130,1,124,0,115,104,124,2,100,2,107, - 2,114,104,116,5,100,6,131,1,130,1,100,7,83,0,41, - 8,122,28,86,101,114,105,102,121,32,97,114,103,117,109,101, - 110,116,115,32,97,114,101,32,34,115,97,110,101,34,46,122, - 31,109,111,100,117,108,101,32,110,97,109,101,32,109,117,115, - 116,32,98,101,32,115,116,114,44,32,110,111,116,32,123,125, - 114,22,0,0,0,122,18,108,101,118,101,108,32,109,117,115, - 116,32,98,101,32,62,61,32,48,122,31,95,95,112,97,99, - 107,97,103,101,95,95,32,110,111,116,32,115,101,116,32,116, - 111,32,97,32,115,116,114,105,110,103,122,54,97,116,116,101, - 109,112,116,101,100,32,114,101,108,97,116,105,118,101,32,105, - 109,112,111,114,116,32,119,105,116,104,32,110,111,32,107,110, - 111,119,110,32,112,97,114,101,110,116,32,112,97,99,107,97, - 103,101,122,17,69,109,112,116,121,32,109,111,100,117,108,101, - 32,110,97,109,101,78,41,7,218,10,105,115,105,110,115,116, - 97,110,99,101,218,3,115,116,114,218,9,84,121,112,101,69, - 114,114,111,114,114,45,0,0,0,114,14,0,0,0,114,182, - 0,0,0,114,79,0,0,0,169,3,114,17,0,0,0,114, - 183,0,0,0,114,184,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,13,95,115,97,110,105,116, - 121,95,99,104,101,99,107,169,3,0,0,115,22,0,0,0, - 0,2,10,1,18,1,8,1,8,1,8,1,10,1,10,1, - 4,1,8,2,12,1,114,197,0,0,0,122,16,78,111,32, - 109,111,100,117,108,101,32,110,97,109,101,100,32,122,4,123, - 33,114,125,99,2,0,0,0,0,0,0,0,8,0,0,0, - 8,0,0,0,67,0,0,0,115,220,0,0,0,100,0,125, - 2,124,0,160,0,100,1,161,1,100,2,25,0,125,3,124, - 3,114,134,124,3,116,1,106,2,107,7,114,42,116,3,124, - 1,124,3,131,2,1,0,124,0,116,1,106,2,107,6,114, - 62,116,1,106,2,124,0,25,0,83,0,116,1,106,2,124, - 3,25,0,125,4,122,10,124,4,106,4,125,2,87,0,110, - 50,4,0,116,5,107,10,114,132,1,0,1,0,1,0,116, - 6,100,3,23,0,160,7,124,0,124,3,161,2,125,5,116, - 8,124,5,124,0,100,4,141,2,100,0,130,2,89,0,110, - 2,88,0,116,9,124,0,124,2,131,2,125,6,124,6,100, - 0,107,8,114,172,116,8,116,6,160,7,124,0,161,1,124, - 0,100,4,141,2,130,1,110,8,116,10,124,6,131,1,125, - 7,124,3,114,216,116,1,106,2,124,3,25,0,125,4,116, - 11,124,4,124,0,160,0,100,1,161,1,100,5,25,0,124, - 7,131,3,1,0,124,7,83,0,41,6,78,114,128,0,0, - 0,114,22,0,0,0,122,23,59,32,123,33,114,125,32,105, - 115,32,110,111,116,32,97,32,112,97,99,107,97,103,101,114, - 16,0,0,0,233,2,0,0,0,41,12,114,129,0,0,0, - 114,15,0,0,0,114,92,0,0,0,114,67,0,0,0,114, - 141,0,0,0,114,106,0,0,0,218,8,95,69,82,82,95, - 77,83,71,114,45,0,0,0,218,19,77,111,100,117,108,101, - 78,111,116,70,111,117,110,100,69,114,114,111,114,114,192,0, - 0,0,114,159,0,0,0,114,5,0,0,0,41,8,114,17, - 0,0,0,218,7,105,109,112,111,114,116,95,114,164,0,0, - 0,114,130,0,0,0,90,13,112,97,114,101,110,116,95,109, - 111,100,117,108,101,114,157,0,0,0,114,95,0,0,0,114, - 96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,23,95,102,105,110,100,95,97,110,100,95,108, - 111,97,100,95,117,110,108,111,99,107,101,100,188,3,0,0, - 115,42,0,0,0,0,1,4,1,14,1,4,1,10,1,10, - 2,10,1,10,1,10,1,2,1,10,1,14,1,16,1,20, - 1,10,1,8,1,20,2,8,1,4,2,10,1,22,1,114, - 202,0,0,0,99,2,0,0,0,0,0,0,0,4,0,0, + 0,0,0,0,0,0,0,0,0,10,0,0,0,10,0,0, + 0,67,0,0,0,115,12,1,0,0,116,0,106,1,125,3, + 124,3,100,1,107,8,114,22,116,2,100,2,131,1,130,1, + 124,3,115,38,116,3,160,4,100,3,116,5,161,2,1,0, + 124,0,116,0,106,6,107,6,125,4,124,3,68,0,93,210, + 125,5,116,7,131,0,143,84,1,0,122,10,124,5,106,8, + 125,6,87,0,110,54,4,0,116,9,107,10,114,128,1,0, + 1,0,1,0,116,10,124,5,124,0,124,1,131,3,125,7, + 124,7,100,1,107,8,114,124,89,0,87,0,53,0,81,0, + 82,0,163,0,113,52,89,0,110,14,88,0,124,6,124,0, + 124,1,124,2,131,3,125,7,87,0,53,0,81,0,82,0, + 88,0,124,7,100,1,107,9,114,52,124,4,144,0,115,254, + 124,0,116,0,106,6,107,6,144,0,114,254,116,0,106,6, + 124,0,25,0,125,8,122,10,124,8,106,11,125,9,87,0, + 110,28,4,0,116,9,107,10,114,226,1,0,1,0,1,0, + 124,7,6,0,89,0,2,0,1,0,83,0,88,0,124,9, + 100,1,107,8,114,244,124,7,2,0,1,0,83,0,124,9, + 2,0,1,0,83,0,113,52,124,7,2,0,1,0,83,0, + 113,52,100,1,83,0,41,4,122,21,70,105,110,100,32,97, + 32,109,111,100,117,108,101,39,115,32,115,112,101,99,46,78, + 122,53,115,121,115,46,109,101,116,97,95,112,97,116,104,32, + 105,115,32,78,111,110,101,44,32,80,121,116,104,111,110,32, + 105,115,32,108,105,107,101,108,121,32,115,104,117,116,116,105, + 110,103,32,100,111,119,110,122,22,115,121,115,46,109,101,116, + 97,95,112,97,116,104,32,105,115,32,101,109,112,116,121,41, + 12,114,15,0,0,0,218,9,109,101,116,97,95,112,97,116, + 104,114,79,0,0,0,218,9,95,119,97,114,110,105,110,103, + 115,218,4,119,97,114,110,218,13,73,109,112,111,114,116,87, + 97,114,110,105,110,103,114,92,0,0,0,114,178,0,0,0, + 114,166,0,0,0,114,106,0,0,0,114,187,0,0,0,114, + 105,0,0,0,41,10,114,17,0,0,0,114,164,0,0,0, + 114,165,0,0,0,114,188,0,0,0,90,9,105,115,95,114, + 101,108,111,97,100,114,186,0,0,0,114,166,0,0,0,114, + 95,0,0,0,114,96,0,0,0,114,105,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,95, + 102,105,110,100,95,115,112,101,99,122,3,0,0,115,54,0, + 0,0,0,2,6,1,8,2,8,3,4,1,12,5,10,1, + 8,1,8,1,2,1,10,1,14,1,12,1,8,1,20,2, + 22,1,8,2,18,1,10,1,2,1,10,1,14,4,14,2, + 8,1,8,2,10,2,10,2,114,192,0,0,0,99,3,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,0, + 0,0,67,0,0,0,115,108,0,0,0,116,0,124,0,116, + 1,131,2,115,28,116,2,100,1,160,3,116,4,124,0,131, + 1,161,1,131,1,130,1,124,2,100,2,107,0,114,44,116, + 5,100,3,131,1,130,1,124,2,100,2,107,4,114,84,116, + 0,124,1,116,1,131,2,115,72,116,2,100,4,131,1,130, + 1,110,12,124,1,115,84,116,6,100,5,131,1,130,1,124, + 0,115,104,124,2,100,2,107,2,114,104,116,5,100,6,131, + 1,130,1,100,7,83,0,41,8,122,28,86,101,114,105,102, + 121,32,97,114,103,117,109,101,110,116,115,32,97,114,101,32, + 34,115,97,110,101,34,46,122,31,109,111,100,117,108,101,32, + 110,97,109,101,32,109,117,115,116,32,98,101,32,115,116,114, + 44,32,110,111,116,32,123,125,114,22,0,0,0,122,18,108, + 101,118,101,108,32,109,117,115,116,32,98,101,32,62,61,32, + 48,122,31,95,95,112,97,99,107,97,103,101,95,95,32,110, + 111,116,32,115,101,116,32,116,111,32,97,32,115,116,114,105, + 110,103,122,54,97,116,116,101,109,112,116,101,100,32,114,101, + 108,97,116,105,118,101,32,105,109,112,111,114,116,32,119,105, + 116,104,32,110,111,32,107,110,111,119,110,32,112,97,114,101, + 110,116,32,112,97,99,107,97,103,101,122,17,69,109,112,116, + 121,32,109,111,100,117,108,101,32,110,97,109,101,78,41,7, + 218,10,105,115,105,110,115,116,97,110,99,101,218,3,115,116, + 114,218,9,84,121,112,101,69,114,114,111,114,114,45,0,0, + 0,114,14,0,0,0,114,182,0,0,0,114,79,0,0,0, + 169,3,114,17,0,0,0,114,183,0,0,0,114,184,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,13,95,115,97,110,105,116,121,95,99,104,101,99,107,169, + 3,0,0,115,22,0,0,0,0,2,10,1,18,1,8,1, + 8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,197, + 0,0,0,122,16,78,111,32,109,111,100,117,108,101,32,110, + 97,109,101,100,32,122,4,123,33,114,125,99,2,0,0,0, + 0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0, + 67,0,0,0,115,220,0,0,0,100,0,125,2,124,0,160, + 0,100,1,161,1,100,2,25,0,125,3,124,3,114,134,124, + 3,116,1,106,2,107,7,114,42,116,3,124,1,124,3,131, + 2,1,0,124,0,116,1,106,2,107,6,114,62,116,1,106, + 2,124,0,25,0,83,0,116,1,106,2,124,3,25,0,125, + 4,122,10,124,4,106,4,125,2,87,0,110,50,4,0,116, + 5,107,10,114,132,1,0,1,0,1,0,116,6,100,3,23, + 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, + 0,100,4,141,2,100,0,130,2,89,0,110,2,88,0,116, + 9,124,0,124,2,131,2,125,6,124,6,100,0,107,8,114, + 172,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, + 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,114, + 216,116,1,106,2,124,3,25,0,125,4,116,11,124,4,124, + 0,160,0,100,1,161,1,100,5,25,0,124,7,131,3,1, + 0,124,7,83,0,41,6,78,114,128,0,0,0,114,22,0, + 0,0,122,23,59,32,123,33,114,125,32,105,115,32,110,111, + 116,32,97,32,112,97,99,107,97,103,101,114,16,0,0,0, + 233,2,0,0,0,41,12,114,129,0,0,0,114,15,0,0, + 0,114,92,0,0,0,114,67,0,0,0,114,141,0,0,0, + 114,106,0,0,0,218,8,95,69,82,82,95,77,83,71,114, + 45,0,0,0,218,19,77,111,100,117,108,101,78,111,116,70, + 111,117,110,100,69,114,114,111,114,114,192,0,0,0,114,159, + 0,0,0,114,5,0,0,0,41,8,114,17,0,0,0,218, + 7,105,109,112,111,114,116,95,114,164,0,0,0,114,130,0, + 0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108, + 101,114,157,0,0,0,114,95,0,0,0,114,96,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 23,95,102,105,110,100,95,97,110,100,95,108,111,97,100,95, + 117,110,108,111,99,107,101,100,188,3,0,0,115,42,0,0, + 0,0,1,4,1,14,1,4,1,10,1,10,2,10,1,10, + 1,10,1,2,1,10,1,14,1,16,1,20,1,10,1,8, + 1,20,2,8,1,4,2,10,1,22,1,114,202,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0, 0,10,0,0,0,67,0,0,0,115,106,0,0,0,116,0, 124,0,131,1,143,50,1,0,116,1,106,2,160,3,124,0, 116,4,161,2,125,2,124,2,116,4,107,8,114,54,116,5, @@ -1477,128 +1496,129 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 108,111,97,100,218,3,0,0,115,22,0,0,0,0,2,10, 1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12, 2,8,1,114,204,0,0,0,114,22,0,0,0,99,3,0, - 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, - 0,0,115,42,0,0,0,116,0,124,0,124,1,124,2,131, - 3,1,0,124,2,100,1,107,4,114,32,116,1,124,0,124, - 1,124,2,131,3,125,0,116,2,124,0,116,3,131,2,83, - 0,41,2,97,50,1,0,0,73,109,112,111,114,116,32,97, - 110,100,32,114,101,116,117,114,110,32,116,104,101,32,109,111, - 100,117,108,101,32,98,97,115,101,100,32,111,110,32,105,116, - 115,32,110,97,109,101,44,32,116,104,101,32,112,97,99,107, - 97,103,101,32,116,104,101,32,99,97,108,108,32,105,115,10, - 32,32,32,32,98,101,105,110,103,32,109,97,100,101,32,102, - 114,111,109,44,32,97,110,100,32,116,104,101,32,108,101,118, - 101,108,32,97,100,106,117,115,116,109,101,110,116,46,10,10, - 32,32,32,32,84,104,105,115,32,102,117,110,99,116,105,111, - 110,32,114,101,112,114,101,115,101,110,116,115,32,116,104,101, - 32,103,114,101,97,116,101,115,116,32,99,111,109,109,111,110, - 32,100,101,110,111,109,105,110,97,116,111,114,32,111,102,32, - 102,117,110,99,116,105,111,110,97,108,105,116,121,10,32,32, - 32,32,98,101,116,119,101,101,110,32,105,109,112,111,114,116, - 95,109,111,100,117,108,101,32,97,110,100,32,95,95,105,109, - 112,111,114,116,95,95,46,32,84,104,105,115,32,105,110,99, - 108,117,100,101,115,32,115,101,116,116,105,110,103,32,95,95, - 112,97,99,107,97,103,101,95,95,32,105,102,10,32,32,32, - 32,116,104,101,32,108,111,97,100,101,114,32,100,105,100,32, - 110,111,116,46,10,10,32,32,32,32,114,22,0,0,0,41, - 4,114,197,0,0,0,114,185,0,0,0,114,204,0,0,0, - 218,11,95,103,99,100,95,105,109,112,111,114,116,114,196,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,205,0,0,0,234,3,0,0,115,8,0,0,0,0, - 9,12,1,8,1,12,1,114,205,0,0,0,169,1,218,9, - 114,101,99,117,114,115,105,118,101,99,3,0,0,0,1,0, - 0,0,8,0,0,0,11,0,0,0,67,0,0,0,115,226, - 0,0,0,124,1,68,0,93,216,125,4,116,0,124,4,116, - 1,131,2,115,66,124,3,114,34,124,0,106,2,100,1,23, - 0,125,5,110,4,100,2,125,5,116,3,100,3,124,5,155, - 0,100,4,116,4,124,4,131,1,106,2,155,0,157,4,131, - 1,130,1,110,154,124,4,100,5,107,2,114,108,124,3,115, - 106,116,5,124,0,100,6,131,2,114,106,116,6,124,0,124, - 0,106,7,124,2,100,7,100,8,141,4,1,0,110,112,116, - 5,124,0,124,4,131,2,115,220,100,9,160,8,124,0,106, - 2,124,4,161,2,125,6,122,14,116,9,124,2,124,6,131, - 2,1,0,87,0,110,72,4,0,116,10,107,10,114,218,1, - 0,125,7,1,0,122,42,124,7,106,11,124,6,107,2,114, - 200,116,12,106,13,160,14,124,6,116,15,161,2,100,10,107, - 9,114,200,87,0,89,0,162,8,113,4,130,0,87,0,53, - 0,100,10,125,7,126,7,88,0,89,0,110,2,88,0,113, - 4,124,0,83,0,41,11,122,238,70,105,103,117,114,101,32, - 111,117,116,32,119,104,97,116,32,95,95,105,109,112,111,114, - 116,95,95,32,115,104,111,117,108,100,32,114,101,116,117,114, - 110,46,10,10,32,32,32,32,84,104,101,32,105,109,112,111, - 114,116,95,32,112,97,114,97,109,101,116,101,114,32,105,115, - 32,97,32,99,97,108,108,97,98,108,101,32,119,104,105,99, - 104,32,116,97,107,101,115,32,116,104,101,32,110,97,109,101, - 32,111,102,32,109,111,100,117,108,101,32,116,111,10,32,32, - 32,32,105,109,112,111,114,116,46,32,73,116,32,105,115,32, - 114,101,113,117,105,114,101,100,32,116,111,32,100,101,99,111, - 117,112,108,101,32,116,104,101,32,102,117,110,99,116,105,111, - 110,32,102,114,111,109,32,97,115,115,117,109,105,110,103,32, - 105,109,112,111,114,116,108,105,98,39,115,10,32,32,32,32, - 105,109,112,111,114,116,32,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,32,105,115,32,100,101,115,105,114,101,100, - 46,10,10,32,32,32,32,122,8,46,95,95,97,108,108,95, - 95,122,13,96,96,102,114,111,109,32,108,105,115,116,39,39, - 122,8,73,116,101,109,32,105,110,32,122,18,32,109,117,115, - 116,32,98,101,32,115,116,114,44,32,110,111,116,32,250,1, - 42,218,7,95,95,97,108,108,95,95,84,114,206,0,0,0, - 114,179,0,0,0,78,41,16,114,193,0,0,0,114,194,0, - 0,0,114,1,0,0,0,114,195,0,0,0,114,14,0,0, - 0,114,4,0,0,0,218,16,95,104,97,110,100,108,101,95, - 102,114,111,109,108,105,115,116,114,209,0,0,0,114,45,0, - 0,0,114,67,0,0,0,114,200,0,0,0,114,17,0,0, - 0,114,15,0,0,0,114,92,0,0,0,114,34,0,0,0, - 114,203,0,0,0,41,8,114,96,0,0,0,218,8,102,114, - 111,109,108,105,115,116,114,201,0,0,0,114,207,0,0,0, - 218,1,120,90,5,119,104,101,114,101,90,9,102,114,111,109, - 95,110,97,109,101,90,3,101,120,99,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,210,0,0,0,249,3, - 0,0,115,44,0,0,0,0,10,8,1,10,1,4,1,12, - 2,4,1,28,2,8,1,14,1,10,1,2,255,8,2,10, - 1,14,1,2,1,14,1,16,4,10,1,16,255,2,2,8, - 1,22,1,114,210,0,0,0,99,1,0,0,0,0,0,0, - 0,3,0,0,0,6,0,0,0,67,0,0,0,115,146,0, - 0,0,124,0,160,0,100,1,161,1,125,1,124,0,160,0, - 100,2,161,1,125,2,124,1,100,3,107,9,114,82,124,2, - 100,3,107,9,114,78,124,1,124,2,106,1,107,3,114,78, - 116,2,106,3,100,4,124,1,155,2,100,5,124,2,106,1, - 155,2,100,6,157,5,116,4,100,7,100,8,141,3,1,0, - 124,1,83,0,124,2,100,3,107,9,114,96,124,2,106,1, - 83,0,116,2,106,3,100,9,116,4,100,7,100,8,141,3, - 1,0,124,0,100,10,25,0,125,1,100,11,124,0,107,7, - 114,142,124,1,160,5,100,12,161,1,100,13,25,0,125,1, - 124,1,83,0,41,14,122,167,67,97,108,99,117,108,97,116, - 101,32,119,104,97,116,32,95,95,112,97,99,107,97,103,101, - 95,95,32,115,104,111,117,108,100,32,98,101,46,10,10,32, - 32,32,32,95,95,112,97,99,107,97,103,101,95,95,32,105, - 115,32,110,111,116,32,103,117,97,114,97,110,116,101,101,100, - 32,116,111,32,98,101,32,100,101,102,105,110,101,100,32,111, - 114,32,99,111,117,108,100,32,98,101,32,115,101,116,32,116, - 111,32,78,111,110,101,10,32,32,32,32,116,111,32,114,101, - 112,114,101,115,101,110,116,32,116,104,97,116,32,105,116,115, - 32,112,114,111,112,101,114,32,118,97,108,117,101,32,105,115, - 32,117,110,107,110,111,119,110,46,10,10,32,32,32,32,114, - 145,0,0,0,114,105,0,0,0,78,122,32,95,95,112,97, - 99,107,97,103,101,95,95,32,33,61,32,95,95,115,112,101, - 99,95,95,46,112,97,114,101,110,116,32,40,122,4,32,33, - 61,32,250,1,41,233,3,0,0,0,41,1,90,10,115,116, - 97,99,107,108,101,118,101,108,122,89,99,97,110,39,116,32, - 114,101,115,111,108,118,101,32,112,97,99,107,97,103,101,32, - 102,114,111,109,32,95,95,115,112,101,99,95,95,32,111,114, - 32,95,95,112,97,99,107,97,103,101,95,95,44,32,102,97, - 108,108,105,110,103,32,98,97,99,107,32,111,110,32,95,95, - 110,97,109,101,95,95,32,97,110,100,32,95,95,112,97,116, - 104,95,95,114,1,0,0,0,114,141,0,0,0,114,128,0, - 0,0,114,22,0,0,0,41,6,114,34,0,0,0,114,130, - 0,0,0,114,189,0,0,0,114,190,0,0,0,114,191,0, - 0,0,114,129,0,0,0,41,3,218,7,103,108,111,98,97, - 108,115,114,183,0,0,0,114,95,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,17,95,99,97, - 108,99,95,95,95,112,97,99,107,97,103,101,95,95,30,4, - 0,0,115,38,0,0,0,0,7,10,1,10,1,8,1,18, - 1,22,2,2,0,2,254,6,3,4,1,8,1,6,2,6, - 2,2,0,2,254,6,3,8,1,8,1,14,1,114,216,0, - 0,0,114,10,0,0,0,99,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,42,0,0,0,116,0,124,0,124, + 1,124,2,131,3,1,0,124,2,100,1,107,4,114,32,116, + 1,124,0,124,1,124,2,131,3,125,0,116,2,124,0,116, + 3,131,2,83,0,41,2,97,50,1,0,0,73,109,112,111, + 114,116,32,97,110,100,32,114,101,116,117,114,110,32,116,104, + 101,32,109,111,100,117,108,101,32,98,97,115,101,100,32,111, + 110,32,105,116,115,32,110,97,109,101,44,32,116,104,101,32, + 112,97,99,107,97,103,101,32,116,104,101,32,99,97,108,108, + 32,105,115,10,32,32,32,32,98,101,105,110,103,32,109,97, + 100,101,32,102,114,111,109,44,32,97,110,100,32,116,104,101, + 32,108,101,118,101,108,32,97,100,106,117,115,116,109,101,110, + 116,46,10,10,32,32,32,32,84,104,105,115,32,102,117,110, + 99,116,105,111,110,32,114,101,112,114,101,115,101,110,116,115, + 32,116,104,101,32,103,114,101,97,116,101,115,116,32,99,111, + 109,109,111,110,32,100,101,110,111,109,105,110,97,116,111,114, + 32,111,102,32,102,117,110,99,116,105,111,110,97,108,105,116, + 121,10,32,32,32,32,98,101,116,119,101,101,110,32,105,109, + 112,111,114,116,95,109,111,100,117,108,101,32,97,110,100,32, + 95,95,105,109,112,111,114,116,95,95,46,32,84,104,105,115, + 32,105,110,99,108,117,100,101,115,32,115,101,116,116,105,110, + 103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,102, + 10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,32, + 100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,22, + 0,0,0,41,4,114,197,0,0,0,114,185,0,0,0,114, + 204,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114, + 116,114,196,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,205,0,0,0,234,3,0,0,115,8, + 0,0,0,0,9,12,1,8,1,12,1,114,205,0,0,0, + 169,1,218,9,114,101,99,117,114,115,105,118,101,99,3,0, + 0,0,0,0,0,0,1,0,0,0,8,0,0,0,11,0, + 0,0,67,0,0,0,115,226,0,0,0,124,1,68,0,93, + 216,125,4,116,0,124,4,116,1,131,2,115,66,124,3,114, + 34,124,0,106,2,100,1,23,0,125,5,110,4,100,2,125, + 5,116,3,100,3,124,5,155,0,100,4,116,4,124,4,131, + 1,106,2,155,0,157,4,131,1,130,1,110,154,124,4,100, + 5,107,2,114,108,124,3,115,106,116,5,124,0,100,6,131, + 2,114,106,116,6,124,0,124,0,106,7,124,2,100,7,100, + 8,141,4,1,0,110,112,116,5,124,0,124,4,131,2,115, + 220,100,9,160,8,124,0,106,2,124,4,161,2,125,6,122, + 14,116,9,124,2,124,6,131,2,1,0,87,0,110,72,4, + 0,116,10,107,10,114,218,1,0,125,7,1,0,122,42,124, + 7,106,11,124,6,107,2,114,200,116,12,106,13,160,14,124, + 6,116,15,161,2,100,10,107,9,114,200,87,0,89,0,162, + 8,113,4,130,0,87,0,53,0,100,10,125,7,126,7,88, + 0,89,0,110,2,88,0,113,4,124,0,83,0,41,11,122, + 238,70,105,103,117,114,101,32,111,117,116,32,119,104,97,116, + 32,95,95,105,109,112,111,114,116,95,95,32,115,104,111,117, + 108,100,32,114,101,116,117,114,110,46,10,10,32,32,32,32, + 84,104,101,32,105,109,112,111,114,116,95,32,112,97,114,97, + 109,101,116,101,114,32,105,115,32,97,32,99,97,108,108,97, + 98,108,101,32,119,104,105,99,104,32,116,97,107,101,115,32, + 116,104,101,32,110,97,109,101,32,111,102,32,109,111,100,117, + 108,101,32,116,111,10,32,32,32,32,105,109,112,111,114,116, + 46,32,73,116,32,105,115,32,114,101,113,117,105,114,101,100, + 32,116,111,32,100,101,99,111,117,112,108,101,32,116,104,101, + 32,102,117,110,99,116,105,111,110,32,102,114,111,109,32,97, + 115,115,117,109,105,110,103,32,105,109,112,111,114,116,108,105, + 98,39,115,10,32,32,32,32,105,109,112,111,114,116,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,105,115, + 32,100,101,115,105,114,101,100,46,10,10,32,32,32,32,122, + 8,46,95,95,97,108,108,95,95,122,13,96,96,102,114,111, + 109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105, + 110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114, + 44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108, + 95,95,84,114,206,0,0,0,114,179,0,0,0,78,41,16, + 114,193,0,0,0,114,194,0,0,0,114,1,0,0,0,114, + 195,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16, + 95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116, + 114,209,0,0,0,114,45,0,0,0,114,67,0,0,0,114, + 200,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92, + 0,0,0,114,34,0,0,0,114,203,0,0,0,41,8,114, + 96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,201, + 0,0,0,114,207,0,0,0,218,1,120,90,5,119,104,101, + 114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101, + 120,99,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,210,0,0,0,249,3,0,0,115,44,0,0,0,0, + 10,8,1,10,1,4,1,12,2,4,1,28,2,8,1,14, + 1,10,1,2,255,8,2,10,1,14,1,2,1,14,1,16, + 4,10,1,16,255,2,2,8,1,22,1,114,210,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,6,0,0,0,67,0,0,0,115,146,0,0,0,124,0, + 160,0,100,1,161,1,125,1,124,0,160,0,100,2,161,1, + 125,2,124,1,100,3,107,9,114,82,124,2,100,3,107,9, + 114,78,124,1,124,2,106,1,107,3,114,78,116,2,106,3, + 100,4,124,1,155,2,100,5,124,2,106,1,155,2,100,6, + 157,5,116,4,100,7,100,8,141,3,1,0,124,1,83,0, + 124,2,100,3,107,9,114,96,124,2,106,1,83,0,116,2, + 106,3,100,9,116,4,100,7,100,8,141,3,1,0,124,0, + 100,10,25,0,125,1,100,11,124,0,107,7,114,142,124,1, + 160,5,100,12,161,1,100,13,25,0,125,1,124,1,83,0, + 41,14,122,167,67,97,108,99,117,108,97,116,101,32,119,104, + 97,116,32,95,95,112,97,99,107,97,103,101,95,95,32,115, + 104,111,117,108,100,32,98,101,46,10,10,32,32,32,32,95, + 95,112,97,99,107,97,103,101,95,95,32,105,115,32,110,111, + 116,32,103,117,97,114,97,110,116,101,101,100,32,116,111,32, + 98,101,32,100,101,102,105,110,101,100,32,111,114,32,99,111, + 117,108,100,32,98,101,32,115,101,116,32,116,111,32,78,111, + 110,101,10,32,32,32,32,116,111,32,114,101,112,114,101,115, + 101,110,116,32,116,104,97,116,32,105,116,115,32,112,114,111, + 112,101,114,32,118,97,108,117,101,32,105,115,32,117,110,107, + 110,111,119,110,46,10,10,32,32,32,32,114,145,0,0,0, + 114,105,0,0,0,78,122,32,95,95,112,97,99,107,97,103, + 101,95,95,32,33,61,32,95,95,115,112,101,99,95,95,46, + 112,97,114,101,110,116,32,40,122,4,32,33,61,32,250,1, + 41,233,3,0,0,0,41,1,90,10,115,116,97,99,107,108, + 101,118,101,108,122,89,99,97,110,39,116,32,114,101,115,111, + 108,118,101,32,112,97,99,107,97,103,101,32,102,114,111,109, + 32,95,95,115,112,101,99,95,95,32,111,114,32,95,95,112, + 97,99,107,97,103,101,95,95,44,32,102,97,108,108,105,110, + 103,32,98,97,99,107,32,111,110,32,95,95,110,97,109,101, + 95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114, + 1,0,0,0,114,141,0,0,0,114,128,0,0,0,114,22, + 0,0,0,41,6,114,34,0,0,0,114,130,0,0,0,114, + 189,0,0,0,114,190,0,0,0,114,191,0,0,0,114,129, + 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,183, + 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95, + 95,112,97,99,107,97,103,101,95,95,30,4,0,0,115,38, + 0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2, + 0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2, + 254,6,3,8,1,8,1,14,1,114,216,0,0,0,114,10, + 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, 9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0, 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, 5,110,36,124,1,100,2,107,9,114,30,124,1,110,2,105, @@ -1654,76 +1674,77 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8, 1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32, 1,10,1,12,2,114,219,0,0,0,99,1,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, - 38,0,0,0,116,0,160,1,124,0,161,1,125,1,124,1, - 100,0,107,8,114,30,116,2,100,1,124,0,23,0,131,1, - 130,1,116,3,124,1,131,1,83,0,41,2,78,122,25,110, - 111,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, - 101,32,110,97,109,101,100,32,41,4,114,160,0,0,0,114, - 166,0,0,0,114,79,0,0,0,114,159,0,0,0,41,2, - 114,17,0,0,0,114,95,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,18,95,98,117,105,108, - 116,105,110,95,102,114,111,109,95,110,97,109,101,94,4,0, - 0,115,8,0,0,0,0,1,10,1,8,1,12,1,114,220, - 0,0,0,99,2,0,0,0,0,0,0,0,10,0,0,0, - 5,0,0,0,67,0,0,0,115,166,0,0,0,124,1,97, - 0,124,0,97,1,116,2,116,1,131,1,125,2,116,1,106, - 3,160,4,161,0,68,0,93,72,92,2,125,3,125,4,116, - 5,124,4,124,2,131,2,114,26,124,3,116,1,106,6,107, - 6,114,60,116,7,125,5,110,18,116,0,160,8,124,3,161, - 1,114,26,116,9,125,5,110,2,113,26,116,10,124,4,124, - 5,131,2,125,6,116,11,124,6,124,4,131,2,1,0,113, - 26,116,1,106,3,116,12,25,0,125,7,100,1,68,0,93, - 46,125,8,124,8,116,1,106,3,107,7,114,138,116,13,124, - 8,131,1,125,9,110,10,116,1,106,3,124,8,25,0,125, - 9,116,14,124,7,124,8,124,9,131,3,1,0,113,114,100, - 2,83,0,41,3,122,250,83,101,116,117,112,32,105,109,112, - 111,114,116,108,105,98,32,98,121,32,105,109,112,111,114,116, - 105,110,103,32,110,101,101,100,101,100,32,98,117,105,108,116, - 45,105,110,32,109,111,100,117,108,101,115,32,97,110,100,32, - 105,110,106,101,99,116,105,110,103,32,116,104,101,109,10,32, - 32,32,32,105,110,116,111,32,116,104,101,32,103,108,111,98, - 97,108,32,110,97,109,101,115,112,97,99,101,46,10,10,32, - 32,32,32,65,115,32,115,121,115,32,105,115,32,110,101,101, - 100,101,100,32,102,111,114,32,115,121,115,46,109,111,100,117, - 108,101,115,32,97,99,99,101,115,115,32,97,110,100,32,95, - 105,109,112,32,105,115,32,110,101,101,100,101,100,32,116,111, - 32,108,111,97,100,32,98,117,105,108,116,45,105,110,10,32, - 32,32,32,109,111,100,117,108,101,115,44,32,116,104,111,115, - 101,32,116,119,111,32,109,111,100,117,108,101,115,32,109,117, - 115,116,32,98,101,32,101,120,112,108,105,99,105,116,108,121, - 32,112,97,115,115,101,100,32,105,110,46,10,10,32,32,32, - 32,41,3,114,23,0,0,0,114,189,0,0,0,114,64,0, - 0,0,78,41,15,114,57,0,0,0,114,15,0,0,0,114, - 14,0,0,0,114,92,0,0,0,218,5,105,116,101,109,115, - 114,193,0,0,0,114,78,0,0,0,114,160,0,0,0,114, - 88,0,0,0,114,173,0,0,0,114,142,0,0,0,114,148, - 0,0,0,114,1,0,0,0,114,220,0,0,0,114,5,0, - 0,0,41,10,218,10,115,121,115,95,109,111,100,117,108,101, - 218,11,95,105,109,112,95,109,111,100,117,108,101,90,11,109, - 111,100,117,108,101,95,116,121,112,101,114,17,0,0,0,114, - 96,0,0,0,114,109,0,0,0,114,95,0,0,0,90,11, - 115,101,108,102,95,109,111,100,117,108,101,90,12,98,117,105, - 108,116,105,110,95,110,97,109,101,90,14,98,117,105,108,116, - 105,110,95,109,111,100,117,108,101,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,6,95,115,101,116,117,112, - 101,4,0,0,115,36,0,0,0,0,9,4,1,4,3,8, - 1,18,1,10,1,10,1,6,1,10,1,6,2,2,1,10, - 1,12,3,10,1,8,1,10,1,10,2,10,1,114,224,0, - 0,0,99,2,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,67,0,0,0,115,38,0,0,0,116,0,124,0, - 124,1,131,2,1,0,116,1,106,2,160,3,116,4,161,1, - 1,0,116,1,106,2,160,3,116,5,161,1,1,0,100,1, - 83,0,41,2,122,48,73,110,115,116,97,108,108,32,105,109, - 112,111,114,116,101,114,115,32,102,111,114,32,98,117,105,108, - 116,105,110,32,97,110,100,32,102,114,111,122,101,110,32,109, - 111,100,117,108,101,115,78,41,6,114,224,0,0,0,114,15, - 0,0,0,114,188,0,0,0,114,120,0,0,0,114,160,0, - 0,0,114,173,0,0,0,41,2,114,222,0,0,0,114,223, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,8,95,105,110,115,116,97,108,108,136,4,0,0, - 115,6,0,0,0,0,2,10,2,12,1,114,225,0,0,0, - 99,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1, + 125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0, + 23,0,131,1,130,1,116,3,124,1,131,1,83,0,41,2, + 78,122,25,110,111,32,98,117,105,108,116,45,105,110,32,109, + 111,100,117,108,101,32,110,97,109,101,100,32,41,4,114,160, + 0,0,0,114,166,0,0,0,114,79,0,0,0,114,159,0, + 0,0,41,2,114,17,0,0,0,114,95,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, + 98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109, + 101,94,4,0,0,115,8,0,0,0,0,1,10,1,8,1, + 12,1,114,220,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,0, + 115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,116, + 1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,93, + 72,92,2,125,3,125,4,116,5,124,4,124,2,131,2,114, + 26,124,3,116,1,106,6,107,6,114,60,116,7,125,5,110, + 18,116,0,160,8,124,3,161,1,114,26,116,9,125,5,110, + 2,113,26,116,10,124,4,124,5,131,2,125,6,116,11,124, + 6,124,4,131,2,1,0,113,26,116,1,106,3,116,12,25, + 0,125,7,100,1,68,0,93,46,125,8,124,8,116,1,106, + 3,107,7,114,138,116,13,124,8,131,1,125,9,110,10,116, + 1,106,3,124,8,25,0,125,9,116,14,124,7,124,8,124, + 9,131,3,1,0,113,114,100,2,83,0,41,3,122,250,83, + 101,116,117,112,32,105,109,112,111,114,116,108,105,98,32,98, + 121,32,105,109,112,111,114,116,105,110,103,32,110,101,101,100, + 101,100,32,98,117,105,108,116,45,105,110,32,109,111,100,117, + 108,101,115,32,97,110,100,32,105,110,106,101,99,116,105,110, + 103,32,116,104,101,109,10,32,32,32,32,105,110,116,111,32, + 116,104,101,32,103,108,111,98,97,108,32,110,97,109,101,115, + 112,97,99,101,46,10,10,32,32,32,32,65,115,32,115,121, + 115,32,105,115,32,110,101,101,100,101,100,32,102,111,114,32, + 115,121,115,46,109,111,100,117,108,101,115,32,97,99,99,101, + 115,115,32,97,110,100,32,95,105,109,112,32,105,115,32,110, + 101,101,100,101,100,32,116,111,32,108,111,97,100,32,98,117, + 105,108,116,45,105,110,10,32,32,32,32,109,111,100,117,108, + 101,115,44,32,116,104,111,115,101,32,116,119,111,32,109,111, + 100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,120, + 112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,32, + 105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,0, + 114,189,0,0,0,114,64,0,0,0,78,41,15,114,57,0, + 0,0,114,15,0,0,0,114,14,0,0,0,114,92,0,0, + 0,218,5,105,116,101,109,115,114,193,0,0,0,114,78,0, + 0,0,114,160,0,0,0,114,88,0,0,0,114,173,0,0, + 0,114,142,0,0,0,114,148,0,0,0,114,1,0,0,0, + 114,220,0,0,0,114,5,0,0,0,41,10,218,10,115,121, + 115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109, + 111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121, + 112,101,114,17,0,0,0,114,96,0,0,0,114,109,0,0, + 0,114,95,0,0,0,90,11,115,101,108,102,95,109,111,100, + 117,108,101,90,12,98,117,105,108,116,105,110,95,110,97,109, + 101,90,14,98,117,105,108,116,105,110,95,109,111,100,117,108, + 101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,6,95,115,101,116,117,112,101,4,0,0,115,36,0,0, + 0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,6, + 1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,10, + 1,10,2,10,1,114,224,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2, + 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, + 106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,2, + 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, + 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, + 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, + 101,115,78,41,6,114,224,0,0,0,114,15,0,0,0,114, + 188,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173, + 0,0,0,41,2,114,222,0,0,0,114,223,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 95,105,110,115,116,97,108,108,136,4,0,0,115,6,0,0, + 0,0,2,10,2,12,1,114,225,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, 0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0, 125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5, 25,0,161,1,1,0,100,2,83,0,41,3,122,57,73,110, diff --git a/Python/importlib_external.h b/Python/importlib_external.h index ea4d8953490..b5b4df22805 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1,88 +1,89 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_bootstrap_external[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,64,0,0,0,115,52,2,0,0,100,0,90,0,100,1, - 90,1,100,2,90,2,101,2,101,1,23,0,90,3,100,3, - 100,4,132,0,90,4,100,5,100,6,132,0,90,5,100,7, - 100,8,132,0,90,6,100,9,100,10,132,0,90,7,100,11, - 100,12,132,0,90,8,100,13,100,14,132,0,90,9,100,15, - 100,16,132,0,90,10,100,17,100,18,132,0,90,11,100,19, - 100,20,132,0,90,12,100,21,100,22,132,0,90,13,100,23, - 100,24,132,0,90,14,100,25,102,1,100,26,100,27,132,1, - 90,15,101,16,101,15,106,17,131,1,90,18,100,28,160,19, - 100,29,100,30,161,2,100,31,23,0,90,20,101,21,160,22, - 101,20,100,30,161,2,90,23,100,32,90,24,100,33,90,25, - 100,34,103,1,90,26,100,35,103,1,90,27,101,27,4,0, - 90,28,90,29,100,36,102,1,100,36,100,37,156,1,100,38, - 100,39,132,3,90,30,100,40,100,41,132,0,90,31,100,42, - 100,43,132,0,90,32,100,44,100,45,132,0,90,33,100,46, - 100,47,132,0,90,34,100,48,100,49,132,0,90,35,100,50, - 100,51,132,0,90,36,100,52,100,53,132,0,90,37,100,54, - 100,55,132,0,90,38,100,56,100,57,132,0,90,39,100,36, - 100,36,100,36,102,3,100,58,100,59,132,1,90,40,100,60, - 100,60,102,2,100,61,100,62,132,1,90,41,100,63,102,1, - 100,64,100,65,132,1,90,42,100,66,100,67,132,0,90,43, - 101,44,131,0,90,45,100,36,102,1,100,36,101,45,100,68, - 156,2,100,69,100,70,132,3,90,46,71,0,100,71,100,72, - 132,0,100,72,131,2,90,47,71,0,100,73,100,74,132,0, - 100,74,131,2,90,48,71,0,100,75,100,76,132,0,100,76, - 101,48,131,3,90,49,71,0,100,77,100,78,132,0,100,78, - 131,2,90,50,71,0,100,79,100,80,132,0,100,80,101,50, - 101,49,131,4,90,51,71,0,100,81,100,82,132,0,100,82, - 101,50,101,48,131,4,90,52,103,0,90,53,71,0,100,83, - 100,84,132,0,100,84,101,50,101,48,131,4,90,54,71,0, - 100,85,100,86,132,0,100,86,131,2,90,55,71,0,100,87, - 100,88,132,0,100,88,131,2,90,56,71,0,100,89,100,90, - 132,0,100,90,131,2,90,57,71,0,100,91,100,92,132,0, - 100,92,131,2,90,58,100,36,102,1,100,93,100,94,132,1, - 90,59,100,95,100,96,132,0,90,60,100,97,100,98,132,0, - 90,61,100,99,100,100,132,0,90,62,100,36,83,0,41,101, - 97,94,1,0,0,67,111,114,101,32,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,32,111,102,32,112,97,116,104, - 45,98,97,115,101,100,32,105,109,112,111,114,116,46,10,10, - 84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,78, - 79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,100, - 105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,100, - 33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,101, - 115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,116, - 32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,115, - 116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,116, - 104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,112, - 111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,32, - 114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,106, - 101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,102, - 105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,97, - 116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,100, - 101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,32, - 115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,114, - 116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,108, - 105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,111, - 110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,101, - 46,10,10,41,1,218,3,119,105,110,41,2,90,6,99,121, - 103,119,105,110,90,6,100,97,114,119,105,110,99,0,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,3,0,0, - 0,115,60,0,0,0,116,0,106,1,160,2,116,3,161,1, - 114,48,116,0,106,1,160,2,116,4,161,1,114,30,100,1, - 137,0,110,4,100,2,137,0,135,0,102,1,100,3,100,4, - 132,8,125,0,110,8,100,5,100,4,132,0,125,0,124,0, - 83,0,41,6,78,90,12,80,89,84,72,79,78,67,65,83, - 69,79,75,115,12,0,0,0,80,89,84,72,79,78,67,65, - 83,69,79,75,99,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,19,0,0,0,115,10,0,0,0,136,0, - 116,0,106,1,107,6,83,0,41,1,250,53,84,114,117,101, - 32,105,102,32,102,105,108,101,110,97,109,101,115,32,109,117, - 115,116,32,98,101,32,99,104,101,99,107,101,100,32,99,97, - 115,101,45,105,110,115,101,110,115,105,116,105,118,101,108,121, - 46,41,2,218,3,95,111,115,90,7,101,110,118,105,114,111, - 110,169,0,169,1,218,3,107,101,121,114,3,0,0,0,250, - 38,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, - 105,98,46,95,98,111,111,116,115,116,114,97,112,95,101,120, - 116,101,114,110,97,108,62,218,11,95,114,101,108,97,120,95, - 99,97,115,101,36,0,0,0,115,2,0,0,0,0,2,122, - 37,95,109,97,107,101,95,114,101,108,97,120,95,99,97,115, - 101,46,60,108,111,99,97,108,115,62,46,95,114,101,108,97, - 120,95,99,97,115,101,99,0,0,0,0,0,0,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,64,0,0,0,115,52,2,0,0,100,0, + 90,0,100,1,90,1,100,2,90,2,101,2,101,1,23,0, + 90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,0, + 90,5,100,7,100,8,132,0,90,6,100,9,100,10,132,0, + 90,7,100,11,100,12,132,0,90,8,100,13,100,14,132,0, + 90,9,100,15,100,16,132,0,90,10,100,17,100,18,132,0, + 90,11,100,19,100,20,132,0,90,12,100,21,100,22,132,0, + 90,13,100,23,100,24,132,0,90,14,100,25,102,1,100,26, + 100,27,132,1,90,15,101,16,101,15,106,17,131,1,90,18, + 100,28,160,19,100,29,100,30,161,2,100,31,23,0,90,20, + 101,21,160,22,101,20,100,30,161,2,90,23,100,32,90,24, + 100,33,90,25,100,34,103,1,90,26,100,35,103,1,90,27, + 101,27,4,0,90,28,90,29,100,36,102,1,100,36,100,37, + 156,1,100,38,100,39,132,3,90,30,100,40,100,41,132,0, + 90,31,100,42,100,43,132,0,90,32,100,44,100,45,132,0, + 90,33,100,46,100,47,132,0,90,34,100,48,100,49,132,0, + 90,35,100,50,100,51,132,0,90,36,100,52,100,53,132,0, + 90,37,100,54,100,55,132,0,90,38,100,56,100,57,132,0, + 90,39,100,36,100,36,100,36,102,3,100,58,100,59,132,1, + 90,40,100,60,100,60,102,2,100,61,100,62,132,1,90,41, + 100,63,102,1,100,64,100,65,132,1,90,42,100,66,100,67, + 132,0,90,43,101,44,131,0,90,45,100,36,102,1,100,36, + 101,45,100,68,156,2,100,69,100,70,132,3,90,46,71,0, + 100,71,100,72,132,0,100,72,131,2,90,47,71,0,100,73, + 100,74,132,0,100,74,131,2,90,48,71,0,100,75,100,76, + 132,0,100,76,101,48,131,3,90,49,71,0,100,77,100,78, + 132,0,100,78,131,2,90,50,71,0,100,79,100,80,132,0, + 100,80,101,50,101,49,131,4,90,51,71,0,100,81,100,82, + 132,0,100,82,101,50,101,48,131,4,90,52,103,0,90,53, + 71,0,100,83,100,84,132,0,100,84,101,50,101,48,131,4, + 90,54,71,0,100,85,100,86,132,0,100,86,131,2,90,55, + 71,0,100,87,100,88,132,0,100,88,131,2,90,56,71,0, + 100,89,100,90,132,0,100,90,131,2,90,57,71,0,100,91, + 100,92,132,0,100,92,131,2,90,58,100,36,102,1,100,93, + 100,94,132,1,90,59,100,95,100,96,132,0,90,60,100,97, + 100,98,132,0,90,61,100,99,100,100,132,0,90,62,100,36, + 83,0,41,101,97,94,1,0,0,67,111,114,101,32,105,109, + 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, + 112,97,116,104,45,98,97,115,101,100,32,105,109,112,111,114, + 116,46,10,10,84,104,105,115,32,109,111,100,117,108,101,32, + 105,115,32,78,79,84,32,109,101,97,110,116,32,116,111,32, + 98,101,32,100,105,114,101,99,116,108,121,32,105,109,112,111, + 114,116,101,100,33,32,73,116,32,104,97,115,32,98,101,101, + 110,32,100,101,115,105,103,110,101,100,32,115,117,99,104,10, + 116,104,97,116,32,105,116,32,99,97,110,32,98,101,32,98, + 111,111,116,115,116,114,97,112,112,101,100,32,105,110,116,111, + 32,80,121,116,104,111,110,32,97,115,32,116,104,101,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, + 32,105,109,112,111,114,116,46,32,65,115,10,115,117,99,104, + 32,105,116,32,114,101,113,117,105,114,101,115,32,116,104,101, + 32,105,110,106,101,99,116,105,111,110,32,111,102,32,115,112, + 101,99,105,102,105,99,32,109,111,100,117,108,101,115,32,97, + 110,100,32,97,116,116,114,105,98,117,116,101,115,32,105,110, + 32,111,114,100,101,114,32,116,111,10,119,111,114,107,46,32, + 79,110,101,32,115,104,111,117,108,100,32,117,115,101,32,105, + 109,112,111,114,116,108,105,98,32,97,115,32,116,104,101,32, + 112,117,98,108,105,99,45,102,97,99,105,110,103,32,118,101, + 114,115,105,111,110,32,111,102,32,116,104,105,115,32,109,111, + 100,117,108,101,46,10,10,41,1,218,3,119,105,110,41,2, + 90,6,99,121,103,119,105,110,90,6,100,97,114,119,105,110, + 99,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,3,0,0,0,115,60,0,0,0,116,0, + 106,1,160,2,116,3,161,1,114,48,116,0,106,1,160,2, + 116,4,161,1,114,30,100,1,137,0,110,4,100,2,137,0, + 135,0,102,1,100,3,100,4,132,8,125,0,110,8,100,5, + 100,4,132,0,125,0,124,0,83,0,41,6,78,90,12,80, + 89,84,72,79,78,67,65,83,69,79,75,115,12,0,0,0, + 80,89,84,72,79,78,67,65,83,69,79,75,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,19,0,0,0,115,10,0,0,0,136,0,116,0,106,1, + 107,6,83,0,41,1,250,53,84,114,117,101,32,105,102,32, + 102,105,108,101,110,97,109,101,115,32,109,117,115,116,32,98, + 101,32,99,104,101,99,107,101,100,32,99,97,115,101,45,105, + 110,115,101,110,115,105,116,105,118,101,108,121,46,41,2,218, + 3,95,111,115,90,7,101,110,118,105,114,111,110,169,0,169, + 1,218,3,107,101,121,114,3,0,0,0,250,38,60,102,114, + 111,122,101,110,32,105,109,112,111,114,116,108,105,98,46,95, + 98,111,111,116,115,116,114,97,112,95,101,120,116,101,114,110, + 97,108,62,218,11,95,114,101,108,97,120,95,99,97,115,101, + 36,0,0,0,115,2,0,0,0,0,2,122,37,95,109,97, + 107,101,95,114,101,108,97,120,95,99,97,115,101,46,60,108, + 111,99,97,108,115,62,46,95,114,101,108,97,120,95,99,97, + 115,101,99,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,83,0,0,0,115,4,0,0,0, 100,1,83,0,41,2,114,1,0,0,0,70,114,3,0,0, 0,114,3,0,0,0,114,3,0,0,0,114,3,0,0,0, @@ -98,96 +99,98 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,95,114,101,108,97,120,95,99,97,115,101,29,0,0,0, 115,14,0,0,0,0,1,12,1,12,1,6,2,4,2,14, 4,8,3,114,13,0,0,0,99,1,0,0,0,0,0,0, - 0,1,0,0,0,4,0,0,0,67,0,0,0,115,20,0, - 0,0,116,0,124,0,131,1,100,1,64,0,160,1,100,2, - 100,3,161,2,83,0,41,4,122,42,67,111,110,118,101,114, - 116,32,97,32,51,50,45,98,105,116,32,105,110,116,101,103, - 101,114,32,116,111,32,108,105,116,116,108,101,45,101,110,100, - 105,97,110,46,236,3,0,0,0,255,127,255,127,3,0,233, - 4,0,0,0,218,6,108,105,116,116,108,101,41,2,218,3, - 105,110,116,218,8,116,111,95,98,121,116,101,115,41,1,218, - 1,120,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,12,95,112,97,99,107,95,117,105,110,116,51,50,46, - 0,0,0,115,2,0,0,0,0,2,114,20,0,0,0,99, - 1,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, + 0,115,20,0,0,0,116,0,124,0,131,1,100,1,64,0, + 160,1,100,2,100,3,161,2,83,0,41,4,122,42,67,111, + 110,118,101,114,116,32,97,32,51,50,45,98,105,116,32,105, + 110,116,101,103,101,114,32,116,111,32,108,105,116,116,108,101, + 45,101,110,100,105,97,110,46,236,3,0,0,0,255,127,255, + 127,3,0,233,4,0,0,0,218,6,108,105,116,116,108,101, + 41,2,218,3,105,110,116,218,8,116,111,95,98,121,116,101, + 115,41,1,218,1,120,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,12,95,112,97,99,107,95,117,105,110, + 116,51,50,46,0,0,0,115,2,0,0,0,0,2,114,20, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0, + 0,116,0,124,0,131,1,100,1,107,2,115,16,116,1,130, + 1,116,2,160,3,124,0,100,2,161,2,83,0,41,3,122, + 47,67,111,110,118,101,114,116,32,52,32,98,121,116,101,115, + 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97, + 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46, + 114,15,0,0,0,114,16,0,0,0,169,4,218,3,108,101, + 110,218,14,65,115,115,101,114,116,105,111,110,69,114,114,111, + 114,114,17,0,0,0,218,10,102,114,111,109,95,98,121,116, + 101,115,169,1,218,4,100,97,116,97,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,14,95,117,110,112,97, + 99,107,95,117,105,110,116,51,50,51,0,0,0,115,4,0, + 0,0,0,2,16,1,114,27,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, 67,0,0,0,115,28,0,0,0,116,0,124,0,131,1,100, 1,107,2,115,16,116,1,130,1,116,2,160,3,124,0,100, 2,161,2,83,0,41,3,122,47,67,111,110,118,101,114,116, - 32,52,32,98,121,116,101,115,32,105,110,32,108,105,116,116, + 32,50,32,98,121,116,101,115,32,105,110,32,108,105,116,116, 108,101,45,101,110,100,105,97,110,32,116,111,32,97,110,32, - 105,110,116,101,103,101,114,46,114,15,0,0,0,114,16,0, - 0,0,169,4,218,3,108,101,110,218,14,65,115,115,101,114, - 116,105,111,110,69,114,114,111,114,114,17,0,0,0,218,10, - 102,114,111,109,95,98,121,116,101,115,169,1,218,4,100,97, - 116,97,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,14,95,117,110,112,97,99,107,95,117,105,110,116,51, - 50,51,0,0,0,115,4,0,0,0,0,2,16,1,114,27, - 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, - 4,0,0,0,67,0,0,0,115,28,0,0,0,116,0,124, - 0,131,1,100,1,107,2,115,16,116,1,130,1,116,2,160, - 3,124,0,100,2,161,2,83,0,41,3,122,47,67,111,110, - 118,101,114,116,32,50,32,98,121,116,101,115,32,105,110,32, - 108,105,116,116,108,101,45,101,110,100,105,97,110,32,116,111, - 32,97,110,32,105,110,116,101,103,101,114,46,233,2,0,0, - 0,114,16,0,0,0,114,21,0,0,0,114,25,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 14,95,117,110,112,97,99,107,95,117,105,110,116,49,54,56, - 0,0,0,115,4,0,0,0,0,2,16,1,114,29,0,0, - 0,99,0,0,0,0,0,0,0,0,1,0,0,0,4,0, + 105,110,116,101,103,101,114,46,233,2,0,0,0,114,16,0, + 0,0,114,21,0,0,0,114,25,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,14,95,117,110, + 112,97,99,107,95,117,105,110,116,49,54,56,0,0,0,115, + 4,0,0,0,0,2,16,1,114,29,0,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, 0,0,71,0,0,0,115,20,0,0,0,116,0,160,1,100, 1,100,2,132,0,124,0,68,0,131,1,161,1,83,0,41, 3,122,31,82,101,112,108,97,99,101,109,101,110,116,32,102, 111,114,32,111,115,46,112,97,116,104,46,106,111,105,110,40, - 41,46,99,1,0,0,0,0,0,0,0,2,0,0,0,5, - 0,0,0,83,0,0,0,115,26,0,0,0,103,0,124,0, - 93,18,125,1,124,1,114,22,124,1,160,0,116,1,161,1, - 145,2,113,4,83,0,114,3,0,0,0,41,2,218,6,114, - 115,116,114,105,112,218,15,112,97,116,104,95,115,101,112,97, - 114,97,116,111,114,115,41,2,218,2,46,48,218,4,112,97, - 114,116,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,10,60,108,105,115,116,99,111,109,112,62,64,0,0, - 0,115,6,0,0,0,6,1,2,0,4,255,122,30,95,112, - 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115, - 62,46,60,108,105,115,116,99,111,109,112,62,41,2,218,8, - 112,97,116,104,95,115,101,112,218,4,106,111,105,110,41,1, - 218,10,112,97,116,104,95,112,97,114,116,115,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,10,95,112,97, - 116,104,95,106,111,105,110,62,0,0,0,115,6,0,0,0, - 0,2,10,1,2,255,114,38,0,0,0,99,1,0,0,0, - 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,96,0,0,0,116,0,116,1,131,1,100,1,107,2,114, - 36,124,0,160,2,116,3,161,1,92,3,125,1,125,2,125, - 3,124,1,124,3,102,2,83,0,116,4,124,0,131,1,68, - 0,93,42,125,4,124,4,116,1,107,6,114,44,124,0,106, - 5,124,4,100,1,100,2,141,2,92,2,125,1,125,3,124, - 1,124,3,102,2,2,0,1,0,83,0,113,44,100,3,124, - 0,102,2,83,0,41,4,122,32,82,101,112,108,97,99,101, - 109,101,110,116,32,102,111,114,32,111,115,46,112,97,116,104, - 46,115,112,108,105,116,40,41,46,233,1,0,0,0,41,1, - 90,8,109,97,120,115,112,108,105,116,218,0,41,6,114,22, - 0,0,0,114,31,0,0,0,218,10,114,112,97,114,116,105, - 116,105,111,110,114,35,0,0,0,218,8,114,101,118,101,114, - 115,101,100,218,6,114,115,112,108,105,116,41,5,218,4,112, - 97,116,104,90,5,102,114,111,110,116,218,1,95,218,4,116, - 97,105,108,114,19,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,11,95,112,97,116,104,95,115, - 112,108,105,116,68,0,0,0,115,16,0,0,0,0,2,12, - 1,16,1,8,1,12,1,8,1,18,1,14,1,114,47,0, - 0,0,99,1,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,10,0,0,0,116,0,160,1, - 124,0,161,1,83,0,41,1,122,126,83,116,97,116,32,116, - 104,101,32,112,97,116,104,46,10,10,32,32,32,32,77,97, - 100,101,32,97,32,115,101,112,97,114,97,116,101,32,102,117, - 110,99,116,105,111,110,32,116,111,32,109,97,107,101,32,105, - 116,32,101,97,115,105,101,114,32,116,111,32,111,118,101,114, - 114,105,100,101,32,105,110,32,101,120,112,101,114,105,109,101, - 110,116,115,10,32,32,32,32,40,101,46,103,46,32,99,97, - 99,104,101,32,115,116,97,116,32,114,101,115,117,108,116,115, - 41,46,10,10,32,32,32,32,41,2,114,2,0,0,0,90, - 4,115,116,97,116,169,1,114,44,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,10,95,112,97, - 116,104,95,115,116,97,116,80,0,0,0,115,2,0,0,0, - 0,7,114,49,0,0,0,99,2,0,0,0,0,0,0,0, + 41,46,99,1,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,5,0,0,0,83,0,0,0,115,26,0,0,0, + 103,0,124,0,93,18,125,1,124,1,114,22,124,1,160,0, + 116,1,161,1,145,2,113,4,83,0,114,3,0,0,0,41, + 2,218,6,114,115,116,114,105,112,218,15,112,97,116,104,95, + 115,101,112,97,114,97,116,111,114,115,41,2,218,2,46,48, + 218,4,112,97,114,116,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,10,60,108,105,115,116,99,111,109,112, + 62,64,0,0,0,115,6,0,0,0,6,1,2,0,4,255, + 122,30,95,112,97,116,104,95,106,111,105,110,46,60,108,111, + 99,97,108,115,62,46,60,108,105,115,116,99,111,109,112,62, + 41,2,218,8,112,97,116,104,95,115,101,112,218,4,106,111, + 105,110,41,1,218,10,112,97,116,104,95,112,97,114,116,115, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 10,95,112,97,116,104,95,106,111,105,110,62,0,0,0,115, + 6,0,0,0,0,2,10,1,2,255,114,38,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, + 5,0,0,0,67,0,0,0,115,96,0,0,0,116,0,116, + 1,131,1,100,1,107,2,114,36,124,0,160,2,116,3,161, + 1,92,3,125,1,125,2,125,3,124,1,124,3,102,2,83, + 0,116,4,124,0,131,1,68,0,93,42,125,4,124,4,116, + 1,107,6,114,44,124,0,106,5,124,4,100,1,100,2,141, + 2,92,2,125,1,125,3,124,1,124,3,102,2,2,0,1, + 0,83,0,113,44,100,3,124,0,102,2,83,0,41,4,122, + 32,82,101,112,108,97,99,101,109,101,110,116,32,102,111,114, + 32,111,115,46,112,97,116,104,46,115,112,108,105,116,40,41, + 46,233,1,0,0,0,41,1,90,8,109,97,120,115,112,108, + 105,116,218,0,41,6,114,22,0,0,0,114,31,0,0,0, + 218,10,114,112,97,114,116,105,116,105,111,110,114,35,0,0, + 0,218,8,114,101,118,101,114,115,101,100,218,6,114,115,112, + 108,105,116,41,5,218,4,112,97,116,104,90,5,102,114,111, + 110,116,218,1,95,218,4,116,97,105,108,114,19,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 11,95,112,97,116,104,95,115,112,108,105,116,68,0,0,0, + 115,16,0,0,0,0,2,12,1,16,1,8,1,12,1,8, + 1,18,1,14,1,114,47,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,10,0,0,0,116,0,160,1,124,0,161,1, + 83,0,41,1,122,126,83,116,97,116,32,116,104,101,32,112, + 97,116,104,46,10,10,32,32,32,32,77,97,100,101,32,97, + 32,115,101,112,97,114,97,116,101,32,102,117,110,99,116,105, + 111,110,32,116,111,32,109,97,107,101,32,105,116,32,101,97, + 115,105,101,114,32,116,111,32,111,118,101,114,114,105,100,101, + 32,105,110,32,101,120,112,101,114,105,109,101,110,116,115,10, + 32,32,32,32,40,101,46,103,46,32,99,97,99,104,101,32, + 115,116,97,116,32,114,101,115,117,108,116,115,41,46,10,10, + 32,32,32,32,41,2,114,2,0,0,0,90,4,115,116,97, + 116,169,1,114,44,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,10,95,112,97,116,104,95,115, + 116,97,116,80,0,0,0,115,2,0,0,0,0,7,114,49, + 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, 3,0,0,0,8,0,0,0,67,0,0,0,115,50,0,0, 0,122,12,116,0,124,0,131,1,125,2,87,0,110,22,4, 0,116,1,107,10,114,34,1,0,1,0,1,0,89,0,100, @@ -203,43 +206,44 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 95,112,97,116,104,95,105,115,95,109,111,100,101,95,116,121, 112,101,90,0,0,0,115,10,0,0,0,0,2,2,1,12, 1,14,1,8,1,114,53,0,0,0,99,1,0,0,0,0, - 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, - 10,0,0,0,116,0,124,0,100,1,131,2,83,0,41,2, - 122,31,82,101,112,108,97,99,101,109,101,110,116,32,102,111, - 114,32,111,115,46,112,97,116,104,46,105,115,102,105,108,101, - 46,105,0,128,0,0,41,1,114,53,0,0,0,114,48,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,10,0,0,0,116,0,124,0,100,1,131,2, + 83,0,41,2,122,31,82,101,112,108,97,99,101,109,101,110, + 116,32,102,111,114,32,111,115,46,112,97,116,104,46,105,115, + 102,105,108,101,46,105,0,128,0,0,41,1,114,53,0,0, + 0,114,48,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,12,95,112,97,116,104,95,105,115,102, + 105,108,101,99,0,0,0,115,2,0,0,0,0,2,114,54, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,115,22,0,0, + 0,124,0,115,12,116,0,160,1,161,0,125,0,116,2,124, + 0,100,1,131,2,83,0,41,2,122,30,82,101,112,108,97, + 99,101,109,101,110,116,32,102,111,114,32,111,115,46,112,97, + 116,104,46,105,115,100,105,114,46,105,0,64,0,0,41,3, + 114,2,0,0,0,218,6,103,101,116,99,119,100,114,53,0, + 0,0,114,48,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,11,95,112,97,116,104,95,105,115, + 100,105,114,104,0,0,0,115,6,0,0,0,0,2,4,1, + 8,1,114,56,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,26,0,0,0,124,0,160,0,116,1,161,1,112,24,124, + 0,100,1,100,2,133,2,25,0,116,2,107,6,83,0,41, + 3,122,142,82,101,112,108,97,99,101,109,101,110,116,32,102, + 111,114,32,111,115,46,112,97,116,104,46,105,115,97,98,115, + 46,10,10,32,32,32,32,67,111,110,115,105,100,101,114,115, + 32,97,32,87,105,110,100,111,119,115,32,100,114,105,118,101, + 45,114,101,108,97,116,105,118,101,32,112,97,116,104,32,40, + 110,111,32,100,114,105,118,101,44,32,98,117,116,32,115,116, + 97,114,116,115,32,119,105,116,104,32,115,108,97,115,104,41, + 32,116,111,10,32,32,32,32,115,116,105,108,108,32,98,101, + 32,34,97,98,115,111,108,117,116,101,34,46,10,32,32,32, + 32,114,39,0,0,0,233,3,0,0,0,41,3,114,10,0, + 0,0,114,31,0,0,0,218,20,95,112,97,116,104,115,101, + 112,115,95,119,105,116,104,95,99,111,108,111,110,114,48,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,12,95,112,97,116,104,95,105,115,102,105,108,101,99, - 0,0,0,115,2,0,0,0,0,2,114,54,0,0,0,99, - 1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, - 67,0,0,0,115,22,0,0,0,124,0,115,12,116,0,160, - 1,161,0,125,0,116,2,124,0,100,1,131,2,83,0,41, - 2,122,30,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,105,115,100,105,114, - 46,105,0,64,0,0,41,3,114,2,0,0,0,218,6,103, - 101,116,99,119,100,114,53,0,0,0,114,48,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,11, - 95,112,97,116,104,95,105,115,100,105,114,104,0,0,0,115, - 6,0,0,0,0,2,4,1,8,1,114,56,0,0,0,99, - 1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, - 67,0,0,0,115,26,0,0,0,124,0,160,0,116,1,161, - 1,112,24,124,0,100,1,100,2,133,2,25,0,116,2,107, - 6,83,0,41,3,122,142,82,101,112,108,97,99,101,109,101, - 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,105, - 115,97,98,115,46,10,10,32,32,32,32,67,111,110,115,105, - 100,101,114,115,32,97,32,87,105,110,100,111,119,115,32,100, - 114,105,118,101,45,114,101,108,97,116,105,118,101,32,112,97, - 116,104,32,40,110,111,32,100,114,105,118,101,44,32,98,117, - 116,32,115,116,97,114,116,115,32,119,105,116,104,32,115,108, - 97,115,104,41,32,116,111,10,32,32,32,32,115,116,105,108, - 108,32,98,101,32,34,97,98,115,111,108,117,116,101,34,46, - 10,32,32,32,32,114,39,0,0,0,233,3,0,0,0,41, - 3,114,10,0,0,0,114,31,0,0,0,218,20,95,112,97, - 116,104,115,101,112,115,95,119,105,116,104,95,99,111,108,111, - 110,114,48,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,11,95,112,97,116,104,95,105,115,97, - 98,115,111,0,0,0,115,2,0,0,0,0,6,114,59,0, - 0,0,233,182,1,0,0,99,3,0,0,0,0,0,0,0, + 0,218,11,95,112,97,116,104,95,105,115,97,98,115,111,0, + 0,0,115,2,0,0,0,0,6,114,59,0,0,0,233,182, + 1,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, 6,0,0,0,11,0,0,0,67,0,0,0,115,162,0,0, 0,100,1,160,0,124,0,116,1,124,0,131,1,161,2,125, 3,116,2,160,3,124,3,116,2,106,4,116,2,106,5,66, @@ -275,239 +279,240 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,105,116,101,95,97,116,111,109,105,99,120,0,0,0,115, 30,0,0,0,0,5,16,1,6,1,16,0,6,255,4,2, 2,3,14,1,20,1,16,1,14,1,2,1,14,1,14,1, - 6,1,114,69,0,0,0,105,73,13,0,0,114,28,0,0, + 6,1,114,69,0,0,0,105,82,13,0,0,114,28,0,0, 0,114,16,0,0,0,115,2,0,0,0,13,10,90,11,95, 95,112,121,99,97,99,104,101,95,95,122,4,111,112,116,45, 122,3,46,112,121,122,4,46,112,121,99,78,41,1,218,12, 111,112,116,105,109,105,122,97,116,105,111,110,99,2,0,0, - 0,1,0,0,0,12,0,0,0,5,0,0,0,67,0,0, - 0,115,88,1,0,0,124,1,100,1,107,9,114,52,116,0, - 160,1,100,2,116,2,161,2,1,0,124,2,100,1,107,9, - 114,40,100,3,125,3,116,3,124,3,131,1,130,1,124,1, - 114,48,100,4,110,2,100,5,125,2,116,4,160,5,124,0, - 161,1,125,0,116,6,124,0,131,1,92,2,125,4,125,5, - 124,5,160,7,100,6,161,1,92,3,125,6,125,7,125,8, - 116,8,106,9,106,10,125,9,124,9,100,1,107,8,114,114, - 116,11,100,7,131,1,130,1,100,4,160,12,124,6,114,126, - 124,6,110,2,124,8,124,7,124,9,103,3,161,1,125,10, - 124,2,100,1,107,8,114,172,116,8,106,13,106,14,100,8, - 107,2,114,164,100,4,125,2,110,8,116,8,106,13,106,14, - 125,2,116,15,124,2,131,1,125,2,124,2,100,4,107,3, - 114,224,124,2,160,16,161,0,115,210,116,17,100,9,160,18, - 124,2,161,1,131,1,130,1,100,10,160,18,124,10,116,19, - 124,2,161,3,125,10,124,10,116,20,100,8,25,0,23,0, - 125,11,116,8,106,21,100,1,107,9,144,1,114,76,116,22, - 124,4,131,1,144,1,115,16,116,23,116,4,160,24,161,0, - 124,4,131,2,125,4,124,4,100,5,25,0,100,11,107,2, - 144,1,114,56,124,4,100,8,25,0,116,25,107,7,144,1, - 114,56,124,4,100,12,100,1,133,2,25,0,125,4,116,23, - 116,8,106,21,124,4,160,26,116,25,161,1,124,11,131,3, - 83,0,116,23,124,4,116,27,124,11,131,3,83,0,41,13, - 97,254,2,0,0,71,105,118,101,110,32,116,104,101,32,112, - 97,116,104,32,116,111,32,97,32,46,112,121,32,102,105,108, - 101,44,32,114,101,116,117,114,110,32,116,104,101,32,112,97, - 116,104,32,116,111,32,105,116,115,32,46,112,121,99,32,102, - 105,108,101,46,10,10,32,32,32,32,84,104,101,32,46,112, - 121,32,102,105,108,101,32,100,111,101,115,32,110,111,116,32, - 110,101,101,100,32,116,111,32,101,120,105,115,116,59,32,116, - 104,105,115,32,115,105,109,112,108,121,32,114,101,116,117,114, - 110,115,32,116,104,101,32,112,97,116,104,32,116,111,32,116, - 104,101,10,32,32,32,32,46,112,121,99,32,102,105,108,101, - 32,99,97,108,99,117,108,97,116,101,100,32,97,115,32,105, - 102,32,116,104,101,32,46,112,121,32,102,105,108,101,32,119, - 101,114,101,32,105,109,112,111,114,116,101,100,46,10,10,32, - 32,32,32,84,104,101,32,39,111,112,116,105,109,105,122,97, - 116,105,111,110,39,32,112,97,114,97,109,101,116,101,114,32, - 99,111,110,116,114,111,108,115,32,116,104,101,32,112,114,101, - 115,117,109,101,100,32,111,112,116,105,109,105,122,97,116,105, - 111,110,32,108,101,118,101,108,32,111,102,10,32,32,32,32, - 116,104,101,32,98,121,116,101,99,111,100,101,32,102,105,108, - 101,46,32,73,102,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,105,115,32,110,111,116,32,78,111,110,101, - 44,32,116,104,101,32,115,116,114,105,110,103,32,114,101,112, - 114,101,115,101,110,116,97,116,105,111,110,10,32,32,32,32, - 111,102,32,116,104,101,32,97,114,103,117,109,101,110,116,32, - 105,115,32,116,97,107,101,110,32,97,110,100,32,118,101,114, - 105,102,105,101,100,32,116,111,32,98,101,32,97,108,112,104, - 97,110,117,109,101,114,105,99,32,40,101,108,115,101,32,86, - 97,108,117,101,69,114,114,111,114,10,32,32,32,32,105,115, - 32,114,97,105,115,101,100,41,46,10,10,32,32,32,32,84, - 104,101,32,100,101,98,117,103,95,111,118,101,114,114,105,100, - 101,32,112,97,114,97,109,101,116,101,114,32,105,115,32,100, - 101,112,114,101,99,97,116,101,100,46,32,73,102,32,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,32,105,115,32, - 110,111,116,32,78,111,110,101,44,10,32,32,32,32,97,32, - 84,114,117,101,32,118,97,108,117,101,32,105,115,32,116,104, - 101,32,115,97,109,101,32,97,115,32,115,101,116,116,105,110, - 103,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, - 32,116,111,32,116,104,101,32,101,109,112,116,121,32,115,116, - 114,105,110,103,10,32,32,32,32,119,104,105,108,101,32,97, - 32,70,97,108,115,101,32,118,97,108,117,101,32,105,115,32, - 101,113,117,105,118,97,108,101,110,116,32,116,111,32,115,101, + 0,0,0,0,0,1,0,0,0,12,0,0,0,5,0,0, + 0,67,0,0,0,115,88,1,0,0,124,1,100,1,107,9, + 114,52,116,0,160,1,100,2,116,2,161,2,1,0,124,2, + 100,1,107,9,114,40,100,3,125,3,116,3,124,3,131,1, + 130,1,124,1,114,48,100,4,110,2,100,5,125,2,116,4, + 160,5,124,0,161,1,125,0,116,6,124,0,131,1,92,2, + 125,4,125,5,124,5,160,7,100,6,161,1,92,3,125,6, + 125,7,125,8,116,8,106,9,106,10,125,9,124,9,100,1, + 107,8,114,114,116,11,100,7,131,1,130,1,100,4,160,12, + 124,6,114,126,124,6,110,2,124,8,124,7,124,9,103,3, + 161,1,125,10,124,2,100,1,107,8,114,172,116,8,106,13, + 106,14,100,8,107,2,114,164,100,4,125,2,110,8,116,8, + 106,13,106,14,125,2,116,15,124,2,131,1,125,2,124,2, + 100,4,107,3,114,224,124,2,160,16,161,0,115,210,116,17, + 100,9,160,18,124,2,161,1,131,1,130,1,100,10,160,18, + 124,10,116,19,124,2,161,3,125,10,124,10,116,20,100,8, + 25,0,23,0,125,11,116,8,106,21,100,1,107,9,144,1, + 114,76,116,22,124,4,131,1,144,1,115,16,116,23,116,4, + 160,24,161,0,124,4,131,2,125,4,124,4,100,5,25,0, + 100,11,107,2,144,1,114,56,124,4,100,8,25,0,116,25, + 107,7,144,1,114,56,124,4,100,12,100,1,133,2,25,0, + 125,4,116,23,116,8,106,21,124,4,160,26,116,25,161,1, + 124,11,131,3,83,0,116,23,124,4,116,27,124,11,131,3, + 83,0,41,13,97,254,2,0,0,71,105,118,101,110,32,116, + 104,101,32,112,97,116,104,32,116,111,32,97,32,46,112,121, + 32,102,105,108,101,44,32,114,101,116,117,114,110,32,116,104, + 101,32,112,97,116,104,32,116,111,32,105,116,115,32,46,112, + 121,99,32,102,105,108,101,46,10,10,32,32,32,32,84,104, + 101,32,46,112,121,32,102,105,108,101,32,100,111,101,115,32, + 110,111,116,32,110,101,101,100,32,116,111,32,101,120,105,115, + 116,59,32,116,104,105,115,32,115,105,109,112,108,121,32,114, + 101,116,117,114,110,115,32,116,104,101,32,112,97,116,104,32, + 116,111,32,116,104,101,10,32,32,32,32,46,112,121,99,32, + 102,105,108,101,32,99,97,108,99,117,108,97,116,101,100,32, + 97,115,32,105,102,32,116,104,101,32,46,112,121,32,102,105, + 108,101,32,119,101,114,101,32,105,109,112,111,114,116,101,100, + 46,10,10,32,32,32,32,84,104,101,32,39,111,112,116,105, + 109,105,122,97,116,105,111,110,39,32,112,97,114,97,109,101, + 116,101,114,32,99,111,110,116,114,111,108,115,32,116,104,101, + 32,112,114,101,115,117,109,101,100,32,111,112,116,105,109,105, + 122,97,116,105,111,110,32,108,101,118,101,108,32,111,102,10, + 32,32,32,32,116,104,101,32,98,121,116,101,99,111,100,101, + 32,102,105,108,101,46,32,73,102,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,105,115,32,110,111,116,32, + 78,111,110,101,44,32,116,104,101,32,115,116,114,105,110,103, + 32,114,101,112,114,101,115,101,110,116,97,116,105,111,110,10, + 32,32,32,32,111,102,32,116,104,101,32,97,114,103,117,109, + 101,110,116,32,105,115,32,116,97,107,101,110,32,97,110,100, + 32,118,101,114,105,102,105,101,100,32,116,111,32,98,101,32, + 97,108,112,104,97,110,117,109,101,114,105,99,32,40,101,108, + 115,101,32,86,97,108,117,101,69,114,114,111,114,10,32,32, + 32,32,105,115,32,114,97,105,115,101,100,41,46,10,10,32, + 32,32,32,84,104,101,32,100,101,98,117,103,95,111,118,101, + 114,114,105,100,101,32,112,97,114,97,109,101,116,101,114,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,73, + 102,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 32,105,115,32,110,111,116,32,78,111,110,101,44,10,32,32, + 32,32,97,32,84,114,117,101,32,118,97,108,117,101,32,105, + 115,32,116,104,101,32,115,97,109,101,32,97,115,32,115,101, 116,116,105,110,103,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,116,111,32,39,49,39,46,10,10,32,32, - 32,32,73,102,32,115,121,115,46,105,109,112,108,101,109,101, + 105,111,110,39,32,116,111,32,116,104,101,32,101,109,112,116, + 121,32,115,116,114,105,110,103,10,32,32,32,32,119,104,105, + 108,101,32,97,32,70,97,108,115,101,32,118,97,108,117,101, + 32,105,115,32,101,113,117,105,118,97,108,101,110,116,32,116, + 111,32,115,101,116,116,105,110,103,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,116,111,32,39,49,39,46, + 10,10,32,32,32,32,73,102,32,115,121,115,46,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,46,99,97,99,104, + 101,95,116,97,103,32,105,115,32,78,111,110,101,32,116,104, + 101,110,32,78,111,116,73,109,112,108,101,109,101,110,116,101, + 100,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 46,10,10,32,32,32,32,78,122,70,116,104,101,32,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,112,97,114, + 97,109,101,116,101,114,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,59,32,117,115,101,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,105,110,115,116,101,97,100, + 122,50,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 32,111,114,32,111,112,116,105,109,105,122,97,116,105,111,110, + 32,109,117,115,116,32,98,101,32,115,101,116,32,116,111,32, + 78,111,110,101,114,40,0,0,0,114,39,0,0,0,218,1, + 46,250,36,115,121,115,46,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, + 105,115,32,78,111,110,101,233,0,0,0,0,122,24,123,33, + 114,125,32,105,115,32,110,111,116,32,97,108,112,104,97,110, + 117,109,101,114,105,99,122,7,123,125,46,123,125,123,125,250, + 1,58,114,28,0,0,0,41,28,218,9,95,119,97,114,110, + 105,110,103,115,218,4,119,97,114,110,218,18,68,101,112,114, + 101,99,97,116,105,111,110,87,97,114,110,105,110,103,218,9, + 84,121,112,101,69,114,114,111,114,114,2,0,0,0,218,6, + 102,115,112,97,116,104,114,47,0,0,0,114,41,0,0,0, + 114,8,0,0,0,218,14,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,218,9,99,97,99,104,101,95,116,97,103, + 218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,100, + 69,114,114,111,114,114,36,0,0,0,218,5,102,108,97,103, + 115,218,8,111,112,116,105,109,105,122,101,218,3,115,116,114, + 218,7,105,115,97,108,110,117,109,218,10,86,97,108,117,101, + 69,114,114,111,114,114,62,0,0,0,218,4,95,79,80,84, + 218,17,66,89,84,69,67,79,68,69,95,83,85,70,70,73, + 88,69,83,218,14,112,121,99,97,99,104,101,95,112,114,101, + 102,105,120,114,59,0,0,0,114,38,0,0,0,114,55,0, + 0,0,114,31,0,0,0,218,6,108,115,116,114,105,112,218, + 8,95,80,89,67,65,67,72,69,41,12,114,44,0,0,0, + 90,14,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 114,70,0,0,0,218,7,109,101,115,115,97,103,101,218,4, + 104,101,97,100,114,46,0,0,0,90,4,98,97,115,101,218, + 3,115,101,112,218,4,114,101,115,116,90,3,116,97,103,90, + 15,97,108,109,111,115,116,95,102,105,108,101,110,97,109,101, + 218,8,102,105,108,101,110,97,109,101,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,17,99,97,99,104,101, + 95,102,114,111,109,95,115,111,117,114,99,101,33,1,0,0, + 115,72,0,0,0,0,18,8,1,6,1,2,255,4,2,8, + 1,4,1,8,1,12,1,10,1,12,1,16,1,8,1,8, + 1,8,1,24,1,8,1,12,1,6,2,8,1,8,1,8, + 1,8,1,14,1,14,1,12,1,12,9,10,1,14,5,28, + 1,12,4,2,1,4,1,8,1,2,253,4,5,114,98,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,10, + 0,0,0,5,0,0,0,67,0,0,0,115,46,1,0,0, + 116,0,106,1,106,2,100,1,107,8,114,20,116,3,100,2, + 131,1,130,1,116,4,160,5,124,0,161,1,125,0,116,6, + 124,0,131,1,92,2,125,1,125,2,100,3,125,3,116,0, + 106,7,100,1,107,9,114,102,116,0,106,7,160,8,116,9, + 161,1,125,4,124,1,160,10,124,4,116,11,23,0,161,1, + 114,102,124,1,116,12,124,4,131,1,100,1,133,2,25,0, + 125,1,100,4,125,3,124,3,115,144,116,6,124,1,131,1, + 92,2,125,1,125,5,124,5,116,13,107,3,114,144,116,14, + 116,13,155,0,100,5,124,0,155,2,157,3,131,1,130,1, + 124,2,160,15,100,6,161,1,125,6,124,6,100,7,107,7, + 114,178,116,14,100,8,124,2,155,2,157,2,131,1,130,1, + 110,92,124,6,100,9,107,2,144,1,114,14,124,2,160,16, + 100,6,100,10,161,2,100,11,25,0,125,7,124,7,160,10, + 116,17,161,1,115,228,116,14,100,12,116,17,155,2,157,2, + 131,1,130,1,124,7,116,12,116,17,131,1,100,1,133,2, + 25,0,125,8,124,8,160,18,161,0,144,1,115,14,116,14, + 100,13,124,7,155,2,100,14,157,3,131,1,130,1,124,2, + 160,19,100,6,161,1,100,15,25,0,125,9,116,20,124,1, + 124,9,116,21,100,15,25,0,23,0,131,2,83,0,41,16, + 97,110,1,0,0,71,105,118,101,110,32,116,104,101,32,112, + 97,116,104,32,116,111,32,97,32,46,112,121,99,46,32,102, + 105,108,101,44,32,114,101,116,117,114,110,32,116,104,101,32, + 112,97,116,104,32,116,111,32,105,116,115,32,46,112,121,32, + 102,105,108,101,46,10,10,32,32,32,32,84,104,101,32,46, + 112,121,99,32,102,105,108,101,32,100,111,101,115,32,110,111, + 116,32,110,101,101,100,32,116,111,32,101,120,105,115,116,59, + 32,116,104,105,115,32,115,105,109,112,108,121,32,114,101,116, + 117,114,110,115,32,116,104,101,32,112,97,116,104,32,116,111, + 10,32,32,32,32,116,104,101,32,46,112,121,32,102,105,108, + 101,32,99,97,108,99,117,108,97,116,101,100,32,116,111,32, + 99,111,114,114,101,115,112,111,110,100,32,116,111,32,116,104, + 101,32,46,112,121,99,32,102,105,108,101,46,32,32,73,102, + 32,112,97,116,104,32,100,111,101,115,10,32,32,32,32,110, + 111,116,32,99,111,110,102,111,114,109,32,116,111,32,80,69, + 80,32,51,49,52,55,47,52,56,56,32,102,111,114,109,97, + 116,44,32,86,97,108,117,101,69,114,114,111,114,32,119,105, + 108,108,32,98,101,32,114,97,105,115,101,100,46,32,73,102, + 10,32,32,32,32,115,121,115,46,105,109,112,108,101,109,101, 110,116,97,116,105,111,110,46,99,97,99,104,101,95,116,97, 103,32,105,115,32,78,111,110,101,32,116,104,101,110,32,78, 111,116,73,109,112,108,101,109,101,110,116,101,100,69,114,114, 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,122,70,116,104,101,32,100,101,98,117,103,95, - 111,118,101,114,114,105,100,101,32,112,97,114,97,109,101,116, - 101,114,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 59,32,117,115,101,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,105,110,115,116,101,97,100,122,50,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,32,111,114,32, - 111,112,116,105,109,105,122,97,116,105,111,110,32,109,117,115, - 116,32,98,101,32,115,101,116,32,116,111,32,78,111,110,101, - 114,40,0,0,0,114,39,0,0,0,218,1,46,250,36,115, - 121,115,46,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,46,99,97,99,104,101,95,116,97,103,32,105,115,32,78, - 111,110,101,233,0,0,0,0,122,24,123,33,114,125,32,105, - 115,32,110,111,116,32,97,108,112,104,97,110,117,109,101,114, - 105,99,122,7,123,125,46,123,125,123,125,250,1,58,114,28, - 0,0,0,41,28,218,9,95,119,97,114,110,105,110,103,115, - 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, - 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, - 69,114,114,111,114,114,2,0,0,0,218,6,102,115,112,97, - 116,104,114,47,0,0,0,114,41,0,0,0,114,8,0,0, - 0,218,14,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,218,9,99,97,99,104,101,95,116,97,103,218,19,78,111, - 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, - 114,114,36,0,0,0,218,5,102,108,97,103,115,218,8,111, - 112,116,105,109,105,122,101,218,3,115,116,114,218,7,105,115, - 97,108,110,117,109,218,10,86,97,108,117,101,69,114,114,111, - 114,114,62,0,0,0,218,4,95,79,80,84,218,17,66,89, - 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,218, - 14,112,121,99,97,99,104,101,95,112,114,101,102,105,120,114, - 59,0,0,0,114,38,0,0,0,114,55,0,0,0,114,31, - 0,0,0,218,6,108,115,116,114,105,112,218,8,95,80,89, - 67,65,67,72,69,41,12,114,44,0,0,0,90,14,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,114,70,0,0, - 0,218,7,109,101,115,115,97,103,101,218,4,104,101,97,100, - 114,46,0,0,0,90,4,98,97,115,101,218,3,115,101,112, - 218,4,114,101,115,116,90,3,116,97,103,90,15,97,108,109, - 111,115,116,95,102,105,108,101,110,97,109,101,218,8,102,105, - 108,101,110,97,109,101,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,17,99,97,99,104,101,95,102,114,111, - 109,95,115,111,117,114,99,101,32,1,0,0,115,72,0,0, - 0,0,18,8,1,6,1,2,255,4,2,8,1,4,1,8, - 1,12,1,10,1,12,1,16,1,8,1,8,1,8,1,24, - 1,8,1,12,1,6,2,8,1,8,1,8,1,8,1,14, - 1,14,1,12,1,12,9,10,1,14,5,28,1,12,4,2, - 1,4,1,8,1,2,253,4,5,114,98,0,0,0,99,1, - 0,0,0,0,0,0,0,10,0,0,0,5,0,0,0,67, - 0,0,0,115,46,1,0,0,116,0,106,1,106,2,100,1, - 107,8,114,20,116,3,100,2,131,1,130,1,116,4,160,5, - 124,0,161,1,125,0,116,6,124,0,131,1,92,2,125,1, - 125,2,100,3,125,3,116,0,106,7,100,1,107,9,114,102, - 116,0,106,7,160,8,116,9,161,1,125,4,124,1,160,10, - 124,4,116,11,23,0,161,1,114,102,124,1,116,12,124,4, - 131,1,100,1,133,2,25,0,125,1,100,4,125,3,124,3, - 115,144,116,6,124,1,131,1,92,2,125,1,125,5,124,5, - 116,13,107,3,114,144,116,14,116,13,155,0,100,5,124,0, - 155,2,157,3,131,1,130,1,124,2,160,15,100,6,161,1, - 125,6,124,6,100,7,107,7,114,178,116,14,100,8,124,2, - 155,2,157,2,131,1,130,1,110,92,124,6,100,9,107,2, - 144,1,114,14,124,2,160,16,100,6,100,10,161,2,100,11, - 25,0,125,7,124,7,160,10,116,17,161,1,115,228,116,14, - 100,12,116,17,155,2,157,2,131,1,130,1,124,7,116,12, - 116,17,131,1,100,1,133,2,25,0,125,8,124,8,160,18, - 161,0,144,1,115,14,116,14,100,13,124,7,155,2,100,14, - 157,3,131,1,130,1,124,2,160,19,100,6,161,1,100,15, - 25,0,125,9,116,20,124,1,124,9,116,21,100,15,25,0, - 23,0,131,2,83,0,41,16,97,110,1,0,0,71,105,118, - 101,110,32,116,104,101,32,112,97,116,104,32,116,111,32,97, - 32,46,112,121,99,46,32,102,105,108,101,44,32,114,101,116, - 117,114,110,32,116,104,101,32,112,97,116,104,32,116,111,32, - 105,116,115,32,46,112,121,32,102,105,108,101,46,10,10,32, - 32,32,32,84,104,101,32,46,112,121,99,32,102,105,108,101, - 32,100,111,101,115,32,110,111,116,32,110,101,101,100,32,116, - 111,32,101,120,105,115,116,59,32,116,104,105,115,32,115,105, - 109,112,108,121,32,114,101,116,117,114,110,115,32,116,104,101, - 32,112,97,116,104,32,116,111,10,32,32,32,32,116,104,101, - 32,46,112,121,32,102,105,108,101,32,99,97,108,99,117,108, - 97,116,101,100,32,116,111,32,99,111,114,114,101,115,112,111, - 110,100,32,116,111,32,116,104,101,32,46,112,121,99,32,102, - 105,108,101,46,32,32,73,102,32,112,97,116,104,32,100,111, - 101,115,10,32,32,32,32,110,111,116,32,99,111,110,102,111, - 114,109,32,116,111,32,80,69,80,32,51,49,52,55,47,52, - 56,56,32,102,111,114,109,97,116,44,32,86,97,108,117,101, - 69,114,114,111,114,32,119,105,108,108,32,98,101,32,114,97, - 105,115,101,100,46,32,73,102,10,32,32,32,32,115,121,115, - 46,105,109,112,108,101,109,101,110,116,97,116,105,111,110,46, - 99,97,99,104,101,95,116,97,103,32,105,115,32,78,111,110, - 101,32,116,104,101,110,32,78,111,116,73,109,112,108,101,109, - 101,110,116,101,100,69,114,114,111,114,32,105,115,32,114,97, - 105,115,101,100,46,10,10,32,32,32,32,78,114,72,0,0, - 0,70,84,122,31,32,110,111,116,32,98,111,116,116,111,109, - 45,108,101,118,101,108,32,100,105,114,101,99,116,111,114,121, - 32,105,110,32,114,71,0,0,0,62,2,0,0,0,114,28, - 0,0,0,114,57,0,0,0,122,29,101,120,112,101,99,116, - 101,100,32,111,110,108,121,32,50,32,111,114,32,51,32,100, - 111,116,115,32,105,110,32,114,57,0,0,0,114,28,0,0, - 0,233,254,255,255,255,122,53,111,112,116,105,109,105,122,97, - 116,105,111,110,32,112,111,114,116,105,111,110,32,111,102,32, - 102,105,108,101,110,97,109,101,32,100,111,101,115,32,110,111, - 116,32,115,116,97,114,116,32,119,105,116,104,32,122,19,111, - 112,116,105,109,105,122,97,116,105,111,110,32,108,101,118,101, - 108,32,122,29,32,105,115,32,110,111,116,32,97,110,32,97, - 108,112,104,97,110,117,109,101,114,105,99,32,118,97,108,117, - 101,114,73,0,0,0,41,22,114,8,0,0,0,114,80,0, - 0,0,114,81,0,0,0,114,82,0,0,0,114,2,0,0, - 0,114,79,0,0,0,114,47,0,0,0,114,90,0,0,0, - 114,30,0,0,0,114,31,0,0,0,114,10,0,0,0,114, - 35,0,0,0,114,22,0,0,0,114,92,0,0,0,114,87, - 0,0,0,218,5,99,111,117,110,116,114,43,0,0,0,114, - 88,0,0,0,114,86,0,0,0,218,9,112,97,114,116,105, - 116,105,111,110,114,38,0,0,0,218,15,83,79,85,82,67, - 69,95,83,85,70,70,73,88,69,83,41,10,114,44,0,0, - 0,114,94,0,0,0,90,16,112,121,99,97,99,104,101,95, - 102,105,108,101,110,97,109,101,90,23,102,111,117,110,100,95, - 105,110,95,112,121,99,97,99,104,101,95,112,114,101,102,105, - 120,90,13,115,116,114,105,112,112,101,100,95,112,97,116,104, - 90,7,112,121,99,97,99,104,101,90,9,100,111,116,95,99, - 111,117,110,116,114,70,0,0,0,90,9,111,112,116,95,108, - 101,118,101,108,90,13,98,97,115,101,95,102,105,108,101,110, - 97,109,101,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,17,115,111,117,114,99,101,95,102,114,111,109,95, - 99,97,99,104,101,103,1,0,0,115,52,0,0,0,0,9, - 12,1,8,1,10,1,12,1,4,1,10,1,12,1,14,1, - 16,1,4,1,4,1,12,1,8,1,18,2,10,1,8,1, - 16,1,10,1,16,1,10,1,14,2,16,1,10,1,16,2, - 14,1,114,103,0,0,0,99,1,0,0,0,0,0,0,0, - 5,0,0,0,9,0,0,0,67,0,0,0,115,126,0,0, - 0,116,0,124,0,131,1,100,1,107,2,114,16,100,2,83, - 0,124,0,160,1,100,3,161,1,92,3,125,1,125,2,125, - 3,124,1,114,56,124,3,160,2,161,0,100,4,100,5,133, - 2,25,0,100,6,107,3,114,60,124,0,83,0,122,12,116, - 3,124,0,131,1,125,4,87,0,110,36,4,0,116,4,116, - 5,102,2,107,10,114,108,1,0,1,0,1,0,124,0,100, - 2,100,5,133,2,25,0,125,4,89,0,110,2,88,0,116, - 6,124,4,131,1,114,122,124,4,83,0,124,0,83,0,41, - 7,122,188,67,111,110,118,101,114,116,32,97,32,98,121,116, - 101,99,111,100,101,32,102,105,108,101,32,112,97,116,104,32, - 116,111,32,97,32,115,111,117,114,99,101,32,112,97,116,104, - 32,40,105,102,32,112,111,115,115,105,98,108,101,41,46,10, - 10,32,32,32,32,84,104,105,115,32,102,117,110,99,116,105, - 111,110,32,101,120,105,115,116,115,32,112,117,114,101,108,121, - 32,102,111,114,32,98,97,99,107,119,97,114,100,115,45,99, - 111,109,112,97,116,105,98,105,108,105,116,121,32,102,111,114, - 10,32,32,32,32,80,121,73,109,112,111,114,116,95,69,120, - 101,99,67,111,100,101,77,111,100,117,108,101,87,105,116,104, - 70,105,108,101,110,97,109,101,115,40,41,32,105,110,32,116, - 104,101,32,67,32,65,80,73,46,10,10,32,32,32,32,114, - 73,0,0,0,78,114,71,0,0,0,233,253,255,255,255,233, - 255,255,255,255,90,2,112,121,41,7,114,22,0,0,0,114, - 41,0,0,0,218,5,108,111,119,101,114,114,103,0,0,0, - 114,82,0,0,0,114,87,0,0,0,114,54,0,0,0,41, - 5,218,13,98,121,116,101,99,111,100,101,95,112,97,116,104, - 114,96,0,0,0,114,45,0,0,0,90,9,101,120,116,101, - 110,115,105,111,110,218,11,115,111,117,114,99,101,95,112,97, - 116,104,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,15,95,103,101,116,95,115,111,117,114,99,101,102,105, - 108,101,143,1,0,0,115,20,0,0,0,0,7,12,1,4, - 1,16,1,24,1,4,1,2,1,12,1,18,1,18,1,114, - 109,0,0,0,99,1,0,0,0,0,0,0,0,1,0,0, + 32,32,32,78,114,72,0,0,0,70,84,122,31,32,110,111, + 116,32,98,111,116,116,111,109,45,108,101,118,101,108,32,100, + 105,114,101,99,116,111,114,121,32,105,110,32,114,71,0,0, + 0,62,2,0,0,0,114,28,0,0,0,114,57,0,0,0, + 122,29,101,120,112,101,99,116,101,100,32,111,110,108,121,32, + 50,32,111,114,32,51,32,100,111,116,115,32,105,110,32,114, + 57,0,0,0,114,28,0,0,0,233,254,255,255,255,122,53, + 111,112,116,105,109,105,122,97,116,105,111,110,32,112,111,114, + 116,105,111,110,32,111,102,32,102,105,108,101,110,97,109,101, + 32,100,111,101,115,32,110,111,116,32,115,116,97,114,116,32, + 119,105,116,104,32,122,19,111,112,116,105,109,105,122,97,116, + 105,111,110,32,108,101,118,101,108,32,122,29,32,105,115,32, + 110,111,116,32,97,110,32,97,108,112,104,97,110,117,109,101, + 114,105,99,32,118,97,108,117,101,114,73,0,0,0,41,22, + 114,8,0,0,0,114,80,0,0,0,114,81,0,0,0,114, + 82,0,0,0,114,2,0,0,0,114,79,0,0,0,114,47, + 0,0,0,114,90,0,0,0,114,30,0,0,0,114,31,0, + 0,0,114,10,0,0,0,114,35,0,0,0,114,22,0,0, + 0,114,92,0,0,0,114,87,0,0,0,218,5,99,111,117, + 110,116,114,43,0,0,0,114,88,0,0,0,114,86,0,0, + 0,218,9,112,97,114,116,105,116,105,111,110,114,38,0,0, + 0,218,15,83,79,85,82,67,69,95,83,85,70,70,73,88, + 69,83,41,10,114,44,0,0,0,114,94,0,0,0,90,16, + 112,121,99,97,99,104,101,95,102,105,108,101,110,97,109,101, + 90,23,102,111,117,110,100,95,105,110,95,112,121,99,97,99, + 104,101,95,112,114,101,102,105,120,90,13,115,116,114,105,112, + 112,101,100,95,112,97,116,104,90,7,112,121,99,97,99,104, + 101,90,9,100,111,116,95,99,111,117,110,116,114,70,0,0, + 0,90,9,111,112,116,95,108,101,118,101,108,90,13,98,97, + 115,101,95,102,105,108,101,110,97,109,101,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,115,111,117,114, + 99,101,95,102,114,111,109,95,99,97,99,104,101,104,1,0, + 0,115,52,0,0,0,0,9,12,1,8,1,10,1,12,1, + 4,1,10,1,12,1,14,1,16,1,4,1,4,1,12,1, + 8,1,18,2,10,1,8,1,16,1,10,1,16,1,10,1, + 14,2,16,1,10,1,16,2,14,1,114,103,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, + 9,0,0,0,67,0,0,0,115,126,0,0,0,116,0,124, + 0,131,1,100,1,107,2,114,16,100,2,83,0,124,0,160, + 1,100,3,161,1,92,3,125,1,125,2,125,3,124,1,114, + 56,124,3,160,2,161,0,100,4,100,5,133,2,25,0,100, + 6,107,3,114,60,124,0,83,0,122,12,116,3,124,0,131, + 1,125,4,87,0,110,36,4,0,116,4,116,5,102,2,107, + 10,114,108,1,0,1,0,1,0,124,0,100,2,100,5,133, + 2,25,0,125,4,89,0,110,2,88,0,116,6,124,4,131, + 1,114,122,124,4,83,0,124,0,83,0,41,7,122,188,67, + 111,110,118,101,114,116,32,97,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,32,112,97,116,104,32,116,111,32,97, + 32,115,111,117,114,99,101,32,112,97,116,104,32,40,105,102, + 32,112,111,115,115,105,98,108,101,41,46,10,10,32,32,32, + 32,84,104,105,115,32,102,117,110,99,116,105,111,110,32,101, + 120,105,115,116,115,32,112,117,114,101,108,121,32,102,111,114, + 32,98,97,99,107,119,97,114,100,115,45,99,111,109,112,97, + 116,105,98,105,108,105,116,121,32,102,111,114,10,32,32,32, + 32,80,121,73,109,112,111,114,116,95,69,120,101,99,67,111, + 100,101,77,111,100,117,108,101,87,105,116,104,70,105,108,101, + 110,97,109,101,115,40,41,32,105,110,32,116,104,101,32,67, + 32,65,80,73,46,10,10,32,32,32,32,114,73,0,0,0, + 78,114,71,0,0,0,233,253,255,255,255,233,255,255,255,255, + 90,2,112,121,41,7,114,22,0,0,0,114,41,0,0,0, + 218,5,108,111,119,101,114,114,103,0,0,0,114,82,0,0, + 0,114,87,0,0,0,114,54,0,0,0,41,5,218,13,98, + 121,116,101,99,111,100,101,95,112,97,116,104,114,96,0,0, + 0,114,45,0,0,0,90,9,101,120,116,101,110,115,105,111, + 110,218,11,115,111,117,114,99,101,95,112,97,116,104,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, + 103,101,116,95,115,111,117,114,99,101,102,105,108,101,144,1, + 0,0,115,20,0,0,0,0,7,12,1,4,1,16,1,24, + 1,4,1,2,1,12,1,18,1,18,1,114,109,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, 0,8,0,0,0,67,0,0,0,115,74,0,0,0,124,0, 160,0,116,1,116,2,131,1,161,1,114,48,122,10,116,3, 124,0,131,1,87,0,83,0,4,0,116,4,107,10,114,44, @@ -518,63 +523,64 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,98,0,0,0,114,82,0,0,0,114,89,0, 0,0,41,1,114,97,0,0,0,114,3,0,0,0,114,3, 0,0,0,114,6,0,0,0,218,11,95,103,101,116,95,99, - 97,99,104,101,100,162,1,0,0,115,16,0,0,0,0,1, + 97,99,104,101,100,163,1,0,0,115,16,0,0,0,0,1, 14,1,2,1,10,1,14,1,8,1,14,1,4,2,114,113, - 0,0,0,99,1,0,0,0,0,0,0,0,2,0,0,0, - 8,0,0,0,67,0,0,0,115,52,0,0,0,122,14,116, - 0,124,0,131,1,106,1,125,1,87,0,110,24,4,0,116, - 2,107,10,114,38,1,0,1,0,1,0,100,1,125,1,89, - 0,110,2,88,0,124,1,100,2,79,0,125,1,124,1,83, - 0,41,3,122,51,67,97,108,99,117,108,97,116,101,32,116, - 104,101,32,109,111,100,101,32,112,101,114,109,105,115,115,105, - 111,110,115,32,102,111,114,32,97,32,98,121,116,101,99,111, - 100,101,32,102,105,108,101,46,114,60,0,0,0,233,128,0, - 0,0,41,3,114,49,0,0,0,114,51,0,0,0,114,50, - 0,0,0,41,2,114,44,0,0,0,114,52,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,10, - 95,99,97,108,99,95,109,111,100,101,174,1,0,0,115,12, - 0,0,0,0,2,2,1,14,1,14,1,10,3,8,1,114, - 115,0,0,0,99,1,0,0,0,0,0,0,0,3,0,0, - 0,8,0,0,0,3,0,0,0,115,68,0,0,0,100,6, - 135,0,102,1,100,2,100,3,132,9,125,1,122,10,116,0, - 106,1,125,2,87,0,110,28,4,0,116,2,107,10,114,52, - 1,0,1,0,1,0,100,4,100,5,132,0,125,2,89,0, - 110,2,88,0,124,2,124,1,136,0,131,2,1,0,124,1, - 83,0,41,7,122,252,68,101,99,111,114,97,116,111,114,32, - 116,111,32,118,101,114,105,102,121,32,116,104,97,116,32,116, - 104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,32, - 114,101,113,117,101,115,116,101,100,32,109,97,116,99,104,101, - 115,32,116,104,101,32,111,110,101,32,116,104,101,10,32,32, - 32,32,108,111,97,100,101,114,32,99,97,110,32,104,97,110, - 100,108,101,46,10,10,32,32,32,32,84,104,101,32,102,105, - 114,115,116,32,97,114,103,117,109,101,110,116,32,40,115,101, - 108,102,41,32,109,117,115,116,32,100,101,102,105,110,101,32, - 95,110,97,109,101,32,119,104,105,99,104,32,116,104,101,32, - 115,101,99,111,110,100,32,97,114,103,117,109,101,110,116,32, - 105,115,10,32,32,32,32,99,111,109,112,97,114,101,100,32, - 97,103,97,105,110,115,116,46,32,73,102,32,116,104,101,32, - 99,111,109,112,97,114,105,115,111,110,32,102,97,105,108,115, - 32,116,104,101,110,32,73,109,112,111,114,116,69,114,114,111, - 114,32,105,115,32,114,97,105,115,101,100,46,10,10,32,32, - 32,32,78,99,2,0,0,0,0,0,0,0,4,0,0,0, - 4,0,0,0,31,0,0,0,115,66,0,0,0,124,1,100, - 0,107,8,114,16,124,0,106,0,125,1,110,32,124,0,106, - 0,124,1,107,3,114,48,116,1,100,1,124,0,106,0,124, - 1,102,2,22,0,124,1,100,2,141,2,130,1,136,0,124, - 0,124,1,102,2,124,2,158,2,124,3,142,1,83,0,41, - 3,78,122,30,108,111,97,100,101,114,32,102,111,114,32,37, - 115,32,99,97,110,110,111,116,32,104,97,110,100,108,101,32, - 37,115,169,1,218,4,110,97,109,101,41,2,114,117,0,0, - 0,218,11,73,109,112,111,114,116,69,114,114,111,114,41,4, - 218,4,115,101,108,102,114,117,0,0,0,218,4,97,114,103, - 115,90,6,107,119,97,114,103,115,169,1,218,6,109,101,116, - 104,111,100,114,3,0,0,0,114,6,0,0,0,218,19,95, - 99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,112, - 101,114,194,1,0,0,115,18,0,0,0,0,1,8,1,8, - 1,10,1,4,1,8,255,2,1,2,255,6,2,122,40,95, - 99,104,101,99,107,95,110,97,109,101,46,60,108,111,99,97, - 108,115,62,46,95,99,104,101,99,107,95,110,97,109,101,95, - 119,114,97,112,112,101,114,99,2,0,0,0,0,0,0,0, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,8,0,0,0,67,0,0,0,115,52,0,0, + 0,122,14,116,0,124,0,131,1,106,1,125,1,87,0,110, + 24,4,0,116,2,107,10,114,38,1,0,1,0,1,0,100, + 1,125,1,89,0,110,2,88,0,124,1,100,2,79,0,125, + 1,124,1,83,0,41,3,122,51,67,97,108,99,117,108,97, + 116,101,32,116,104,101,32,109,111,100,101,32,112,101,114,109, + 105,115,115,105,111,110,115,32,102,111,114,32,97,32,98,121, + 116,101,99,111,100,101,32,102,105,108,101,46,114,60,0,0, + 0,233,128,0,0,0,41,3,114,49,0,0,0,114,51,0, + 0,0,114,50,0,0,0,41,2,114,44,0,0,0,114,52, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,10,95,99,97,108,99,95,109,111,100,101,175,1, + 0,0,115,12,0,0,0,0,2,2,1,14,1,14,1,10, + 3,8,1,114,115,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,8,0,0,0,3,0,0, + 0,115,68,0,0,0,100,6,135,0,102,1,100,2,100,3, + 132,9,125,1,122,10,116,0,106,1,125,2,87,0,110,28, + 4,0,116,2,107,10,114,52,1,0,1,0,1,0,100,4, + 100,5,132,0,125,2,89,0,110,2,88,0,124,2,124,1, + 136,0,131,2,1,0,124,1,83,0,41,7,122,252,68,101, + 99,111,114,97,116,111,114,32,116,111,32,118,101,114,105,102, + 121,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108, + 101,32,98,101,105,110,103,32,114,101,113,117,101,115,116,101, + 100,32,109,97,116,99,104,101,115,32,116,104,101,32,111,110, + 101,32,116,104,101,10,32,32,32,32,108,111,97,100,101,114, + 32,99,97,110,32,104,97,110,100,108,101,46,10,10,32,32, + 32,32,84,104,101,32,102,105,114,115,116,32,97,114,103,117, + 109,101,110,116,32,40,115,101,108,102,41,32,109,117,115,116, + 32,100,101,102,105,110,101,32,95,110,97,109,101,32,119,104, + 105,99,104,32,116,104,101,32,115,101,99,111,110,100,32,97, + 114,103,117,109,101,110,116,32,105,115,10,32,32,32,32,99, + 111,109,112,97,114,101,100,32,97,103,97,105,110,115,116,46, + 32,73,102,32,116,104,101,32,99,111,109,112,97,114,105,115, + 111,110,32,102,97,105,108,115,32,116,104,101,110,32,73,109, + 112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,105, + 115,101,100,46,10,10,32,32,32,32,78,99,2,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, + 31,0,0,0,115,66,0,0,0,124,1,100,0,107,8,114, + 16,124,0,106,0,125,1,110,32,124,0,106,0,124,1,107, + 3,114,48,116,1,100,1,124,0,106,0,124,1,102,2,22, + 0,124,1,100,2,141,2,130,1,136,0,124,0,124,1,102, + 2,124,2,158,2,124,3,142,1,83,0,41,3,78,122,30, + 108,111,97,100,101,114,32,102,111,114,32,37,115,32,99,97, + 110,110,111,116,32,104,97,110,100,108,101,32,37,115,169,1, + 218,4,110,97,109,101,41,2,114,117,0,0,0,218,11,73, + 109,112,111,114,116,69,114,114,111,114,41,4,218,4,115,101, + 108,102,114,117,0,0,0,218,4,97,114,103,115,90,6,107, + 119,97,114,103,115,169,1,218,6,109,101,116,104,111,100,114, + 3,0,0,0,114,6,0,0,0,218,19,95,99,104,101,99, + 107,95,110,97,109,101,95,119,114,97,112,112,101,114,195,1, + 0,0,115,18,0,0,0,0,1,8,1,8,1,10,1,4, + 1,8,255,2,1,2,255,6,2,122,40,95,99,104,101,99, + 107,95,110,97,109,101,46,60,108,111,99,97,108,115,62,46, + 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, + 112,101,114,99,2,0,0,0,0,0,0,0,0,0,0,0, 3,0,0,0,7,0,0,0,83,0,0,0,115,56,0,0, 0,100,1,68,0,93,32,125,2,116,0,124,1,124,2,131, 2,114,4,116,1,124,0,124,2,116,2,124,1,124,2,131, @@ -588,165 +594,166 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 95,95,218,6,117,112,100,97,116,101,41,3,90,3,110,101, 119,90,3,111,108,100,114,67,0,0,0,114,3,0,0,0, 114,3,0,0,0,114,6,0,0,0,218,5,95,119,114,97, - 112,205,1,0,0,115,8,0,0,0,0,1,8,1,10,1, + 112,206,1,0,0,115,8,0,0,0,0,1,8,1,10,1, 20,1,122,26,95,99,104,101,99,107,95,110,97,109,101,46, 60,108,111,99,97,108,115,62,46,95,119,114,97,112,41,1, 78,41,3,218,10,95,98,111,111,116,115,116,114,97,112,114, 133,0,0,0,218,9,78,97,109,101,69,114,114,111,114,41, 3,114,122,0,0,0,114,123,0,0,0,114,133,0,0,0, 114,3,0,0,0,114,121,0,0,0,114,6,0,0,0,218, - 11,95,99,104,101,99,107,95,110,97,109,101,186,1,0,0, + 11,95,99,104,101,99,107,95,110,97,109,101,187,1,0,0, 115,14,0,0,0,0,8,14,7,2,1,10,1,14,2,14, 5,10,1,114,136,0,0,0,99,2,0,0,0,0,0,0, - 0,5,0,0,0,6,0,0,0,67,0,0,0,115,60,0, - 0,0,124,0,160,0,124,1,161,1,92,2,125,2,125,3, - 124,2,100,1,107,8,114,56,116,1,124,3,131,1,114,56, - 100,2,125,4,116,2,160,3,124,4,160,4,124,3,100,3, - 25,0,161,1,116,5,161,2,1,0,124,2,83,0,41,4, - 122,155,84,114,121,32,116,111,32,102,105,110,100,32,97,32, - 108,111,97,100,101,114,32,102,111,114,32,116,104,101,32,115, - 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,32, - 98,121,32,100,101,108,101,103,97,116,105,110,103,32,116,111, - 10,32,32,32,32,115,101,108,102,46,102,105,110,100,95,108, - 111,97,100,101,114,40,41,46,10,10,32,32,32,32,84,104, - 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,32,105,110,32,102,97,118,111,114, - 32,111,102,32,102,105,110,100,101,114,46,102,105,110,100,95, - 115,112,101,99,40,41,46,10,10,32,32,32,32,78,122,44, - 78,111,116,32,105,109,112,111,114,116,105,110,103,32,100,105, - 114,101,99,116,111,114,121,32,123,125,58,32,109,105,115,115, - 105,110,103,32,95,95,105,110,105,116,95,95,114,73,0,0, - 0,41,6,218,11,102,105,110,100,95,108,111,97,100,101,114, - 114,22,0,0,0,114,75,0,0,0,114,76,0,0,0,114, - 62,0,0,0,218,13,73,109,112,111,114,116,87,97,114,110, - 105,110,103,41,5,114,119,0,0,0,218,8,102,117,108,108, - 110,97,109,101,218,6,108,111,97,100,101,114,218,8,112,111, - 114,116,105,111,110,115,218,3,109,115,103,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,17,95,102,105,110, - 100,95,109,111,100,117,108,101,95,115,104,105,109,214,1,0, - 0,115,10,0,0,0,0,10,14,1,16,1,4,1,22,1, - 114,143,0,0,0,99,3,0,0,0,0,0,0,0,6,0, - 0,0,4,0,0,0,67,0,0,0,115,158,0,0,0,124, - 0,100,1,100,2,133,2,25,0,125,3,124,3,116,0,107, - 3,114,60,100,3,124,1,155,2,100,4,124,3,155,2,157, - 4,125,4,116,1,160,2,100,5,124,4,161,2,1,0,116, - 3,124,4,102,1,124,2,142,1,130,1,116,4,124,0,131, - 1,100,6,107,0,114,102,100,7,124,1,155,2,157,2,125, - 4,116,1,160,2,100,5,124,4,161,2,1,0,116,5,124, - 4,131,1,130,1,116,6,124,0,100,2,100,8,133,2,25, - 0,131,1,125,5,124,5,100,9,64,0,114,154,100,10,124, - 5,155,2,100,11,124,1,155,2,157,4,125,4,116,3,124, - 4,102,1,124,2,142,1,130,1,124,5,83,0,41,12,97, - 84,2,0,0,80,101,114,102,111,114,109,32,98,97,115,105, - 99,32,118,97,108,105,100,105,116,121,32,99,104,101,99,107, - 105,110,103,32,111,102,32,97,32,112,121,99,32,104,101,97, - 100,101,114,32,97,110,100,32,114,101,116,117,114,110,32,116, - 104,101,32,102,108,97,103,115,32,102,105,101,108,100,44,10, - 32,32,32,32,119,104,105,99,104,32,100,101,116,101,114,109, - 105,110,101,115,32,104,111,119,32,116,104,101,32,112,121,99, - 32,115,104,111,117,108,100,32,98,101,32,102,117,114,116,104, - 101,114,32,118,97,108,105,100,97,116,101,100,32,97,103,97, - 105,110,115,116,32,116,104,101,32,115,111,117,114,99,101,46, - 10,10,32,32,32,32,42,100,97,116,97,42,32,105,115,32, - 116,104,101,32,99,111,110,116,101,110,116,115,32,111,102,32, - 116,104,101,32,112,121,99,32,102,105,108,101,46,32,40,79, - 110,108,121,32,116,104,101,32,102,105,114,115,116,32,49,54, - 32,98,121,116,101,115,32,97,114,101,10,32,32,32,32,114, - 101,113,117,105,114,101,100,44,32,116,104,111,117,103,104,46, - 41,10,10,32,32,32,32,42,110,97,109,101,42,32,105,115, - 32,116,104,101,32,110,97,109,101,32,111,102,32,116,104,101, - 32,109,111,100,117,108,101,32,98,101,105,110,103,32,105,109, - 112,111,114,116,101,100,46,32,73,116,32,105,115,32,117,115, - 101,100,32,102,111,114,32,108,111,103,103,105,110,103,46,10, - 10,32,32,32,32,42,101,120,99,95,100,101,116,97,105,108, - 115,42,32,105,115,32,97,32,100,105,99,116,105,111,110,97, - 114,121,32,112,97,115,115,101,100,32,116,111,32,73,109,112, - 111,114,116,69,114,114,111,114,32,105,102,32,105,116,32,114, - 97,105,115,101,100,32,102,111,114,10,32,32,32,32,105,109, - 112,114,111,118,101,100,32,100,101,98,117,103,103,105,110,103, - 46,10,10,32,32,32,32,73,109,112,111,114,116,69,114,114, - 111,114,32,105,115,32,114,97,105,115,101,100,32,119,104,101, - 110,32,116,104,101,32,109,97,103,105,99,32,110,117,109,98, - 101,114,32,105,115,32,105,110,99,111,114,114,101,99,116,32, - 111,114,32,119,104,101,110,32,116,104,101,32,102,108,97,103, - 115,10,32,32,32,32,102,105,101,108,100,32,105,115,32,105, - 110,118,97,108,105,100,46,32,69,79,70,69,114,114,111,114, - 32,105,115,32,114,97,105,115,101,100,32,119,104,101,110,32, - 116,104,101,32,100,97,116,97,32,105,115,32,102,111,117,110, - 100,32,116,111,32,98,101,32,116,114,117,110,99,97,116,101, - 100,46,10,10,32,32,32,32,78,114,15,0,0,0,122,20, - 98,97,100,32,109,97,103,105,99,32,110,117,109,98,101,114, - 32,105,110,32,122,2,58,32,250,2,123,125,233,16,0,0, - 0,122,40,114,101,97,99,104,101,100,32,69,79,70,32,119, - 104,105,108,101,32,114,101,97,100,105,110,103,32,112,121,99, - 32,104,101,97,100,101,114,32,111,102,32,233,8,0,0,0, - 233,252,255,255,255,122,14,105,110,118,97,108,105,100,32,102, - 108,97,103,115,32,122,4,32,105,110,32,41,7,218,12,77, - 65,71,73,67,95,78,85,77,66,69,82,114,134,0,0,0, - 218,16,95,118,101,114,98,111,115,101,95,109,101,115,115,97, - 103,101,114,118,0,0,0,114,22,0,0,0,218,8,69,79, - 70,69,114,114,111,114,114,27,0,0,0,41,6,114,26,0, - 0,0,114,117,0,0,0,218,11,101,120,99,95,100,101,116, - 97,105,108,115,90,5,109,97,103,105,99,114,93,0,0,0, - 114,83,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,231,1,0,0,115,28,0,0,0,0,16,12,1, - 8,1,16,1,12,1,12,1,12,1,10,1,12,1,8,1, - 16,2,8,1,16,1,12,1,114,152,0,0,0,99,5,0, + 0,0,0,0,0,5,0,0,0,6,0,0,0,67,0,0, + 0,115,60,0,0,0,124,0,160,0,124,1,161,1,92,2, + 125,2,125,3,124,2,100,1,107,8,114,56,116,1,124,3, + 131,1,114,56,100,2,125,4,116,2,160,3,124,4,160,4, + 124,3,100,3,25,0,161,1,116,5,161,2,1,0,124,2, + 83,0,41,4,122,155,84,114,121,32,116,111,32,102,105,110, + 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,32,98,121,32,100,101,108,101,103,97,116,105,110, + 103,32,116,111,10,32,32,32,32,115,101,108,102,46,102,105, + 110,100,95,108,111,97,100,101,114,40,41,46,10,10,32,32, + 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, + 32,100,101,112,114,101,99,97,116,101,100,32,105,110,32,102, + 97,118,111,114,32,111,102,32,102,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,40,41,46,10,10,32,32,32, + 32,78,122,44,78,111,116,32,105,109,112,111,114,116,105,110, + 103,32,100,105,114,101,99,116,111,114,121,32,123,125,58,32, + 109,105,115,115,105,110,103,32,95,95,105,110,105,116,95,95, + 114,73,0,0,0,41,6,218,11,102,105,110,100,95,108,111, + 97,100,101,114,114,22,0,0,0,114,75,0,0,0,114,76, + 0,0,0,114,62,0,0,0,218,13,73,109,112,111,114,116, + 87,97,114,110,105,110,103,41,5,114,119,0,0,0,218,8, + 102,117,108,108,110,97,109,101,218,6,108,111,97,100,101,114, + 218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,17, + 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, + 109,215,1,0,0,115,10,0,0,0,0,10,14,1,16,1, + 4,1,22,1,114,143,0,0,0,99,3,0,0,0,0,0, 0,0,0,0,0,0,6,0,0,0,4,0,0,0,67,0, - 0,0,115,112,0,0,0,116,0,124,0,100,1,100,2,133, - 2,25,0,131,1,124,1,100,3,64,0,107,3,114,58,100, - 4,124,3,155,2,157,2,125,5,116,1,160,2,100,5,124, - 5,161,2,1,0,116,3,124,5,102,1,124,4,142,1,130, - 1,124,2,100,6,107,9,114,108,116,0,124,0,100,2,100, - 7,133,2,25,0,131,1,124,2,100,3,64,0,107,3,114, - 108,116,3,100,4,124,3,155,2,157,2,102,1,124,4,142, - 1,130,1,100,6,83,0,41,8,97,7,2,0,0,86,97, - 108,105,100,97,116,101,32,97,32,112,121,99,32,97,103,97, - 105,110,115,116,32,116,104,101,32,115,111,117,114,99,101,32, - 108,97,115,116,45,109,111,100,105,102,105,101,100,32,116,105, - 109,101,46,10,10,32,32,32,32,42,100,97,116,97,42,32, - 105,115,32,116,104,101,32,99,111,110,116,101,110,116,115,32, - 111,102,32,116,104,101,32,112,121,99,32,102,105,108,101,46, - 32,40,79,110,108,121,32,116,104,101,32,102,105,114,115,116, - 32,49,54,32,98,121,116,101,115,32,97,114,101,10,32,32, - 32,32,114,101,113,117,105,114,101,100,46,41,10,10,32,32, - 32,32,42,115,111,117,114,99,101,95,109,116,105,109,101,42, - 32,105,115,32,116,104,101,32,108,97,115,116,32,109,111,100, - 105,102,105,101,100,32,116,105,109,101,115,116,97,109,112,32, - 111,102,32,116,104,101,32,115,111,117,114,99,101,32,102,105, - 108,101,46,10,10,32,32,32,32,42,115,111,117,114,99,101, - 95,115,105,122,101,42,32,105,115,32,78,111,110,101,32,111, - 114,32,116,104,101,32,115,105,122,101,32,111,102,32,116,104, - 101,32,115,111,117,114,99,101,32,102,105,108,101,32,105,110, - 32,98,121,116,101,115,46,10,10,32,32,32,32,42,110,97, - 109,101,42,32,105,115,32,116,104,101,32,110,97,109,101,32, - 111,102,32,116,104,101,32,109,111,100,117,108,101,32,98,101, - 105,110,103,32,105,109,112,111,114,116,101,100,46,32,73,116, - 32,105,115,32,117,115,101,100,32,102,111,114,32,108,111,103, - 103,105,110,103,46,10,10,32,32,32,32,42,101,120,99,95, - 100,101,116,97,105,108,115,42,32,105,115,32,97,32,100,105, - 99,116,105,111,110,97,114,121,32,112,97,115,115,101,100,32, - 116,111,32,73,109,112,111,114,116,69,114,114,111,114,32,105, - 102,32,105,116,32,114,97,105,115,101,100,32,102,111,114,10, - 32,32,32,32,105,109,112,114,111,118,101,100,32,100,101,98, - 117,103,103,105,110,103,46,10,10,32,32,32,32,65,110,32, - 73,109,112,111,114,116,69,114,114,111,114,32,105,115,32,114, - 97,105,115,101,100,32,105,102,32,116,104,101,32,98,121,116, - 101,99,111,100,101,32,105,115,32,115,116,97,108,101,46,10, - 10,32,32,32,32,114,146,0,0,0,233,12,0,0,0,114, - 14,0,0,0,122,22,98,121,116,101,99,111,100,101,32,105, - 115,32,115,116,97,108,101,32,102,111,114,32,114,144,0,0, - 0,78,114,145,0,0,0,41,4,114,27,0,0,0,114,134, - 0,0,0,114,149,0,0,0,114,118,0,0,0,41,6,114, - 26,0,0,0,218,12,115,111,117,114,99,101,95,109,116,105, - 109,101,218,11,115,111,117,114,99,101,95,115,105,122,101,114, - 117,0,0,0,114,151,0,0,0,114,93,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,23,95, - 118,97,108,105,100,97,116,101,95,116,105,109,101,115,116,97, - 109,112,95,112,121,99,8,2,0,0,115,16,0,0,0,0, - 19,24,1,10,1,12,1,12,1,8,1,22,255,2,2,114, - 156,0,0,0,99,4,0,0,0,0,0,0,0,4,0,0, + 0,0,115,158,0,0,0,124,0,100,1,100,2,133,2,25, + 0,125,3,124,3,116,0,107,3,114,60,100,3,124,1,155, + 2,100,4,124,3,155,2,157,4,125,4,116,1,160,2,100, + 5,124,4,161,2,1,0,116,3,124,4,102,1,124,2,142, + 1,130,1,116,4,124,0,131,1,100,6,107,0,114,102,100, + 7,124,1,155,2,157,2,125,4,116,1,160,2,100,5,124, + 4,161,2,1,0,116,5,124,4,131,1,130,1,116,6,124, + 0,100,2,100,8,133,2,25,0,131,1,125,5,124,5,100, + 9,64,0,114,154,100,10,124,5,155,2,100,11,124,1,155, + 2,157,4,125,4,116,3,124,4,102,1,124,2,142,1,130, + 1,124,5,83,0,41,12,97,84,2,0,0,80,101,114,102, + 111,114,109,32,98,97,115,105,99,32,118,97,108,105,100,105, + 116,121,32,99,104,101,99,107,105,110,103,32,111,102,32,97, + 32,112,121,99,32,104,101,97,100,101,114,32,97,110,100,32, + 114,101,116,117,114,110,32,116,104,101,32,102,108,97,103,115, + 32,102,105,101,108,100,44,10,32,32,32,32,119,104,105,99, + 104,32,100,101,116,101,114,109,105,110,101,115,32,104,111,119, + 32,116,104,101,32,112,121,99,32,115,104,111,117,108,100,32, + 98,101,32,102,117,114,116,104,101,114,32,118,97,108,105,100, + 97,116,101,100,32,97,103,97,105,110,115,116,32,116,104,101, + 32,115,111,117,114,99,101,46,10,10,32,32,32,32,42,100, + 97,116,97,42,32,105,115,32,116,104,101,32,99,111,110,116, + 101,110,116,115,32,111,102,32,116,104,101,32,112,121,99,32, + 102,105,108,101,46,32,40,79,110,108,121,32,116,104,101,32, + 102,105,114,115,116,32,49,54,32,98,121,116,101,115,32,97, + 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,44, + 32,116,104,111,117,103,104,46,41,10,10,32,32,32,32,42, + 110,97,109,101,42,32,105,115,32,116,104,101,32,110,97,109, + 101,32,111,102,32,116,104,101,32,109,111,100,117,108,101,32, + 98,101,105,110,103,32,105,109,112,111,114,116,101,100,46,32, + 73,116,32,105,115,32,117,115,101,100,32,102,111,114,32,108, + 111,103,103,105,110,103,46,10,10,32,32,32,32,42,101,120, + 99,95,100,101,116,97,105,108,115,42,32,105,115,32,97,32, + 100,105,99,116,105,111,110,97,114,121,32,112,97,115,115,101, + 100,32,116,111,32,73,109,112,111,114,116,69,114,114,111,114, + 32,105,102,32,105,116,32,114,97,105,115,101,100,32,102,111, + 114,10,32,32,32,32,105,109,112,114,111,118,101,100,32,100, + 101,98,117,103,103,105,110,103,46,10,10,32,32,32,32,73, + 109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,97, + 105,115,101,100,32,119,104,101,110,32,116,104,101,32,109,97, + 103,105,99,32,110,117,109,98,101,114,32,105,115,32,105,110, + 99,111,114,114,101,99,116,32,111,114,32,119,104,101,110,32, + 116,104,101,32,102,108,97,103,115,10,32,32,32,32,102,105, + 101,108,100,32,105,115,32,105,110,118,97,108,105,100,46,32, + 69,79,70,69,114,114,111,114,32,105,115,32,114,97,105,115, + 101,100,32,119,104,101,110,32,116,104,101,32,100,97,116,97, + 32,105,115,32,102,111,117,110,100,32,116,111,32,98,101,32, + 116,114,117,110,99,97,116,101,100,46,10,10,32,32,32,32, + 78,114,15,0,0,0,122,20,98,97,100,32,109,97,103,105, + 99,32,110,117,109,98,101,114,32,105,110,32,122,2,58,32, + 250,2,123,125,233,16,0,0,0,122,40,114,101,97,99,104, + 101,100,32,69,79,70,32,119,104,105,108,101,32,114,101,97, + 100,105,110,103,32,112,121,99,32,104,101,97,100,101,114,32, + 111,102,32,233,8,0,0,0,233,252,255,255,255,122,14,105, + 110,118,97,108,105,100,32,102,108,97,103,115,32,122,4,32, + 105,110,32,41,7,218,12,77,65,71,73,67,95,78,85,77, + 66,69,82,114,134,0,0,0,218,16,95,118,101,114,98,111, + 115,101,95,109,101,115,115,97,103,101,114,118,0,0,0,114, + 22,0,0,0,218,8,69,79,70,69,114,114,111,114,114,27, + 0,0,0,41,6,114,26,0,0,0,114,117,0,0,0,218, + 11,101,120,99,95,100,101,116,97,105,108,115,90,5,109,97, + 103,105,99,114,93,0,0,0,114,83,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,99, + 108,97,115,115,105,102,121,95,112,121,99,232,1,0,0,115, + 28,0,0,0,0,16,12,1,8,1,16,1,12,1,12,1, + 12,1,10,1,12,1,8,1,16,2,8,1,16,1,12,1, + 114,152,0,0,0,99,5,0,0,0,0,0,0,0,0,0, + 0,0,6,0,0,0,4,0,0,0,67,0,0,0,115,112, + 0,0,0,116,0,124,0,100,1,100,2,133,2,25,0,131, + 1,124,1,100,3,64,0,107,3,114,58,100,4,124,3,155, + 2,157,2,125,5,116,1,160,2,100,5,124,5,161,2,1, + 0,116,3,124,5,102,1,124,4,142,1,130,1,124,2,100, + 6,107,9,114,108,116,0,124,0,100,2,100,7,133,2,25, + 0,131,1,124,2,100,3,64,0,107,3,114,108,116,3,100, + 4,124,3,155,2,157,2,102,1,124,4,142,1,130,1,100, + 6,83,0,41,8,97,7,2,0,0,86,97,108,105,100,97, + 116,101,32,97,32,112,121,99,32,97,103,97,105,110,115,116, + 32,116,104,101,32,115,111,117,114,99,101,32,108,97,115,116, + 45,109,111,100,105,102,105,101,100,32,116,105,109,101,46,10, + 10,32,32,32,32,42,100,97,116,97,42,32,105,115,32,116, + 104,101,32,99,111,110,116,101,110,116,115,32,111,102,32,116, + 104,101,32,112,121,99,32,102,105,108,101,46,32,40,79,110, + 108,121,32,116,104,101,32,102,105,114,115,116,32,49,54,32, + 98,121,116,101,115,32,97,114,101,10,32,32,32,32,114,101, + 113,117,105,114,101,100,46,41,10,10,32,32,32,32,42,115, + 111,117,114,99,101,95,109,116,105,109,101,42,32,105,115,32, + 116,104,101,32,108,97,115,116,32,109,111,100,105,102,105,101, + 100,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116, + 104,101,32,115,111,117,114,99,101,32,102,105,108,101,46,10, + 10,32,32,32,32,42,115,111,117,114,99,101,95,115,105,122, + 101,42,32,105,115,32,78,111,110,101,32,111,114,32,116,104, + 101,32,115,105,122,101,32,111,102,32,116,104,101,32,115,111, + 117,114,99,101,32,102,105,108,101,32,105,110,32,98,121,116, + 101,115,46,10,10,32,32,32,32,42,110,97,109,101,42,32, + 105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,116, + 104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,32, + 105,109,112,111,114,116,101,100,46,32,73,116,32,105,115,32, + 117,115,101,100,32,102,111,114,32,108,111,103,103,105,110,103, + 46,10,10,32,32,32,32,42,101,120,99,95,100,101,116,97, + 105,108,115,42,32,105,115,32,97,32,100,105,99,116,105,111, + 110,97,114,121,32,112,97,115,115,101,100,32,116,111,32,73, + 109,112,111,114,116,69,114,114,111,114,32,105,102,32,105,116, + 32,114,97,105,115,101,100,32,102,111,114,10,32,32,32,32, + 105,109,112,114,111,118,101,100,32,100,101,98,117,103,103,105, + 110,103,46,10,10,32,32,32,32,65,110,32,73,109,112,111, + 114,116,69,114,114,111,114,32,105,115,32,114,97,105,115,101, + 100,32,105,102,32,116,104,101,32,98,121,116,101,99,111,100, + 101,32,105,115,32,115,116,97,108,101,46,10,10,32,32,32, + 32,114,146,0,0,0,233,12,0,0,0,114,14,0,0,0, + 122,22,98,121,116,101,99,111,100,101,32,105,115,32,115,116, + 97,108,101,32,102,111,114,32,114,144,0,0,0,78,114,145, + 0,0,0,41,4,114,27,0,0,0,114,134,0,0,0,114, + 149,0,0,0,114,118,0,0,0,41,6,114,26,0,0,0, + 218,12,115,111,117,114,99,101,95,109,116,105,109,101,218,11, + 115,111,117,114,99,101,95,115,105,122,101,114,117,0,0,0, + 114,151,0,0,0,114,93,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,23,95,118,97,108,105, + 100,97,116,101,95,116,105,109,101,115,116,97,109,112,95,112, + 121,99,9,2,0,0,115,16,0,0,0,0,19,24,1,10, + 1,12,1,12,1,8,1,22,255,2,2,114,156,0,0,0, + 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, 100,1,100,2,133,2,25,0,124,1,107,3,114,34,116,0, 100,3,124,2,155,2,157,2,102,1,124,3,142,1,130,1, @@ -790,69 +797,70 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 104,97,115,104,114,117,0,0,0,114,151,0,0,0,114,3, 0,0,0,114,3,0,0,0,114,6,0,0,0,218,18,95, 118,97,108,105,100,97,116,101,95,104,97,115,104,95,112,121, - 99,36,2,0,0,115,12,0,0,0,0,17,16,1,2,1, + 99,37,2,0,0,115,12,0,0,0,0,17,16,1,2,1, 8,255,2,2,2,254,114,158,0,0,0,99,4,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,82,0,0,0,116,0,160,1,124,0,161, + 1,125,4,116,2,124,4,116,3,131,2,114,58,116,4,160, + 5,100,1,124,2,161,2,1,0,124,3,100,2,107,9,114, + 52,116,6,160,7,124,4,124,3,161,2,1,0,124,4,83, + 0,110,20,116,8,100,3,160,9,124,2,161,1,124,1,124, + 2,100,4,141,3,130,1,100,2,83,0,41,5,122,35,67, + 111,109,112,105,108,101,32,98,121,116,101,99,111,100,101,32, + 97,115,32,102,111,117,110,100,32,105,110,32,97,32,112,121, + 99,46,122,21,99,111,100,101,32,111,98,106,101,99,116,32, + 102,114,111,109,32,123,33,114,125,78,122,23,78,111,110,45, + 99,111,100,101,32,111,98,106,101,99,116,32,105,110,32,123, + 33,114,125,169,2,114,117,0,0,0,114,44,0,0,0,41, + 10,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, + 115,218,10,105,115,105,110,115,116,97,110,99,101,218,10,95, + 99,111,100,101,95,116,121,112,101,114,134,0,0,0,114,149, + 0,0,0,218,4,95,105,109,112,90,16,95,102,105,120,95, + 99,111,95,102,105,108,101,110,97,109,101,114,118,0,0,0, + 114,62,0,0,0,41,5,114,26,0,0,0,114,117,0,0, + 0,114,107,0,0,0,114,108,0,0,0,218,4,99,111,100, + 101,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,17,95,99,111,109,112,105,108,101,95,98,121,116,101,99, + 111,100,101,61,2,0,0,115,20,0,0,0,0,2,10,1, + 10,1,12,1,8,1,12,1,6,2,10,1,2,0,2,255, + 114,165,0,0,0,114,73,0,0,0,99,3,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,67, + 0,0,0,115,70,0,0,0,116,0,116,1,131,1,125,3, + 124,3,160,2,116,3,100,1,131,1,161,1,1,0,124,3, + 160,2,116,3,124,1,131,1,161,1,1,0,124,3,160,2, + 116,3,124,2,131,1,161,1,1,0,124,3,160,2,116,4, + 160,5,124,0,161,1,161,1,1,0,124,3,83,0,41,2, + 122,43,80,114,111,100,117,99,101,32,116,104,101,32,100,97, + 116,97,32,102,111,114,32,97,32,116,105,109,101,115,116,97, + 109,112,45,98,97,115,101,100,32,112,121,99,46,114,73,0, + 0,0,41,6,218,9,98,121,116,101,97,114,114,97,121,114, + 148,0,0,0,218,6,101,120,116,101,110,100,114,20,0,0, + 0,114,160,0,0,0,218,5,100,117,109,112,115,41,4,114, + 164,0,0,0,218,5,109,116,105,109,101,114,155,0,0,0, + 114,26,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,22,95,99,111,100,101,95,116,111,95,116, + 105,109,101,115,116,97,109,112,95,112,121,99,74,2,0,0, + 115,12,0,0,0,0,2,8,1,14,1,14,1,14,1,16, + 1,114,170,0,0,0,84,99,3,0,0,0,0,0,0,0, 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,82,0,0,0,116,0,160,1,124,0,161,1,125,4,116, - 2,124,4,116,3,131,2,114,58,116,4,160,5,100,1,124, - 2,161,2,1,0,124,3,100,2,107,9,114,52,116,6,160, - 7,124,4,124,3,161,2,1,0,124,4,83,0,110,20,116, - 8,100,3,160,9,124,2,161,1,124,1,124,2,100,4,141, - 3,130,1,100,2,83,0,41,5,122,35,67,111,109,112,105, - 108,101,32,98,121,116,101,99,111,100,101,32,97,115,32,102, - 111,117,110,100,32,105,110,32,97,32,112,121,99,46,122,21, - 99,111,100,101,32,111,98,106,101,99,116,32,102,114,111,109, - 32,123,33,114,125,78,122,23,78,111,110,45,99,111,100,101, - 32,111,98,106,101,99,116,32,105,110,32,123,33,114,125,169, - 2,114,117,0,0,0,114,44,0,0,0,41,10,218,7,109, - 97,114,115,104,97,108,90,5,108,111,97,100,115,218,10,105, - 115,105,110,115,116,97,110,99,101,218,10,95,99,111,100,101, - 95,116,121,112,101,114,134,0,0,0,114,149,0,0,0,218, - 4,95,105,109,112,90,16,95,102,105,120,95,99,111,95,102, - 105,108,101,110,97,109,101,114,118,0,0,0,114,62,0,0, - 0,41,5,114,26,0,0,0,114,117,0,0,0,114,107,0, - 0,0,114,108,0,0,0,218,4,99,111,100,101,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,17,95,99, - 111,109,112,105,108,101,95,98,121,116,101,99,111,100,101,60, - 2,0,0,115,20,0,0,0,0,2,10,1,10,1,12,1, - 8,1,12,1,6,2,10,1,2,0,2,255,114,165,0,0, - 0,114,73,0,0,0,99,3,0,0,0,0,0,0,0,4, - 0,0,0,5,0,0,0,67,0,0,0,115,70,0,0,0, - 116,0,116,1,131,1,125,3,124,3,160,2,116,3,100,1, - 131,1,161,1,1,0,124,3,160,2,116,3,124,1,131,1, - 161,1,1,0,124,3,160,2,116,3,124,2,131,1,161,1, - 1,0,124,3,160,2,116,4,160,5,124,0,161,1,161,1, - 1,0,124,3,83,0,41,2,122,43,80,114,111,100,117,99, - 101,32,116,104,101,32,100,97,116,97,32,102,111,114,32,97, - 32,116,105,109,101,115,116,97,109,112,45,98,97,115,101,100, - 32,112,121,99,46,114,73,0,0,0,41,6,218,9,98,121, - 116,101,97,114,114,97,121,114,148,0,0,0,218,6,101,120, - 116,101,110,100,114,20,0,0,0,114,160,0,0,0,218,5, - 100,117,109,112,115,41,4,114,164,0,0,0,218,5,109,116, - 105,109,101,114,155,0,0,0,114,26,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,22,95,99, - 111,100,101,95,116,111,95,116,105,109,101,115,116,97,109,112, - 95,112,121,99,73,2,0,0,115,12,0,0,0,0,2,8, - 1,14,1,14,1,14,1,16,1,114,170,0,0,0,84,99, - 3,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, - 67,0,0,0,115,80,0,0,0,116,0,116,1,131,1,125, - 3,100,1,124,2,100,1,62,0,66,0,125,4,124,3,160, - 2,116,3,124,4,131,1,161,1,1,0,116,4,124,1,131, - 1,100,2,107,2,115,50,116,5,130,1,124,3,160,2,124, - 1,161,1,1,0,124,3,160,2,116,6,160,7,124,0,161, - 1,161,1,1,0,124,3,83,0,41,3,122,38,80,114,111, - 100,117,99,101,32,116,104,101,32,100,97,116,97,32,102,111, - 114,32,97,32,104,97,115,104,45,98,97,115,101,100,32,112, - 121,99,46,114,39,0,0,0,114,146,0,0,0,41,8,114, - 166,0,0,0,114,148,0,0,0,114,167,0,0,0,114,20, - 0,0,0,114,22,0,0,0,114,23,0,0,0,114,160,0, - 0,0,114,168,0,0,0,41,5,114,164,0,0,0,114,157, - 0,0,0,90,7,99,104,101,99,107,101,100,114,26,0,0, - 0,114,83,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,17,95,99,111,100,101,95,116,111,95, - 104,97,115,104,95,112,121,99,83,2,0,0,115,14,0,0, - 0,0,2,8,1,12,1,14,1,16,1,10,1,16,1,114, - 171,0,0,0,99,1,0,0,0,0,0,0,0,5,0,0, + 115,80,0,0,0,116,0,116,1,131,1,125,3,100,1,124, + 2,100,1,62,0,66,0,125,4,124,3,160,2,116,3,124, + 4,131,1,161,1,1,0,116,4,124,1,131,1,100,2,107, + 2,115,50,116,5,130,1,124,3,160,2,124,1,161,1,1, + 0,124,3,160,2,116,6,160,7,124,0,161,1,161,1,1, + 0,124,3,83,0,41,3,122,38,80,114,111,100,117,99,101, + 32,116,104,101,32,100,97,116,97,32,102,111,114,32,97,32, + 104,97,115,104,45,98,97,115,101,100,32,112,121,99,46,114, + 39,0,0,0,114,146,0,0,0,41,8,114,166,0,0,0, + 114,148,0,0,0,114,167,0,0,0,114,20,0,0,0,114, + 22,0,0,0,114,23,0,0,0,114,160,0,0,0,114,168, + 0,0,0,41,5,114,164,0,0,0,114,157,0,0,0,90, + 7,99,104,101,99,107,101,100,114,26,0,0,0,114,83,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,17,95,99,111,100,101,95,116,111,95,104,97,115,104, + 95,112,121,99,84,2,0,0,115,14,0,0,0,0,2,8, + 1,12,1,14,1,16,1,10,1,16,1,114,171,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, 0,6,0,0,0,67,0,0,0,115,62,0,0,0,100,1, 100,2,108,0,125,1,116,1,160,2,124,0,161,1,106,3, 125,2,124,1,160,4,124,2,161,1,125,3,116,1,160,5, @@ -877,110 +885,111 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 108,105,110,101,218,8,101,110,99,111,100,105,110,103,90,15, 110,101,119,108,105,110,101,95,100,101,99,111,100,101,114,114, 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,13, - 100,101,99,111,100,101,95,115,111,117,114,99,101,94,2,0, + 100,101,99,111,100,101,95,115,111,117,114,99,101,95,2,0, 0,115,10,0,0,0,0,5,8,1,12,1,10,1,12,1, 114,176,0,0,0,169,2,114,140,0,0,0,218,26,115,117, 98,109,111,100,117,108,101,95,115,101,97,114,99,104,95,108, - 111,99,97,116,105,111,110,115,99,2,0,0,0,2,0,0, - 0,9,0,0,0,8,0,0,0,67,0,0,0,115,16,1, - 0,0,124,1,100,1,107,8,114,60,100,2,125,1,116,0, - 124,2,100,3,131,2,114,70,122,14,124,2,160,1,124,0, - 161,1,125,1,87,0,113,70,4,0,116,2,107,10,114,56, - 1,0,1,0,1,0,89,0,113,70,88,0,110,10,116,3, - 160,4,124,1,161,1,125,1,116,5,106,6,124,0,124,2, - 124,1,100,4,141,3,125,4,100,5,124,4,95,7,124,2, - 100,1,107,8,114,154,116,8,131,0,68,0,93,42,92,2, - 125,5,125,6,124,1,160,9,116,10,124,6,131,1,161,1, - 114,106,124,5,124,0,124,1,131,2,125,2,124,2,124,4, - 95,11,1,0,113,154,113,106,100,1,83,0,124,3,116,12, - 107,8,114,220,116,0,124,2,100,6,131,2,114,226,122,14, - 124,2,160,13,124,0,161,1,125,7,87,0,110,20,4,0, - 116,2,107,10,114,206,1,0,1,0,1,0,89,0,113,226, - 88,0,124,7,114,226,103,0,124,4,95,14,110,6,124,3, - 124,4,95,14,124,4,106,14,103,0,107,2,144,1,114,12, - 124,1,144,1,114,12,116,15,124,1,131,1,100,7,25,0, - 125,8,124,4,106,14,160,16,124,8,161,1,1,0,124,4, - 83,0,41,8,97,61,1,0,0,82,101,116,117,114,110,32, - 97,32,109,111,100,117,108,101,32,115,112,101,99,32,98,97, - 115,101,100,32,111,110,32,97,32,102,105,108,101,32,108,111, - 99,97,116,105,111,110,46,10,10,32,32,32,32,84,111,32, - 105,110,100,105,99,97,116,101,32,116,104,97,116,32,116,104, - 101,32,109,111,100,117,108,101,32,105,115,32,97,32,112,97, - 99,107,97,103,101,44,32,115,101,116,10,32,32,32,32,115, - 117,98,109,111,100,117,108,101,95,115,101,97,114,99,104,95, - 108,111,99,97,116,105,111,110,115,32,116,111,32,97,32,108, - 105,115,116,32,111,102,32,100,105,114,101,99,116,111,114,121, - 32,112,97,116,104,115,46,32,32,65,110,10,32,32,32,32, - 101,109,112,116,121,32,108,105,115,116,32,105,115,32,115,117, - 102,102,105,99,105,101,110,116,44,32,116,104,111,117,103,104, - 32,105,116,115,32,110,111,116,32,111,116,104,101,114,119,105, - 115,101,32,117,115,101,102,117,108,32,116,111,32,116,104,101, - 10,32,32,32,32,105,109,112,111,114,116,32,115,121,115,116, - 101,109,46,10,10,32,32,32,32,84,104,101,32,108,111,97, - 100,101,114,32,109,117,115,116,32,116,97,107,101,32,97,32, - 115,112,101,99,32,97,115,32,105,116,115,32,111,110,108,121, - 32,95,95,105,110,105,116,95,95,40,41,32,97,114,103,46, - 10,10,32,32,32,32,78,122,9,60,117,110,107,110,111,119, - 110,62,218,12,103,101,116,95,102,105,108,101,110,97,109,101, - 169,1,218,6,111,114,105,103,105,110,84,218,10,105,115,95, - 112,97,99,107,97,103,101,114,73,0,0,0,41,17,114,128, - 0,0,0,114,179,0,0,0,114,118,0,0,0,114,2,0, - 0,0,114,79,0,0,0,114,134,0,0,0,218,10,77,111, - 100,117,108,101,83,112,101,99,90,13,95,115,101,116,95,102, - 105,108,101,97,116,116,114,218,27,95,103,101,116,95,115,117, - 112,112,111,114,116,101,100,95,102,105,108,101,95,108,111,97, - 100,101,114,115,114,111,0,0,0,114,112,0,0,0,114,140, - 0,0,0,218,9,95,80,79,80,85,76,65,84,69,114,182, - 0,0,0,114,178,0,0,0,114,47,0,0,0,218,6,97, - 112,112,101,110,100,41,9,114,117,0,0,0,90,8,108,111, - 99,97,116,105,111,110,114,140,0,0,0,114,178,0,0,0, - 218,4,115,112,101,99,218,12,108,111,97,100,101,114,95,99, - 108,97,115,115,218,8,115,117,102,102,105,120,101,115,114,182, - 0,0,0,90,7,100,105,114,110,97,109,101,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,23,115,112,101, - 99,95,102,114,111,109,95,102,105,108,101,95,108,111,99,97, - 116,105,111,110,111,2,0,0,115,62,0,0,0,0,12,8, - 4,4,1,10,2,2,1,14,1,14,1,8,2,10,8,16, - 1,6,3,8,1,14,1,14,1,10,1,6,1,6,2,4, - 3,8,2,10,1,2,1,14,1,14,1,6,2,4,1,8, - 2,6,1,12,1,6,1,12,1,12,2,114,190,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,86,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,90,4,100,3,90,5,100,4, - 90,6,101,7,100,5,100,6,132,0,131,1,90,8,101,7, - 100,7,100,8,132,0,131,1,90,9,101,7,100,9,100,9, - 102,2,100,10,100,11,132,1,131,1,90,10,101,7,100,9, - 102,1,100,12,100,13,132,1,131,1,90,11,100,9,83,0, - 41,14,218,21,87,105,110,100,111,119,115,82,101,103,105,115, - 116,114,121,70,105,110,100,101,114,122,62,77,101,116,97,32, - 112,97,116,104,32,102,105,110,100,101,114,32,102,111,114,32, - 109,111,100,117,108,101,115,32,100,101,99,108,97,114,101,100, - 32,105,110,32,116,104,101,32,87,105,110,100,111,119,115,32, - 114,101,103,105,115,116,114,121,46,122,59,83,111,102,116,119, - 97,114,101,92,80,121,116,104,111,110,92,80,121,116,104,111, - 110,67,111,114,101,92,123,115,121,115,95,118,101,114,115,105, - 111,110,125,92,77,111,100,117,108,101,115,92,123,102,117,108, - 108,110,97,109,101,125,122,65,83,111,102,116,119,97,114,101, - 92,80,121,116,104,111,110,92,80,121,116,104,111,110,67,111, - 114,101,92,123,115,121,115,95,118,101,114,115,105,111,110,125, - 92,77,111,100,117,108,101,115,92,123,102,117,108,108,110,97, - 109,101,125,92,68,101,98,117,103,70,99,2,0,0,0,0, - 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, - 56,0,0,0,122,16,116,0,160,1,116,0,106,2,124,1, - 161,2,87,0,83,0,4,0,116,3,107,10,114,50,1,0, - 1,0,1,0,116,0,160,1,116,0,106,4,124,1,161,2, - 6,0,89,0,83,0,88,0,100,0,83,0,114,110,0,0, - 0,41,5,218,7,95,119,105,110,114,101,103,90,7,79,112, - 101,110,75,101,121,90,17,72,75,69,89,95,67,85,82,82, - 69,78,84,95,85,83,69,82,114,50,0,0,0,90,18,72, - 75,69,89,95,76,79,67,65,76,95,77,65,67,72,73,78, - 69,41,2,218,3,99,108,115,114,5,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,14,95,111, - 112,101,110,95,114,101,103,105,115,116,114,121,191,2,0,0, - 115,8,0,0,0,0,2,2,1,16,1,14,1,122,36,87, - 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, - 110,100,101,114,46,95,111,112,101,110,95,114,101,103,105,115, - 116,114,121,99,2,0,0,0,0,0,0,0,6,0,0,0, + 111,99,97,116,105,111,110,115,99,2,0,0,0,0,0,0, + 0,2,0,0,0,9,0,0,0,8,0,0,0,67,0,0, + 0,115,16,1,0,0,124,1,100,1,107,8,114,60,100,2, + 125,1,116,0,124,2,100,3,131,2,114,70,122,14,124,2, + 160,1,124,0,161,1,125,1,87,0,113,70,4,0,116,2, + 107,10,114,56,1,0,1,0,1,0,89,0,113,70,88,0, + 110,10,116,3,160,4,124,1,161,1,125,1,116,5,106,6, + 124,0,124,2,124,1,100,4,141,3,125,4,100,5,124,4, + 95,7,124,2,100,1,107,8,114,154,116,8,131,0,68,0, + 93,42,92,2,125,5,125,6,124,1,160,9,116,10,124,6, + 131,1,161,1,114,106,124,5,124,0,124,1,131,2,125,2, + 124,2,124,4,95,11,1,0,113,154,113,106,100,1,83,0, + 124,3,116,12,107,8,114,220,116,0,124,2,100,6,131,2, + 114,226,122,14,124,2,160,13,124,0,161,1,125,7,87,0, + 110,20,4,0,116,2,107,10,114,206,1,0,1,0,1,0, + 89,0,113,226,88,0,124,7,114,226,103,0,124,4,95,14, + 110,6,124,3,124,4,95,14,124,4,106,14,103,0,107,2, + 144,1,114,12,124,1,144,1,114,12,116,15,124,1,131,1, + 100,7,25,0,125,8,124,4,106,14,160,16,124,8,161,1, + 1,0,124,4,83,0,41,8,97,61,1,0,0,82,101,116, + 117,114,110,32,97,32,109,111,100,117,108,101,32,115,112,101, + 99,32,98,97,115,101,100,32,111,110,32,97,32,102,105,108, + 101,32,108,111,99,97,116,105,111,110,46,10,10,32,32,32, + 32,84,111,32,105,110,100,105,99,97,116,101,32,116,104,97, + 116,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, + 97,32,112,97,99,107,97,103,101,44,32,115,101,116,10,32, + 32,32,32,115,117,98,109,111,100,117,108,101,95,115,101,97, + 114,99,104,95,108,111,99,97,116,105,111,110,115,32,116,111, + 32,97,32,108,105,115,116,32,111,102,32,100,105,114,101,99, + 116,111,114,121,32,112,97,116,104,115,46,32,32,65,110,10, + 32,32,32,32,101,109,112,116,121,32,108,105,115,116,32,105, + 115,32,115,117,102,102,105,99,105,101,110,116,44,32,116,104, + 111,117,103,104,32,105,116,115,32,110,111,116,32,111,116,104, + 101,114,119,105,115,101,32,117,115,101,102,117,108,32,116,111, + 32,116,104,101,10,32,32,32,32,105,109,112,111,114,116,32, + 115,121,115,116,101,109,46,10,10,32,32,32,32,84,104,101, + 32,108,111,97,100,101,114,32,109,117,115,116,32,116,97,107, + 101,32,97,32,115,112,101,99,32,97,115,32,105,116,115,32, + 111,110,108,121,32,95,95,105,110,105,116,95,95,40,41,32, + 97,114,103,46,10,10,32,32,32,32,78,122,9,60,117,110, + 107,110,111,119,110,62,218,12,103,101,116,95,102,105,108,101, + 110,97,109,101,169,1,218,6,111,114,105,103,105,110,84,218, + 10,105,115,95,112,97,99,107,97,103,101,114,73,0,0,0, + 41,17,114,128,0,0,0,114,179,0,0,0,114,118,0,0, + 0,114,2,0,0,0,114,79,0,0,0,114,134,0,0,0, + 218,10,77,111,100,117,108,101,83,112,101,99,90,13,95,115, + 101,116,95,102,105,108,101,97,116,116,114,218,27,95,103,101, + 116,95,115,117,112,112,111,114,116,101,100,95,102,105,108,101, + 95,108,111,97,100,101,114,115,114,111,0,0,0,114,112,0, + 0,0,114,140,0,0,0,218,9,95,80,79,80,85,76,65, + 84,69,114,182,0,0,0,114,178,0,0,0,114,47,0,0, + 0,218,6,97,112,112,101,110,100,41,9,114,117,0,0,0, + 90,8,108,111,99,97,116,105,111,110,114,140,0,0,0,114, + 178,0,0,0,218,4,115,112,101,99,218,12,108,111,97,100, + 101,114,95,99,108,97,115,115,218,8,115,117,102,102,105,120, + 101,115,114,182,0,0,0,90,7,100,105,114,110,97,109,101, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 23,115,112,101,99,95,102,114,111,109,95,102,105,108,101,95, + 108,111,99,97,116,105,111,110,112,2,0,0,115,62,0,0, + 0,0,12,8,4,4,1,10,2,2,1,14,1,14,1,8, + 2,10,8,16,1,6,3,8,1,14,1,14,1,10,1,6, + 1,6,2,4,3,8,2,10,1,2,1,14,1,14,1,6, + 2,4,1,8,2,6,1,12,1,6,1,12,1,12,2,114, + 190,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,86,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 90,4,100,3,90,5,100,4,90,6,101,7,100,5,100,6, + 132,0,131,1,90,8,101,7,100,7,100,8,132,0,131,1, + 90,9,101,7,100,9,100,9,102,2,100,10,100,11,132,1, + 131,1,90,10,101,7,100,9,102,1,100,12,100,13,132,1, + 131,1,90,11,100,9,83,0,41,14,218,21,87,105,110,100, + 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, + 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, + 100,101,114,32,102,111,114,32,109,111,100,117,108,101,115,32, + 100,101,99,108,97,114,101,100,32,105,110,32,116,104,101,32, + 87,105,110,100,111,119,115,32,114,101,103,105,115,116,114,121, + 46,122,59,83,111,102,116,119,97,114,101,92,80,121,116,104, + 111,110,92,80,121,116,104,111,110,67,111,114,101,92,123,115, + 121,115,95,118,101,114,115,105,111,110,125,92,77,111,100,117, + 108,101,115,92,123,102,117,108,108,110,97,109,101,125,122,65, + 83,111,102,116,119,97,114,101,92,80,121,116,104,111,110,92, + 80,121,116,104,111,110,67,111,114,101,92,123,115,121,115,95, + 118,101,114,115,105,111,110,125,92,77,111,100,117,108,101,115, + 92,123,102,117,108,108,110,97,109,101,125,92,68,101,98,117, + 103,70,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,8,0,0,0,67,0,0,0,115,56,0,0,0, + 122,16,116,0,160,1,116,0,106,2,124,1,161,2,87,0, + 83,0,4,0,116,3,107,10,114,50,1,0,1,0,1,0, + 116,0,160,1,116,0,106,4,124,1,161,2,6,0,89,0, + 83,0,88,0,100,0,83,0,114,110,0,0,0,41,5,218, + 7,95,119,105,110,114,101,103,90,7,79,112,101,110,75,101, + 121,90,17,72,75,69,89,95,67,85,82,82,69,78,84,95, + 85,83,69,82,114,50,0,0,0,90,18,72,75,69,89,95, + 76,79,67,65,76,95,77,65,67,72,73,78,69,41,2,218, + 3,99,108,115,114,5,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,14,95,111,112,101,110,95, + 114,101,103,105,115,116,114,121,192,2,0,0,115,8,0,0, + 0,0,2,2,1,16,1,14,1,122,36,87,105,110,100,111, + 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, + 46,95,111,112,101,110,95,114,101,103,105,115,116,114,121,99, + 2,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, 9,0,0,0,67,0,0,0,115,118,0,0,0,124,0,106, 0,114,14,124,0,106,1,125,2,110,6,124,0,106,2,125, 2,124,2,106,3,124,1,100,1,116,4,106,5,100,0,100, @@ -1002,72 +1011,73 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 105,115,116,114,121,95,107,101,121,114,5,0,0,0,90,4, 104,107,101,121,218,8,102,105,108,101,112,97,116,104,114,3, 0,0,0,114,3,0,0,0,114,6,0,0,0,218,16,95, - 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,198, + 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,199, 2,0,0,115,24,0,0,0,0,2,6,1,8,2,6,1, 6,1,16,255,6,2,2,1,12,1,26,1,14,1,12,1, 122,38,87,105,110,100,111,119,115,82,101,103,105,115,116,114, 121,70,105,110,100,101,114,46,95,115,101,97,114,99,104,95, 114,101,103,105,115,116,114,121,78,99,4,0,0,0,0,0, - 0,0,8,0,0,0,8,0,0,0,67,0,0,0,115,122, - 0,0,0,124,0,160,0,124,1,161,1,125,4,124,4,100, - 0,107,8,114,22,100,0,83,0,122,12,116,1,124,4,131, - 1,1,0,87,0,110,22,4,0,116,2,107,10,114,56,1, - 0,1,0,1,0,89,0,100,0,83,0,88,0,116,3,131, - 0,68,0,93,52,92,2,125,5,125,6,124,4,160,4,116, - 5,124,6,131,1,161,1,114,64,116,6,106,7,124,1,124, - 5,124,1,124,4,131,2,124,4,100,1,141,3,125,7,124, - 7,2,0,1,0,83,0,113,64,100,0,83,0,41,2,78, - 114,180,0,0,0,41,8,114,200,0,0,0,114,49,0,0, - 0,114,50,0,0,0,114,184,0,0,0,114,111,0,0,0, - 114,112,0,0,0,114,134,0,0,0,218,16,115,112,101,99, - 95,102,114,111,109,95,108,111,97,100,101,114,41,8,114,193, - 0,0,0,114,139,0,0,0,114,44,0,0,0,218,6,116, - 97,114,103,101,116,114,199,0,0,0,114,140,0,0,0,114, - 189,0,0,0,114,187,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,9,102,105,110,100,95,115, - 112,101,99,213,2,0,0,115,28,0,0,0,0,2,10,1, - 8,1,4,1,2,1,12,1,14,1,8,1,14,1,14,1, - 6,1,8,1,2,254,6,3,122,31,87,105,110,100,111,119, - 115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,46, - 102,105,110,100,95,115,112,101,99,99,3,0,0,0,0,0, - 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,34, - 0,0,0,124,0,160,0,124,1,124,2,161,2,125,3,124, - 3,100,1,107,9,114,26,124,3,106,1,83,0,100,1,83, - 0,100,1,83,0,41,2,122,108,70,105,110,100,32,109,111, - 100,117,108,101,32,110,97,109,101,100,32,105,110,32,116,104, - 101,32,114,101,103,105,115,116,114,121,46,10,10,32,32,32, - 32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,100, - 32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,32, - 32,85,115,101,32,101,120,101,99,95,109,111,100,117,108,101, - 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, - 32,32,32,32,32,78,169,2,114,203,0,0,0,114,140,0, - 0,0,169,4,114,193,0,0,0,114,139,0,0,0,114,44, - 0,0,0,114,187,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,11,102,105,110,100,95,109,111, - 100,117,108,101,229,2,0,0,115,8,0,0,0,0,7,12, - 1,8,1,6,2,122,33,87,105,110,100,111,119,115,82,101, - 103,105,115,116,114,121,70,105,110,100,101,114,46,102,105,110, - 100,95,109,111,100,117,108,101,41,12,114,125,0,0,0,114, - 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,197, - 0,0,0,114,196,0,0,0,114,195,0,0,0,218,11,99, - 108,97,115,115,109,101,116,104,111,100,114,194,0,0,0,114, - 200,0,0,0,114,203,0,0,0,114,206,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,191,0,0,0,179,2,0,0,115,28,0,0,0, - 8,2,4,3,2,255,2,4,2,255,2,3,4,2,2,1, - 10,6,2,1,10,14,2,1,16,15,2,1,114,191,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,64,0,0,0,115,48,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, - 4,100,5,132,0,90,5,100,6,100,7,132,0,90,6,100, - 8,100,9,132,0,90,7,100,10,83,0,41,11,218,13,95, - 76,111,97,100,101,114,66,97,115,105,99,115,122,83,66,97, - 115,101,32,99,108,97,115,115,32,111,102,32,99,111,109,109, - 111,110,32,99,111,100,101,32,110,101,101,100,101,100,32,98, - 121,32,98,111,116,104,32,83,111,117,114,99,101,76,111,97, - 100,101,114,32,97,110,100,10,32,32,32,32,83,111,117,114, - 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, - 46,99,2,0,0,0,0,0,0,0,5,0,0,0,4,0, + 0,0,0,0,0,0,8,0,0,0,8,0,0,0,67,0, + 0,0,115,122,0,0,0,124,0,160,0,124,1,161,1,125, + 4,124,4,100,0,107,8,114,22,100,0,83,0,122,12,116, + 1,124,4,131,1,1,0,87,0,110,22,4,0,116,2,107, + 10,114,56,1,0,1,0,1,0,89,0,100,0,83,0,88, + 0,116,3,131,0,68,0,93,52,92,2,125,5,125,6,124, + 4,160,4,116,5,124,6,131,1,161,1,114,64,116,6,106, + 7,124,1,124,5,124,1,124,4,131,2,124,4,100,1,141, + 3,125,7,124,7,2,0,1,0,83,0,113,64,100,0,83, + 0,41,2,78,114,180,0,0,0,41,8,114,200,0,0,0, + 114,49,0,0,0,114,50,0,0,0,114,184,0,0,0,114, + 111,0,0,0,114,112,0,0,0,114,134,0,0,0,218,16, + 115,112,101,99,95,102,114,111,109,95,108,111,97,100,101,114, + 41,8,114,193,0,0,0,114,139,0,0,0,114,44,0,0, + 0,218,6,116,97,114,103,101,116,114,199,0,0,0,114,140, + 0,0,0,114,189,0,0,0,114,187,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,9,102,105, + 110,100,95,115,112,101,99,214,2,0,0,115,28,0,0,0, + 0,2,10,1,8,1,4,1,2,1,12,1,14,1,8,1, + 14,1,14,1,6,1,8,1,2,254,6,3,122,31,87,105, + 110,100,111,119,115,82,101,103,105,115,116,114,121,70,105,110, + 100,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0, + 0,0,67,0,0,0,115,34,0,0,0,124,0,160,0,124, + 1,124,2,161,2,125,3,124,3,100,1,107,9,114,26,124, + 3,106,1,83,0,100,1,83,0,100,1,83,0,41,2,122, + 108,70,105,110,100,32,109,111,100,117,108,101,32,110,97,109, + 101,100,32,105,110,32,116,104,101,32,114,101,103,105,115,116, + 114,121,46,10,10,32,32,32,32,32,32,32,32,84,104,105, + 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,85,115,101,32,101,120,101, + 99,95,109,111,100,117,108,101,40,41,32,105,110,115,116,101, + 97,100,46,10,10,32,32,32,32,32,32,32,32,78,169,2, + 114,203,0,0,0,114,140,0,0,0,169,4,114,193,0,0, + 0,114,139,0,0,0,114,44,0,0,0,114,187,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 11,102,105,110,100,95,109,111,100,117,108,101,230,2,0,0, + 115,8,0,0,0,0,7,12,1,8,1,6,2,122,33,87, + 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, + 110,100,101,114,46,102,105,110,100,95,109,111,100,117,108,101, + 41,12,114,125,0,0,0,114,124,0,0,0,114,126,0,0, + 0,114,127,0,0,0,114,197,0,0,0,114,196,0,0,0, + 114,195,0,0,0,218,11,99,108,97,115,115,109,101,116,104, + 111,100,114,194,0,0,0,114,200,0,0,0,114,203,0,0, + 0,114,206,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,191,0,0,0,180, + 2,0,0,115,28,0,0,0,8,2,4,3,2,255,2,4, + 2,255,2,3,4,2,2,1,10,6,2,1,10,14,2,1, + 16,15,2,1,114,191,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, + 0,0,115,48,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, + 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, + 0,90,7,100,10,83,0,41,11,218,13,95,76,111,97,100, + 101,114,66,97,115,105,99,115,122,83,66,97,115,101,32,99, + 108,97,115,115,32,111,102,32,99,111,109,109,111,110,32,99, + 111,100,101,32,110,101,101,100,101,100,32,98,121,32,98,111, + 116,104,32,83,111,117,114,99,101,76,111,97,100,101,114,32, + 97,110,100,10,32,32,32,32,83,111,117,114,99,101,108,101, + 115,115,70,105,108,101,76,111,97,100,101,114,46,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0, 0,0,67,0,0,0,115,64,0,0,0,116,0,124,0,160, 1,124,1,161,1,131,1,100,1,25,0,125,2,124,2,160, 2,100,2,100,1,161,2,100,3,25,0,125,3,124,1,160, @@ -1088,57 +1098,58 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 41,5,114,119,0,0,0,114,139,0,0,0,114,97,0,0, 0,90,13,102,105,108,101,110,97,109,101,95,98,97,115,101, 90,9,116,97,105,108,95,110,97,109,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,182,0,0,0,248, + 114,3,0,0,0,114,6,0,0,0,114,182,0,0,0,249, 2,0,0,115,8,0,0,0,0,3,18,1,16,1,14,1, 122,24,95,76,111,97,100,101,114,66,97,115,105,99,115,46, 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,169,2,122,42,85,115,101,32, - 100,101,102,97,117,108,116,32,115,101,109,97,110,116,105,99, - 115,32,102,111,114,32,109,111,100,117,108,101,32,99,114,101, - 97,116,105,111,110,46,78,114,3,0,0,0,169,2,114,119, - 0,0,0,114,187,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,13,99,114,101,97,116,101,95, - 109,111,100,117,108,101,0,3,0,0,115,2,0,0,0,0, - 1,122,27,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,3,0,0,0,5,0,0,0,67, - 0,0,0,115,56,0,0,0,124,0,160,0,124,1,106,1, - 161,1,125,2,124,2,100,1,107,8,114,36,116,2,100,2, - 160,3,124,1,106,1,161,1,131,1,130,1,116,4,160,5, - 116,6,124,2,124,1,106,7,161,3,1,0,100,1,83,0, - 41,3,122,19,69,120,101,99,117,116,101,32,116,104,101,32, - 109,111,100,117,108,101,46,78,122,52,99,97,110,110,111,116, - 32,108,111,97,100,32,109,111,100,117,108,101,32,123,33,114, - 125,32,119,104,101,110,32,103,101,116,95,99,111,100,101,40, - 41,32,114,101,116,117,114,110,115,32,78,111,110,101,41,8, - 218,8,103,101,116,95,99,111,100,101,114,125,0,0,0,114, - 118,0,0,0,114,62,0,0,0,114,134,0,0,0,218,25, - 95,99,97,108,108,95,119,105,116,104,95,102,114,97,109,101, - 115,95,114,101,109,111,118,101,100,218,4,101,120,101,99,114, - 131,0,0,0,41,3,114,119,0,0,0,218,6,109,111,100, - 117,108,101,114,164,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,11,101,120,101,99,95,109,111, - 100,117,108,101,3,3,0,0,115,12,0,0,0,0,2,12, - 1,8,1,6,1,4,255,6,2,122,25,95,76,111,97,100, - 101,114,66,97,115,105,99,115,46,101,120,101,99,95,109,111, - 100,117,108,101,99,2,0,0,0,0,0,0,0,2,0,0, - 0,4,0,0,0,67,0,0,0,115,12,0,0,0,116,0, - 160,1,124,0,124,1,161,2,83,0,41,1,122,26,84,104, - 105,115,32,109,111,100,117,108,101,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,46,41,2,114,134,0,0,0,218, - 17,95,108,111,97,100,95,109,111,100,117,108,101,95,115,104, - 105,109,169,2,114,119,0,0,0,114,139,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,11,108, - 111,97,100,95,109,111,100,117,108,101,11,3,0,0,115,2, - 0,0,0,0,2,122,25,95,76,111,97,100,101,114,66,97, - 115,105,99,115,46,108,111,97,100,95,109,111,100,117,108,101, - 78,41,8,114,125,0,0,0,114,124,0,0,0,114,126,0, - 0,0,114,127,0,0,0,114,182,0,0,0,114,212,0,0, - 0,114,217,0,0,0,114,220,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 208,0,0,0,243,2,0,0,115,10,0,0,0,8,2,4, - 3,8,8,8,3,8,8,114,208,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,83,0,169,2,122,42, + 85,115,101,32,100,101,102,97,117,108,116,32,115,101,109,97, + 110,116,105,99,115,32,102,111,114,32,109,111,100,117,108,101, + 32,99,114,101,97,116,105,111,110,46,78,114,3,0,0,0, + 169,2,114,119,0,0,0,114,187,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,13,99,114,101, + 97,116,101,95,109,111,100,117,108,101,1,3,0,0,115,2, + 0,0,0,0,1,122,27,95,76,111,97,100,101,114,66,97, + 115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,5,0,0,0,67,0,0,0,115,56,0,0,0, + 124,0,160,0,124,1,106,1,161,1,125,2,124,2,100,1, + 107,8,114,36,116,2,100,2,160,3,124,1,106,1,161,1, + 131,1,130,1,116,4,160,5,116,6,124,2,124,1,106,7, + 161,3,1,0,100,1,83,0,41,3,122,19,69,120,101,99, + 117,116,101,32,116,104,101,32,109,111,100,117,108,101,46,78, + 122,52,99,97,110,110,111,116,32,108,111,97,100,32,109,111, + 100,117,108,101,32,123,33,114,125,32,119,104,101,110,32,103, + 101,116,95,99,111,100,101,40,41,32,114,101,116,117,114,110, + 115,32,78,111,110,101,41,8,218,8,103,101,116,95,99,111, + 100,101,114,125,0,0,0,114,118,0,0,0,114,62,0,0, + 0,114,134,0,0,0,218,25,95,99,97,108,108,95,119,105, + 116,104,95,102,114,97,109,101,115,95,114,101,109,111,118,101, + 100,218,4,101,120,101,99,114,131,0,0,0,41,3,114,119, + 0,0,0,218,6,109,111,100,117,108,101,114,164,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 11,101,120,101,99,95,109,111,100,117,108,101,4,3,0,0, + 115,12,0,0,0,0,2,12,1,8,1,6,1,4,255,6, + 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, + 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, + 0,67,0,0,0,115,12,0,0,0,116,0,160,1,124,0, + 124,1,161,2,83,0,41,1,122,26,84,104,105,115,32,109, + 111,100,117,108,101,32,105,115,32,100,101,112,114,101,99,97, + 116,101,100,46,41,2,114,134,0,0,0,218,17,95,108,111, + 97,100,95,109,111,100,117,108,101,95,115,104,105,109,169,2, + 114,119,0,0,0,114,139,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,11,108,111,97,100,95, + 109,111,100,117,108,101,12,3,0,0,115,2,0,0,0,0, + 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, + 46,108,111,97,100,95,109,111,100,117,108,101,78,41,8,114, + 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, + 0,0,0,114,182,0,0,0,114,212,0,0,0,114,217,0, + 0,0,114,220,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,208,0,0,0, + 244,2,0,0,115,10,0,0,0,8,2,4,3,8,8,8, + 3,8,8,114,208,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, 0,115,74,0,0,0,101,0,90,1,100,0,90,2,100,1, 100,2,132,0,90,3,100,3,100,4,132,0,90,4,100,5, @@ -1146,82 +1157,83 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 100,10,132,0,90,7,100,11,100,12,156,1,100,13,100,14, 132,2,90,8,100,15,100,16,132,0,90,9,100,17,83,0, 41,18,218,12,83,111,117,114,99,101,76,111,97,100,101,114, - 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,8,0,0,0,116,0,130,1,100,1, - 83,0,41,2,122,165,79,112,116,105,111,110,97,108,32,109, - 101,116,104,111,100,32,116,104,97,116,32,114,101,116,117,114, - 110,115,32,116,104,101,32,109,111,100,105,102,105,99,97,116, - 105,111,110,32,116,105,109,101,32,40,97,110,32,105,110,116, - 41,32,102,111,114,32,116,104,101,10,32,32,32,32,32,32, - 32,32,115,112,101,99,105,102,105,101,100,32,112,97,116,104, - 32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,32, - 32,32,32,82,97,105,115,101,115,32,79,83,69,114,114,111, - 114,32,119,104,101,110,32,116,104,101,32,112,97,116,104,32, - 99,97,110,110,111,116,32,98,101,32,104,97,110,100,108,101, - 100,46,10,32,32,32,32,32,32,32,32,78,41,1,114,50, - 0,0,0,169,2,114,119,0,0,0,114,44,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,10, - 112,97,116,104,95,109,116,105,109,101,18,3,0,0,115,2, - 0,0,0,0,6,122,23,83,111,117,114,99,101,76,111,97, - 100,101,114,46,112,97,116,104,95,109,116,105,109,101,99,2, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, - 0,0,0,115,14,0,0,0,100,1,124,0,160,0,124,1, - 161,1,105,1,83,0,41,2,97,158,1,0,0,79,112,116, - 105,111,110,97,108,32,109,101,116,104,111,100,32,114,101,116, - 117,114,110,105,110,103,32,97,32,109,101,116,97,100,97,116, - 97,32,100,105,99,116,32,102,111,114,32,116,104,101,32,115, - 112,101,99,105,102,105,101,100,10,32,32,32,32,32,32,32, - 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10, - 32,32,32,32,32,32,32,32,80,111,115,115,105,98,108,101, - 32,107,101,121,115,58,10,32,32,32,32,32,32,32,32,45, - 32,39,109,116,105,109,101,39,32,40,109,97,110,100,97,116, - 111,114,121,41,32,105,115,32,116,104,101,32,110,117,109,101, - 114,105,99,32,116,105,109,101,115,116,97,109,112,32,111,102, - 32,108,97,115,116,32,115,111,117,114,99,101,10,32,32,32, - 32,32,32,32,32,32,32,99,111,100,101,32,109,111,100,105, - 102,105,99,97,116,105,111,110,59,10,32,32,32,32,32,32, - 32,32,45,32,39,115,105,122,101,39,32,40,111,112,116,105, - 111,110,97,108,41,32,105,115,32,116,104,101,32,115,105,122, - 101,32,105,110,32,98,121,116,101,115,32,111,102,32,116,104, - 101,32,115,111,117,114,99,101,32,99,111,100,101,46,10,10, - 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110, - 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100, - 32,97,108,108,111,119,115,32,116,104,101,32,108,111,97,100, - 101,114,32,116,111,32,114,101,97,100,32,98,121,116,101,99, - 111,100,101,32,102,105,108,101,115,46,10,32,32,32,32,32, - 32,32,32,82,97,105,115,101,115,32,79,83,69,114,114,111, - 114,32,119,104,101,110,32,116,104,101,32,112,97,116,104,32, - 99,97,110,110,111,116,32,98,101,32,104,97,110,100,108,101, - 100,46,10,32,32,32,32,32,32,32,32,114,169,0,0,0, - 41,1,114,223,0,0,0,114,222,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,10,112,97,116, - 104,95,115,116,97,116,115,26,3,0,0,115,2,0,0,0, - 0,12,122,23,83,111,117,114,99,101,76,111,97,100,101,114, - 46,112,97,116,104,95,115,116,97,116,115,99,4,0,0,0, - 0,0,0,0,4,0,0,0,4,0,0,0,67,0,0,0, - 115,12,0,0,0,124,0,160,0,124,2,124,3,161,2,83, - 0,41,1,122,228,79,112,116,105,111,110,97,108,32,109,101, - 116,104,111,100,32,119,104,105,99,104,32,119,114,105,116,101, - 115,32,100,97,116,97,32,40,98,121,116,101,115,41,32,116, - 111,32,97,32,102,105,108,101,32,112,97,116,104,32,40,97, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,8,0,0,0,116,0, + 130,1,100,1,83,0,41,2,122,165,79,112,116,105,111,110, + 97,108,32,109,101,116,104,111,100,32,116,104,97,116,32,114, + 101,116,117,114,110,115,32,116,104,101,32,109,111,100,105,102, + 105,99,97,116,105,111,110,32,116,105,109,101,32,40,97,110, + 32,105,110,116,41,32,102,111,114,32,116,104,101,10,32,32, + 32,32,32,32,32,32,115,112,101,99,105,102,105,101,100,32, + 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, + 32,32,32,32,32,32,32,82,97,105,115,101,115,32,79,83, + 69,114,114,111,114,32,119,104,101,110,32,116,104,101,32,112, + 97,116,104,32,99,97,110,110,111,116,32,98,101,32,104,97, + 110,100,108,101,100,46,10,32,32,32,32,32,32,32,32,78, + 41,1,114,50,0,0,0,169,2,114,119,0,0,0,114,44, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,10,112,97,116,104,95,109,116,105,109,101,19,3, + 0,0,115,2,0,0,0,0,6,122,23,83,111,117,114,99, + 101,76,111,97,100,101,114,46,112,97,116,104,95,109,116,105, + 109,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,67,0,0,0,115,14,0,0,0, + 100,1,124,0,160,0,124,1,161,1,105,1,83,0,41,2, + 97,158,1,0,0,79,112,116,105,111,110,97,108,32,109,101, + 116,104,111,100,32,114,101,116,117,114,110,105,110,103,32,97, + 32,109,101,116,97,100,97,116,97,32,100,105,99,116,32,102, + 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, + 10,32,32,32,32,32,32,32,32,112,97,116,104,32,40,97, 32,115,116,114,41,46,10,10,32,32,32,32,32,32,32,32, + 80,111,115,115,105,98,108,101,32,107,101,121,115,58,10,32, + 32,32,32,32,32,32,32,45,32,39,109,116,105,109,101,39, + 32,40,109,97,110,100,97,116,111,114,121,41,32,105,115,32, + 116,104,101,32,110,117,109,101,114,105,99,32,116,105,109,101, + 115,116,97,109,112,32,111,102,32,108,97,115,116,32,115,111, + 117,114,99,101,10,32,32,32,32,32,32,32,32,32,32,99, + 111,100,101,32,109,111,100,105,102,105,99,97,116,105,111,110, + 59,10,32,32,32,32,32,32,32,32,45,32,39,115,105,122, + 101,39,32,40,111,112,116,105,111,110,97,108,41,32,105,115, + 32,116,104,101,32,115,105,122,101,32,105,110,32,98,121,116, + 101,115,32,111,102,32,116,104,101,32,115,111,117,114,99,101, + 32,99,111,100,101,46,10,10,32,32,32,32,32,32,32,32, 73,109,112,108,101,109,101,110,116,105,110,103,32,116,104,105, 115,32,109,101,116,104,111,100,32,97,108,108,111,119,115,32, - 102,111,114,32,116,104,101,32,119,114,105,116,105,110,103,32, - 111,102,32,98,121,116,101,99,111,100,101,32,102,105,108,101, - 115,46,10,10,32,32,32,32,32,32,32,32,84,104,101,32, - 115,111,117,114,99,101,32,112,97,116,104,32,105,115,32,110, - 101,101,100,101,100,32,105,110,32,111,114,100,101,114,32,116, - 111,32,99,111,114,114,101,99,116,108,121,32,116,114,97,110, - 115,102,101,114,32,112,101,114,109,105,115,115,105,111,110,115, - 10,32,32,32,32,32,32,32,32,41,1,218,8,115,101,116, - 95,100,97,116,97,41,4,114,119,0,0,0,114,108,0,0, - 0,90,10,99,97,99,104,101,95,112,97,116,104,114,26,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,15,95,99,97,99,104,101,95,98,121,116,101,99,111, - 100,101,40,3,0,0,115,2,0,0,0,0,8,122,28,83, - 111,117,114,99,101,76,111,97,100,101,114,46,95,99,97,99, - 104,101,95,98,121,116,101,99,111,100,101,99,3,0,0,0, + 116,104,101,32,108,111,97,100,101,114,32,116,111,32,114,101, + 97,100,32,98,121,116,101,99,111,100,101,32,102,105,108,101, + 115,46,10,32,32,32,32,32,32,32,32,82,97,105,115,101, + 115,32,79,83,69,114,114,111,114,32,119,104,101,110,32,116, + 104,101,32,112,97,116,104,32,99,97,110,110,111,116,32,98, + 101,32,104,97,110,100,108,101,100,46,10,32,32,32,32,32, + 32,32,32,114,169,0,0,0,41,1,114,223,0,0,0,114, + 222,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,10,112,97,116,104,95,115,116,97,116,115,27, + 3,0,0,115,2,0,0,0,0,12,122,23,83,111,117,114, + 99,101,76,111,97,100,101,114,46,112,97,116,104,95,115,116, + 97,116,115,99,4,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,4,0,0,0,67,0,0,0,115,12,0,0, + 0,124,0,160,0,124,2,124,3,161,2,83,0,41,1,122, + 228,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, + 32,119,104,105,99,104,32,119,114,105,116,101,115,32,100,97, + 116,97,32,40,98,121,116,101,115,41,32,116,111,32,97,32, + 102,105,108,101,32,112,97,116,104,32,40,97,32,115,116,114, + 41,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108, + 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101, + 116,104,111,100,32,97,108,108,111,119,115,32,102,111,114,32, + 116,104,101,32,119,114,105,116,105,110,103,32,111,102,32,98, + 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,10, + 32,32,32,32,32,32,32,32,84,104,101,32,115,111,117,114, + 99,101,32,112,97,116,104,32,105,115,32,110,101,101,100,101, + 100,32,105,110,32,111,114,100,101,114,32,116,111,32,99,111, + 114,114,101,99,116,108,121,32,116,114,97,110,115,102,101,114, + 32,112,101,114,109,105,115,115,105,111,110,115,10,32,32,32, + 32,32,32,32,32,41,1,218,8,115,101,116,95,100,97,116, + 97,41,4,114,119,0,0,0,114,108,0,0,0,90,10,99, + 97,99,104,101,95,112,97,116,104,114,26,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, + 99,97,99,104,101,95,98,121,116,101,99,111,100,101,41,3, + 0,0,115,2,0,0,0,0,8,122,28,83,111,117,114,99, + 101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,98, + 121,116,101,99,111,100,101,99,3,0,0,0,0,0,0,0, 0,0,0,0,3,0,0,0,1,0,0,0,67,0,0,0, 115,4,0,0,0,100,1,83,0,41,2,122,150,79,112,116, 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105, @@ -1235,146 +1247,147 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 111,100,101,32,102,105,108,101,115,46,10,32,32,32,32,32, 32,32,32,78,114,3,0,0,0,41,3,114,119,0,0,0, 114,44,0,0,0,114,26,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,225,0,0,0,50,3, + 3,0,0,0,114,6,0,0,0,114,225,0,0,0,51,3, 0,0,115,2,0,0,0,0,1,122,21,83,111,117,114,99, 101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,97, - 99,2,0,0,0,0,0,0,0,5,0,0,0,10,0,0, - 0,67,0,0,0,115,82,0,0,0,124,0,160,0,124,1, - 161,1,125,2,122,14,124,0,160,1,124,2,161,1,125,3, - 87,0,110,48,4,0,116,2,107,10,114,72,1,0,125,4, - 1,0,122,18,116,3,100,1,124,1,100,2,141,2,124,4, - 130,2,87,0,53,0,100,3,125,4,126,4,88,0,89,0, - 110,2,88,0,116,4,124,3,131,1,83,0,41,4,122,52, - 67,111,110,99,114,101,116,101,32,105,109,112,108,101,109,101, - 110,116,97,116,105,111,110,32,111,102,32,73,110,115,112,101, - 99,116,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,46,122,39,115,111,117,114,99,101,32,110,111,116, - 32,97,118,97,105,108,97,98,108,101,32,116,104,114,111,117, - 103,104,32,103,101,116,95,100,97,116,97,40,41,114,116,0, - 0,0,78,41,5,114,179,0,0,0,218,8,103,101,116,95, - 100,97,116,97,114,50,0,0,0,114,118,0,0,0,114,176, - 0,0,0,41,5,114,119,0,0,0,114,139,0,0,0,114, - 44,0,0,0,114,174,0,0,0,218,3,101,120,99,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,10,103, - 101,116,95,115,111,117,114,99,101,57,3,0,0,115,20,0, - 0,0,0,2,10,1,2,1,14,1,16,1,4,1,2,255, - 4,1,2,255,20,2,122,23,83,111,117,114,99,101,76,111, - 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,114, - 105,0,0,0,41,1,218,9,95,111,112,116,105,109,105,122, - 101,99,3,0,0,0,1,0,0,0,4,0,0,0,8,0, - 0,0,67,0,0,0,115,22,0,0,0,116,0,106,1,116, - 2,124,1,124,2,100,1,100,2,124,3,100,3,141,6,83, - 0,41,4,122,130,82,101,116,117,114,110,32,116,104,101,32, - 99,111,100,101,32,111,98,106,101,99,116,32,99,111,109,112, - 105,108,101,100,32,102,114,111,109,32,115,111,117,114,99,101, - 46,10,10,32,32,32,32,32,32,32,32,84,104,101,32,39, - 100,97,116,97,39,32,97,114,103,117,109,101,110,116,32,99, - 97,110,32,98,101,32,97,110,121,32,111,98,106,101,99,116, - 32,116,121,112,101,32,116,104,97,116,32,99,111,109,112,105, - 108,101,40,41,32,115,117,112,112,111,114,116,115,46,10,32, - 32,32,32,32,32,32,32,114,215,0,0,0,84,41,2,218, - 12,100,111,110,116,95,105,110,104,101,114,105,116,114,84,0, - 0,0,41,3,114,134,0,0,0,114,214,0,0,0,218,7, - 99,111,109,112,105,108,101,41,4,114,119,0,0,0,114,26, - 0,0,0,114,44,0,0,0,114,230,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,14,115,111, - 117,114,99,101,95,116,111,95,99,111,100,101,67,3,0,0, - 115,8,0,0,0,0,5,12,1,2,0,2,255,122,27,83, - 111,117,114,99,101,76,111,97,100,101,114,46,115,111,117,114, - 99,101,95,116,111,95,99,111,100,101,99,2,0,0,0,0, - 0,0,0,15,0,0,0,9,0,0,0,67,0,0,0,115, - 34,2,0,0,124,0,160,0,124,1,161,1,125,2,100,1, - 125,3,100,1,125,4,100,1,125,5,100,2,125,6,100,3, - 125,7,122,12,116,1,124,2,131,1,125,8,87,0,110,26, - 4,0,116,2,107,10,114,68,1,0,1,0,1,0,100,1, - 125,8,89,0,144,1,110,48,88,0,122,14,124,0,160,3, - 124,2,161,1,125,9,87,0,110,22,4,0,116,4,107,10, - 114,106,1,0,1,0,1,0,89,0,144,1,110,10,88,0, - 116,5,124,9,100,4,25,0,131,1,125,3,122,14,124,0, - 160,6,124,8,161,1,125,10,87,0,110,20,4,0,116,4, - 107,10,114,154,1,0,1,0,1,0,89,0,110,218,88,0, - 124,1,124,8,100,5,156,2,125,11,122,148,116,7,124,10, - 124,1,124,11,131,3,125,12,116,8,124,10,131,1,100,6, - 100,1,133,2,25,0,125,13,124,12,100,7,64,0,100,8, - 107,3,125,6,124,6,144,1,114,36,124,12,100,9,64,0, - 100,8,107,3,125,7,116,9,106,10,100,10,107,3,144,1, - 114,34,124,7,115,254,116,9,106,10,100,11,107,2,144,1, - 114,34,124,0,160,6,124,2,161,1,125,4,116,9,160,11, - 116,12,124,4,161,2,125,5,116,13,124,10,124,5,124,1, - 124,11,131,4,1,0,110,20,116,14,124,10,124,3,124,9, - 100,12,25,0,124,1,124,11,131,5,1,0,87,0,110,26, - 4,0,116,15,116,16,102,2,107,10,144,1,114,84,1,0, - 1,0,1,0,89,0,110,32,88,0,116,17,160,18,100,13, - 124,8,124,2,161,3,1,0,116,19,124,13,124,1,124,8, - 124,2,100,14,141,4,83,0,124,4,100,1,107,8,144,1, - 114,136,124,0,160,6,124,2,161,1,125,4,124,0,160,20, - 124,4,124,2,161,2,125,14,116,17,160,18,100,15,124,2, - 161,2,1,0,116,21,106,22,144,2,115,30,124,8,100,1, - 107,9,144,2,114,30,124,3,100,1,107,9,144,2,114,30, - 124,6,144,1,114,228,124,5,100,1,107,8,144,1,114,214, - 116,9,160,11,124,4,161,1,125,5,116,23,124,14,124,5, - 124,7,131,3,125,10,110,16,116,24,124,14,124,3,116,25, - 124,4,131,1,131,3,125,10,122,18,124,0,160,26,124,2, - 124,8,124,10,161,3,1,0,87,0,110,22,4,0,116,2, - 107,10,144,2,114,28,1,0,1,0,1,0,89,0,110,2, - 88,0,124,14,83,0,41,16,122,190,67,111,110,99,114,101, - 116,101,32,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,32,111,102,32,73,110,115,112,101,99,116,76,111,97,100, - 101,114,46,103,101,116,95,99,111,100,101,46,10,10,32,32, - 32,32,32,32,32,32,82,101,97,100,105,110,103,32,111,102, - 32,98,121,116,101,99,111,100,101,32,114,101,113,117,105,114, - 101,115,32,112,97,116,104,95,115,116,97,116,115,32,116,111, - 32,98,101,32,105,109,112,108,101,109,101,110,116,101,100,46, - 32,84,111,32,119,114,105,116,101,10,32,32,32,32,32,32, - 32,32,98,121,116,101,99,111,100,101,44,32,115,101,116,95, - 100,97,116,97,32,109,117,115,116,32,97,108,115,111,32,98, - 101,32,105,109,112,108,101,109,101,110,116,101,100,46,10,10, - 32,32,32,32,32,32,32,32,78,70,84,114,169,0,0,0, - 114,159,0,0,0,114,145,0,0,0,114,39,0,0,0,114, - 73,0,0,0,114,28,0,0,0,90,5,110,101,118,101,114, - 90,6,97,108,119,97,121,115,218,4,115,105,122,101,122,13, - 123,125,32,109,97,116,99,104,101,115,32,123,125,41,3,114, - 117,0,0,0,114,107,0,0,0,114,108,0,0,0,122,19, - 99,111,100,101,32,111,98,106,101,99,116,32,102,114,111,109, - 32,123,125,41,27,114,179,0,0,0,114,98,0,0,0,114, - 82,0,0,0,114,224,0,0,0,114,50,0,0,0,114,17, - 0,0,0,114,227,0,0,0,114,152,0,0,0,218,10,109, - 101,109,111,114,121,118,105,101,119,114,163,0,0,0,90,21, - 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, - 95,112,121,99,115,114,157,0,0,0,218,17,95,82,65,87, - 95,77,65,71,73,67,95,78,85,77,66,69,82,114,158,0, - 0,0,114,156,0,0,0,114,118,0,0,0,114,150,0,0, - 0,114,134,0,0,0,114,149,0,0,0,114,165,0,0,0, - 114,233,0,0,0,114,8,0,0,0,218,19,100,111,110,116, - 95,119,114,105,116,101,95,98,121,116,101,99,111,100,101,114, - 171,0,0,0,114,170,0,0,0,114,22,0,0,0,114,226, - 0,0,0,41,15,114,119,0,0,0,114,139,0,0,0,114, - 108,0,0,0,114,154,0,0,0,114,174,0,0,0,114,157, - 0,0,0,90,10,104,97,115,104,95,98,97,115,101,100,90, - 12,99,104,101,99,107,95,115,111,117,114,99,101,114,107,0, - 0,0,218,2,115,116,114,26,0,0,0,114,151,0,0,0, - 114,83,0,0,0,90,10,98,121,116,101,115,95,100,97,116, - 97,90,11,99,111,100,101,95,111,98,106,101,99,116,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,213,0, - 0,0,75,3,0,0,115,152,0,0,0,0,7,10,1,4, - 1,4,1,4,1,4,1,4,1,2,1,12,1,14,1,12, - 2,2,1,14,1,14,1,8,2,12,1,2,1,14,1,14, - 1,6,3,2,1,2,254,6,4,2,1,12,1,16,1,12, - 1,6,1,12,1,12,1,2,255,2,2,8,254,4,3,10, - 1,4,1,2,1,2,254,4,4,8,1,2,255,6,3,2, - 1,2,1,2,1,6,1,2,1,2,251,8,7,20,1,6, - 2,8,1,2,255,4,2,6,1,2,1,2,254,6,3,10, - 1,10,1,12,1,12,1,18,1,6,255,4,2,6,1,10, - 1,10,1,14,2,6,1,6,255,4,2,2,1,18,1,16, - 1,6,1,122,21,83,111,117,114,99,101,76,111,97,100,101, - 114,46,103,101,116,95,99,111,100,101,78,41,10,114,125,0, - 0,0,114,124,0,0,0,114,126,0,0,0,114,223,0,0, - 0,114,224,0,0,0,114,226,0,0,0,114,225,0,0,0, - 114,229,0,0,0,114,233,0,0,0,114,213,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,221,0,0,0,16,3,0,0,115,14,0,0, - 0,8,2,8,8,8,14,8,10,8,7,8,10,14,8,114, - 221,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,10,0,0,0,67,0,0,0,115,82,0,0,0,124,0, + 160,0,124,1,161,1,125,2,122,14,124,0,160,1,124,2, + 161,1,125,3,87,0,110,48,4,0,116,2,107,10,114,72, + 1,0,125,4,1,0,122,18,116,3,100,1,124,1,100,2, + 141,2,124,4,130,2,87,0,53,0,100,3,125,4,126,4, + 88,0,89,0,110,2,88,0,116,4,124,3,131,1,83,0, + 41,4,122,52,67,111,110,99,114,101,116,101,32,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,73, + 110,115,112,101,99,116,76,111,97,100,101,114,46,103,101,116, + 95,115,111,117,114,99,101,46,122,39,115,111,117,114,99,101, + 32,110,111,116,32,97,118,97,105,108,97,98,108,101,32,116, + 104,114,111,117,103,104,32,103,101,116,95,100,97,116,97,40, + 41,114,116,0,0,0,78,41,5,114,179,0,0,0,218,8, + 103,101,116,95,100,97,116,97,114,50,0,0,0,114,118,0, + 0,0,114,176,0,0,0,41,5,114,119,0,0,0,114,139, + 0,0,0,114,44,0,0,0,114,174,0,0,0,218,3,101, + 120,99,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,10,103,101,116,95,115,111,117,114,99,101,58,3,0, + 0,115,20,0,0,0,0,2,10,1,2,1,14,1,16,1, + 4,1,2,255,4,1,2,255,20,2,122,23,83,111,117,114, + 99,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, + 114,99,101,114,105,0,0,0,41,1,218,9,95,111,112,116, + 105,109,105,122,101,99,3,0,0,0,0,0,0,0,1,0, + 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,22, + 0,0,0,116,0,106,1,116,2,124,1,124,2,100,1,100, + 2,124,3,100,3,141,6,83,0,41,4,122,130,82,101,116, + 117,114,110,32,116,104,101,32,99,111,100,101,32,111,98,106, + 101,99,116,32,99,111,109,112,105,108,101,100,32,102,114,111, + 109,32,115,111,117,114,99,101,46,10,10,32,32,32,32,32, + 32,32,32,84,104,101,32,39,100,97,116,97,39,32,97,114, + 103,117,109,101,110,116,32,99,97,110,32,98,101,32,97,110, + 121,32,111,98,106,101,99,116,32,116,121,112,101,32,116,104, + 97,116,32,99,111,109,112,105,108,101,40,41,32,115,117,112, + 112,111,114,116,115,46,10,32,32,32,32,32,32,32,32,114, + 215,0,0,0,84,41,2,218,12,100,111,110,116,95,105,110, + 104,101,114,105,116,114,84,0,0,0,41,3,114,134,0,0, + 0,114,214,0,0,0,218,7,99,111,109,112,105,108,101,41, + 4,114,119,0,0,0,114,26,0,0,0,114,44,0,0,0, + 114,230,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,14,115,111,117,114,99,101,95,116,111,95, + 99,111,100,101,68,3,0,0,115,8,0,0,0,0,5,12, + 1,2,0,2,255,122,27,83,111,117,114,99,101,76,111,97, + 100,101,114,46,115,111,117,114,99,101,95,116,111,95,99,111, + 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,15, + 0,0,0,9,0,0,0,67,0,0,0,115,34,2,0,0, + 124,0,160,0,124,1,161,1,125,2,100,1,125,3,100,1, + 125,4,100,1,125,5,100,2,125,6,100,3,125,7,122,12, + 116,1,124,2,131,1,125,8,87,0,110,26,4,0,116,2, + 107,10,114,68,1,0,1,0,1,0,100,1,125,8,89,0, + 144,1,110,48,88,0,122,14,124,0,160,3,124,2,161,1, + 125,9,87,0,110,22,4,0,116,4,107,10,114,106,1,0, + 1,0,1,0,89,0,144,1,110,10,88,0,116,5,124,9, + 100,4,25,0,131,1,125,3,122,14,124,0,160,6,124,8, + 161,1,125,10,87,0,110,20,4,0,116,4,107,10,114,154, + 1,0,1,0,1,0,89,0,110,218,88,0,124,1,124,8, + 100,5,156,2,125,11,122,148,116,7,124,10,124,1,124,11, + 131,3,125,12,116,8,124,10,131,1,100,6,100,1,133,2, + 25,0,125,13,124,12,100,7,64,0,100,8,107,3,125,6, + 124,6,144,1,114,36,124,12,100,9,64,0,100,8,107,3, + 125,7,116,9,106,10,100,10,107,3,144,1,114,34,124,7, + 115,254,116,9,106,10,100,11,107,2,144,1,114,34,124,0, + 160,6,124,2,161,1,125,4,116,9,160,11,116,12,124,4, + 161,2,125,5,116,13,124,10,124,5,124,1,124,11,131,4, + 1,0,110,20,116,14,124,10,124,3,124,9,100,12,25,0, + 124,1,124,11,131,5,1,0,87,0,110,26,4,0,116,15, + 116,16,102,2,107,10,144,1,114,84,1,0,1,0,1,0, + 89,0,110,32,88,0,116,17,160,18,100,13,124,8,124,2, + 161,3,1,0,116,19,124,13,124,1,124,8,124,2,100,14, + 141,4,83,0,124,4,100,1,107,8,144,1,114,136,124,0, + 160,6,124,2,161,1,125,4,124,0,160,20,124,4,124,2, + 161,2,125,14,116,17,160,18,100,15,124,2,161,2,1,0, + 116,21,106,22,144,2,115,30,124,8,100,1,107,9,144,2, + 114,30,124,3,100,1,107,9,144,2,114,30,124,6,144,1, + 114,228,124,5,100,1,107,8,144,1,114,214,116,9,160,11, + 124,4,161,1,125,5,116,23,124,14,124,5,124,7,131,3, + 125,10,110,16,116,24,124,14,124,3,116,25,124,4,131,1, + 131,3,125,10,122,18,124,0,160,26,124,2,124,8,124,10, + 161,3,1,0,87,0,110,22,4,0,116,2,107,10,144,2, + 114,28,1,0,1,0,1,0,89,0,110,2,88,0,124,14, + 83,0,41,16,122,190,67,111,110,99,114,101,116,101,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, + 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,103, + 101,116,95,99,111,100,101,46,10,10,32,32,32,32,32,32, + 32,32,82,101,97,100,105,110,103,32,111,102,32,98,121,116, + 101,99,111,100,101,32,114,101,113,117,105,114,101,115,32,112, + 97,116,104,95,115,116,97,116,115,32,116,111,32,98,101,32, + 105,109,112,108,101,109,101,110,116,101,100,46,32,84,111,32, + 119,114,105,116,101,10,32,32,32,32,32,32,32,32,98,121, + 116,101,99,111,100,101,44,32,115,101,116,95,100,97,116,97, + 32,109,117,115,116,32,97,108,115,111,32,98,101,32,105,109, + 112,108,101,109,101,110,116,101,100,46,10,10,32,32,32,32, + 32,32,32,32,78,70,84,114,169,0,0,0,114,159,0,0, + 0,114,145,0,0,0,114,39,0,0,0,114,73,0,0,0, + 114,28,0,0,0,90,5,110,101,118,101,114,90,6,97,108, + 119,97,121,115,218,4,115,105,122,101,122,13,123,125,32,109, + 97,116,99,104,101,115,32,123,125,41,3,114,117,0,0,0, + 114,107,0,0,0,114,108,0,0,0,122,19,99,111,100,101, + 32,111,98,106,101,99,116,32,102,114,111,109,32,123,125,41, + 27,114,179,0,0,0,114,98,0,0,0,114,82,0,0,0, + 114,224,0,0,0,114,50,0,0,0,114,17,0,0,0,114, + 227,0,0,0,114,152,0,0,0,218,10,109,101,109,111,114, + 121,118,105,101,119,114,163,0,0,0,90,21,99,104,101,99, + 107,95,104,97,115,104,95,98,97,115,101,100,95,112,121,99, + 115,114,157,0,0,0,218,17,95,82,65,87,95,77,65,71, + 73,67,95,78,85,77,66,69,82,114,158,0,0,0,114,156, + 0,0,0,114,118,0,0,0,114,150,0,0,0,114,134,0, + 0,0,114,149,0,0,0,114,165,0,0,0,114,233,0,0, + 0,114,8,0,0,0,218,19,100,111,110,116,95,119,114,105, + 116,101,95,98,121,116,101,99,111,100,101,114,171,0,0,0, + 114,170,0,0,0,114,22,0,0,0,114,226,0,0,0,41, + 15,114,119,0,0,0,114,139,0,0,0,114,108,0,0,0, + 114,154,0,0,0,114,174,0,0,0,114,157,0,0,0,90, + 10,104,97,115,104,95,98,97,115,101,100,90,12,99,104,101, + 99,107,95,115,111,117,114,99,101,114,107,0,0,0,218,2, + 115,116,114,26,0,0,0,114,151,0,0,0,114,83,0,0, + 0,90,10,98,121,116,101,115,95,100,97,116,97,90,11,99, + 111,100,101,95,111,98,106,101,99,116,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,213,0,0,0,76,3, + 0,0,115,152,0,0,0,0,7,10,1,4,1,4,1,4, + 1,4,1,4,1,2,1,12,1,14,1,12,2,2,1,14, + 1,14,1,8,2,12,1,2,1,14,1,14,1,6,3,2, + 1,2,254,6,4,2,1,12,1,16,1,12,1,6,1,12, + 1,12,1,2,255,2,2,8,254,4,3,10,1,4,1,2, + 1,2,254,4,4,8,1,2,255,6,3,2,1,2,1,2, + 1,6,1,2,1,2,251,8,7,20,1,6,2,8,1,2, + 255,4,2,6,1,2,1,2,254,6,3,10,1,10,1,12, + 1,12,1,18,1,6,255,4,2,6,1,10,1,10,1,14, + 2,6,1,6,255,4,2,2,1,18,1,16,1,6,1,122, + 21,83,111,117,114,99,101,76,111,97,100,101,114,46,103,101, + 116,95,99,111,100,101,78,41,10,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,223,0,0,0,114,224,0, + 0,0,114,226,0,0,0,114,225,0,0,0,114,229,0,0, + 0,114,233,0,0,0,114,213,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 221,0,0,0,17,3,0,0,115,14,0,0,0,8,2,8, + 8,8,14,8,10,8,7,8,10,14,8,114,221,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,4,0,0,0,0,0,0,0,115,124,0,0,0,101,0, 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, @@ -1391,36 +1404,37 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 116,111,99,111,108,32,109,101,116,104,111,100,115,32,116,104, 97,116,10,32,32,32,32,114,101,113,117,105,114,101,32,102, 105,108,101,32,115,121,115,116,101,109,32,117,115,97,103,101, - 46,99,3,0,0,0,0,0,0,0,3,0,0,0,2,0, - 0,0,67,0,0,0,115,16,0,0,0,124,1,124,0,95, - 0,124,2,124,0,95,1,100,1,83,0,41,2,122,75,67, - 97,99,104,101,32,116,104,101,32,109,111,100,117,108,101,32, - 110,97,109,101,32,97,110,100,32,116,104,101,32,112,97,116, - 104,32,116,111,32,116,104,101,32,102,105,108,101,32,102,111, - 117,110,100,32,98,121,32,116,104,101,10,32,32,32,32,32, - 32,32,32,102,105,110,100,101,114,46,78,114,159,0,0,0, - 41,3,114,119,0,0,0,114,139,0,0,0,114,44,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,209,0,0,0,165,3,0,0,115,4,0,0,0,0,3, - 6,1,122,19,70,105,108,101,76,111,97,100,101,114,46,95, - 95,105,110,105,116,95,95,99,2,0,0,0,0,0,0,0, - 2,0,0,0,2,0,0,0,67,0,0,0,115,24,0,0, - 0,124,0,106,0,124,1,106,0,107,2,111,22,124,0,106, - 1,124,1,106,1,107,2,83,0,114,110,0,0,0,169,2, - 218,9,95,95,99,108,97,115,115,95,95,114,131,0,0,0, - 169,2,114,119,0,0,0,90,5,111,116,104,101,114,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,6,95, - 95,101,113,95,95,171,3,0,0,115,6,0,0,0,0,1, - 12,1,10,255,122,17,70,105,108,101,76,111,97,100,101,114, - 46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,20,0,0, - 0,116,0,124,0,106,1,131,1,116,0,124,0,106,2,131, - 1,65,0,83,0,114,110,0,0,0,169,3,218,4,104,97, - 115,104,114,117,0,0,0,114,44,0,0,0,169,1,114,119, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,8,95,95,104,97,115,104,95,95,175,3,0,0, - 115,2,0,0,0,0,1,122,19,70,105,108,101,76,111,97, - 100,101,114,46,95,95,104,97,115,104,95,95,99,2,0,0, + 46,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124, + 1,124,0,95,0,124,2,124,0,95,1,100,1,83,0,41, + 2,122,75,67,97,99,104,101,32,116,104,101,32,109,111,100, + 117,108,101,32,110,97,109,101,32,97,110,100,32,116,104,101, + 32,112,97,116,104,32,116,111,32,116,104,101,32,102,105,108, + 101,32,102,111,117,110,100,32,98,121,32,116,104,101,10,32, + 32,32,32,32,32,32,32,102,105,110,100,101,114,46,78,114, + 159,0,0,0,41,3,114,119,0,0,0,114,139,0,0,0, + 114,44,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,209,0,0,0,166,3,0,0,115,4,0, + 0,0,0,3,6,1,122,19,70,105,108,101,76,111,97,100, + 101,114,46,95,95,105,110,105,116,95,95,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, + 67,0,0,0,115,24,0,0,0,124,0,106,0,124,1,106, + 0,107,2,111,22,124,0,106,1,124,1,106,1,107,2,83, + 0,114,110,0,0,0,169,2,218,9,95,95,99,108,97,115, + 115,95,95,114,131,0,0,0,169,2,114,119,0,0,0,90, + 5,111,116,104,101,114,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,6,95,95,101,113,95,95,172,3,0, + 0,115,6,0,0,0,0,1,12,1,10,255,122,17,70,105, + 108,101,76,111,97,100,101,114,46,95,95,101,113,95,95,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,20,0,0,0,116,0,124, + 0,106,1,131,1,116,0,124,0,106,2,131,1,65,0,83, + 0,114,110,0,0,0,169,3,218,4,104,97,115,104,114,117, + 0,0,0,114,44,0,0,0,169,1,114,119,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,8, + 95,95,104,97,115,104,95,95,176,3,0,0,115,2,0,0, + 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, + 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, 0,0,0,0,0,2,0,0,0,3,0,0,0,3,0,0, 0,115,16,0,0,0,116,0,116,1,124,0,131,2,160,2, 124,1,161,1,83,0,41,1,122,100,76,111,97,100,32,97, @@ -1432,42 +1446,43 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,97,100,46,10,10,32,32,32,32,32,32,32,32,41,3, 218,5,115,117,112,101,114,114,239,0,0,0,114,220,0,0, 0,114,219,0,0,0,169,1,114,241,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,220,0,0,0,178,3,0,0, + 0,0,114,6,0,0,0,114,220,0,0,0,179,3,0,0, 115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,97, 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, - 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,6,0,0,0,124,0,106,0,83,0,169, - 1,122,58,82,101,116,117,114,110,32,116,104,101,32,112,97, - 116,104,32,116,111,32,116,104,101,32,115,111,117,114,99,101, - 32,102,105,108,101,32,97,115,32,102,111,117,110,100,32,98, - 121,32,116,104,101,32,102,105,110,100,101,114,46,114,48,0, - 0,0,114,219,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,179,0,0,0,190,3,0,0,115, - 2,0,0,0,0,3,122,23,70,105,108,101,76,111,97,100, - 101,114,46,103,101,116,95,102,105,108,101,110,97,109,101,99, - 2,0,0,0,0,0,0,0,3,0,0,0,10,0,0,0, - 67,0,0,0,115,44,0,0,0,116,0,160,1,124,1,100, - 1,161,2,143,22,125,2,124,2,160,2,161,0,87,0,2, - 0,53,0,81,0,82,0,163,0,83,0,81,0,82,0,88, - 0,100,2,83,0,41,3,122,39,82,101,116,117,114,110,32, - 116,104,101,32,100,97,116,97,32,102,114,111,109,32,112,97, - 116,104,32,97,115,32,114,97,119,32,98,121,116,101,115,46, - 218,1,114,78,41,3,114,64,0,0,0,114,65,0,0,0, - 90,4,114,101,97,100,41,3,114,119,0,0,0,114,44,0, - 0,0,114,68,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,227,0,0,0,195,3,0,0,115, - 4,0,0,0,0,2,14,1,122,19,70,105,108,101,76,111, - 97,100,101,114,46,103,101,116,95,100,97,116,97,99,2,0, - 0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0, - 0,0,115,18,0,0,0,124,0,160,0,124,1,161,1,114, - 14,124,0,83,0,100,0,83,0,114,110,0,0,0,41,1, - 114,182,0,0,0,169,2,114,119,0,0,0,114,216,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,19,103,101,116,95,114,101,115,111,117,114,99,101,95,114, - 101,97,100,101,114,202,3,0,0,115,6,0,0,0,0,2, - 10,1,4,1,122,30,70,105,108,101,76,111,97,100,101,114, - 46,103,101,116,95,114,101,115,111,117,114,99,101,95,114,101, - 97,100,101,114,99,2,0,0,0,0,0,0,0,3,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,6,0,0,0,124,0,106, + 0,83,0,169,1,122,58,82,101,116,117,114,110,32,116,104, + 101,32,112,97,116,104,32,116,111,32,116,104,101,32,115,111, + 117,114,99,101,32,102,105,108,101,32,97,115,32,102,111,117, + 110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,114, + 46,114,48,0,0,0,114,219,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,179,0,0,0,191, + 3,0,0,115,2,0,0,0,0,3,122,23,70,105,108,101, + 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, + 97,109,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,10,0,0,0,67,0,0,0,115,44,0,0, + 0,116,0,160,1,124,1,100,1,161,2,143,22,125,2,124, + 2,160,2,161,0,87,0,2,0,53,0,81,0,82,0,163, + 0,83,0,81,0,82,0,88,0,100,2,83,0,41,3,122, + 39,82,101,116,117,114,110,32,116,104,101,32,100,97,116,97, + 32,102,114,111,109,32,112,97,116,104,32,97,115,32,114,97, + 119,32,98,121,116,101,115,46,218,1,114,78,41,3,114,64, + 0,0,0,114,65,0,0,0,90,4,114,101,97,100,41,3, + 114,119,0,0,0,114,44,0,0,0,114,68,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,227, + 0,0,0,196,3,0,0,115,4,0,0,0,0,2,14,1, + 122,19,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,100,97,116,97,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,18, + 0,0,0,124,0,160,0,124,1,161,1,114,14,124,0,83, + 0,100,0,83,0,114,110,0,0,0,41,1,114,182,0,0, + 0,169,2,114,119,0,0,0,114,216,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,19,103,101, + 116,95,114,101,115,111,117,114,99,101,95,114,101,97,100,101, + 114,203,3,0,0,115,6,0,0,0,0,2,10,1,4,1, + 122,30,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,114,101,115,111,117,114,99,101,95,114,101,97,100,101,114, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, 0,4,0,0,0,67,0,0,0,115,32,0,0,0,116,0, 116,1,124,0,106,2,131,1,100,1,25,0,124,1,131,2, 125,2,116,3,160,4,124,2,100,2,161,2,83,0,41,3, @@ -1476,53 +1491,54 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,65,0,0,0,169,3,114,119,0,0,0,90,8,114, 101,115,111,117,114,99,101,114,44,0,0,0,114,3,0,0, 0,114,3,0,0,0,114,6,0,0,0,218,13,111,112,101, - 110,95,114,101,115,111,117,114,99,101,208,3,0,0,115,4, + 110,95,114,101,115,111,117,114,99,101,209,3,0,0,115,4, 0,0,0,0,1,20,1,122,24,70,105,108,101,76,111,97, 100,101,114,46,111,112,101,110,95,114,101,115,111,117,114,99, - 101,99,2,0,0,0,0,0,0,0,3,0,0,0,3,0, - 0,0,67,0,0,0,115,38,0,0,0,124,0,160,0,124, - 1,161,1,115,14,116,1,130,1,116,2,116,3,124,0,106, - 4,131,1,100,1,25,0,124,1,131,2,125,2,124,2,83, - 0,169,2,78,114,73,0,0,0,41,5,218,11,105,115,95, - 114,101,115,111,117,114,99,101,218,17,70,105,108,101,78,111, - 116,70,111,117,110,100,69,114,114,111,114,114,38,0,0,0, - 114,47,0,0,0,114,44,0,0,0,114,254,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,13, - 114,101,115,111,117,114,99,101,95,112,97,116,104,212,3,0, - 0,115,8,0,0,0,0,1,10,1,4,1,20,1,122,24, - 70,105,108,101,76,111,97,100,101,114,46,114,101,115,111,117, - 114,99,101,95,112,97,116,104,99,2,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,67,0,0,0,115,40,0, - 0,0,116,0,124,1,107,6,114,12,100,1,83,0,116,1, - 116,2,124,0,106,3,131,1,100,2,25,0,124,1,131,2, - 125,2,116,4,124,2,131,1,83,0,41,3,78,70,114,73, - 0,0,0,41,5,114,35,0,0,0,114,38,0,0,0,114, - 47,0,0,0,114,44,0,0,0,114,54,0,0,0,169,3, - 114,119,0,0,0,114,117,0,0,0,114,44,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,1, - 1,0,0,218,3,0,0,115,8,0,0,0,0,1,8,1, - 4,1,20,1,122,22,70,105,108,101,76,111,97,100,101,114, - 46,105,115,95,114,101,115,111,117,114,99,101,99,1,0,0, - 0,0,0,0,0,1,0,0,0,5,0,0,0,67,0,0, - 0,115,24,0,0,0,116,0,116,1,160,2,116,3,124,0, - 106,4,131,1,100,1,25,0,161,1,131,1,83,0,114,0, - 1,0,0,41,5,218,4,105,116,101,114,114,2,0,0,0, - 218,7,108,105,115,116,100,105,114,114,47,0,0,0,114,44, - 0,0,0,114,246,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,8,99,111,110,116,101,110,116, - 115,224,3,0,0,115,2,0,0,0,0,1,122,19,70,105, - 108,101,76,111,97,100,101,114,46,99,111,110,116,101,110,116, - 115,41,17,114,125,0,0,0,114,124,0,0,0,114,126,0, - 0,0,114,127,0,0,0,114,209,0,0,0,114,243,0,0, - 0,114,247,0,0,0,114,136,0,0,0,114,220,0,0,0, - 114,179,0,0,0,114,227,0,0,0,114,253,0,0,0,114, - 255,0,0,0,114,3,1,0,0,114,1,1,0,0,114,7, - 1,0,0,90,13,95,95,99,108,97,115,115,99,101,108,108, - 95,95,114,3,0,0,0,114,3,0,0,0,114,249,0,0, - 0,114,6,0,0,0,114,239,0,0,0,160,3,0,0,115, - 30,0,0,0,8,2,4,3,8,6,8,4,8,3,2,1, - 14,11,2,1,10,4,8,7,2,1,10,5,8,4,8,6, - 8,6,114,239,0,0,0,99,0,0,0,0,0,0,0,0, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,3,0,0,0,67,0,0,0,115,38,0,0,0,124, + 0,160,0,124,1,161,1,115,14,116,1,130,1,116,2,116, + 3,124,0,106,4,131,1,100,1,25,0,124,1,131,2,125, + 2,124,2,83,0,169,2,78,114,73,0,0,0,41,5,218, + 11,105,115,95,114,101,115,111,117,114,99,101,218,17,70,105, + 108,101,78,111,116,70,111,117,110,100,69,114,114,111,114,114, + 38,0,0,0,114,47,0,0,0,114,44,0,0,0,114,254, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,13,114,101,115,111,117,114,99,101,95,112,97,116, + 104,213,3,0,0,115,8,0,0,0,0,1,10,1,4,1, + 20,1,122,24,70,105,108,101,76,111,97,100,101,114,46,114, + 101,115,111,117,114,99,101,95,112,97,116,104,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, + 0,67,0,0,0,115,40,0,0,0,116,0,124,1,107,6, + 114,12,100,1,83,0,116,1,116,2,124,0,106,3,131,1, + 100,2,25,0,124,1,131,2,125,2,116,4,124,2,131,1, + 83,0,41,3,78,70,114,73,0,0,0,41,5,114,35,0, + 0,0,114,38,0,0,0,114,47,0,0,0,114,44,0,0, + 0,114,54,0,0,0,169,3,114,119,0,0,0,114,117,0, + 0,0,114,44,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,1,1,0,0,219,3,0,0,115, + 8,0,0,0,0,1,8,1,4,1,20,1,122,22,70,105, + 108,101,76,111,97,100,101,114,46,105,115,95,114,101,115,111, + 117,114,99,101,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,5,0,0,0,67,0,0,0,115,24,0, + 0,0,116,0,116,1,160,2,116,3,124,0,106,4,131,1, + 100,1,25,0,161,1,131,1,83,0,114,0,1,0,0,41, + 5,218,4,105,116,101,114,114,2,0,0,0,218,7,108,105, + 115,116,100,105,114,114,47,0,0,0,114,44,0,0,0,114, + 246,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,8,99,111,110,116,101,110,116,115,225,3,0, + 0,115,2,0,0,0,0,1,122,19,70,105,108,101,76,111, + 97,100,101,114,46,99,111,110,116,101,110,116,115,41,17,114, + 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, + 0,0,0,114,209,0,0,0,114,243,0,0,0,114,247,0, + 0,0,114,136,0,0,0,114,220,0,0,0,114,179,0,0, + 0,114,227,0,0,0,114,253,0,0,0,114,255,0,0,0, + 114,3,1,0,0,114,1,1,0,0,114,7,1,0,0,90, + 13,95,95,99,108,97,115,115,99,101,108,108,95,95,114,3, + 0,0,0,114,3,0,0,0,114,249,0,0,0,114,6,0, + 0,0,114,239,0,0,0,161,3,0,0,115,30,0,0,0, + 8,2,4,3,8,6,8,4,8,3,2,1,14,11,2,1, + 10,4,8,7,2,1,10,5,8,4,8,6,8,6,114,239, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,3,0,0,0,64,0,0,0,115,46,0,0, 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,100, @@ -1532,72 +1548,73 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, 83,111,117,114,99,101,76,111,97,100,101,114,32,117,115,105, 110,103,32,116,104,101,32,102,105,108,101,32,115,121,115,116, - 101,109,46,99,2,0,0,0,0,0,0,0,3,0,0,0, - 3,0,0,0,67,0,0,0,115,22,0,0,0,116,0,124, - 1,131,1,125,2,124,2,106,1,124,2,106,2,100,1,156, - 2,83,0,41,2,122,33,82,101,116,117,114,110,32,116,104, - 101,32,109,101,116,97,100,97,116,97,32,102,111,114,32,116, - 104,101,32,112,97,116,104,46,41,2,114,169,0,0,0,114, - 234,0,0,0,41,3,114,49,0,0,0,218,8,115,116,95, - 109,116,105,109,101,90,7,115,116,95,115,105,122,101,41,3, - 114,119,0,0,0,114,44,0,0,0,114,238,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,224, - 0,0,0,232,3,0,0,115,4,0,0,0,0,2,8,1, - 122,27,83,111,117,114,99,101,70,105,108,101,76,111,97,100, - 101,114,46,112,97,116,104,95,115,116,97,116,115,99,4,0, - 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, - 0,0,115,24,0,0,0,116,0,124,1,131,1,125,4,124, - 0,106,1,124,2,124,3,124,4,100,1,141,3,83,0,41, - 2,78,169,1,218,5,95,109,111,100,101,41,2,114,115,0, - 0,0,114,225,0,0,0,41,5,114,119,0,0,0,114,108, - 0,0,0,114,107,0,0,0,114,26,0,0,0,114,52,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,226,0,0,0,237,3,0,0,115,4,0,0,0,0, - 2,8,1,122,32,83,111,117,114,99,101,70,105,108,101,76, - 111,97,100,101,114,46,95,99,97,99,104,101,95,98,121,116, - 101,99,111,100,101,114,60,0,0,0,114,10,1,0,0,99, - 3,0,0,0,1,0,0,0,9,0,0,0,11,0,0,0, - 67,0,0,0,115,0,1,0,0,116,0,124,1,131,1,92, - 2,125,4,125,5,103,0,125,6,124,4,114,52,116,1,124, - 4,131,1,115,52,116,0,124,4,131,1,92,2,125,4,125, - 7,124,6,160,2,124,7,161,1,1,0,113,16,116,3,124, - 6,131,1,68,0,93,112,125,7,116,4,124,4,124,7,131, - 2,125,4,122,14,116,5,160,6,124,4,161,1,1,0,87, - 0,110,82,4,0,116,7,107,10,114,112,1,0,1,0,1, - 0,89,0,113,60,89,0,110,60,4,0,116,8,107,10,114, - 170,1,0,125,8,1,0,122,30,116,9,160,10,100,1,124, - 4,124,8,161,3,1,0,87,0,89,0,162,10,1,0,100, - 2,83,0,87,0,53,0,100,2,125,8,126,8,88,0,89, - 0,110,2,88,0,113,60,122,28,116,11,124,1,124,2,124, - 3,131,3,1,0,116,9,160,10,100,3,124,1,161,2,1, - 0,87,0,110,48,4,0,116,8,107,10,114,250,1,0,125, - 8,1,0,122,18,116,9,160,10,100,1,124,1,124,8,161, - 3,1,0,87,0,53,0,100,2,125,8,126,8,88,0,89, - 0,110,2,88,0,100,2,83,0,41,4,122,27,87,114,105, - 116,101,32,98,121,116,101,115,32,100,97,116,97,32,116,111, - 32,97,32,102,105,108,101,46,122,27,99,111,117,108,100,32, - 110,111,116,32,99,114,101,97,116,101,32,123,33,114,125,58, - 32,123,33,114,125,78,122,12,99,114,101,97,116,101,100,32, - 123,33,114,125,41,12,114,47,0,0,0,114,56,0,0,0, - 114,186,0,0,0,114,42,0,0,0,114,38,0,0,0,114, - 2,0,0,0,90,5,109,107,100,105,114,218,15,70,105,108, - 101,69,120,105,115,116,115,69,114,114,111,114,114,50,0,0, - 0,114,134,0,0,0,114,149,0,0,0,114,69,0,0,0, - 41,9,114,119,0,0,0,114,44,0,0,0,114,26,0,0, - 0,114,11,1,0,0,218,6,112,97,114,101,110,116,114,97, - 0,0,0,114,37,0,0,0,114,33,0,0,0,114,228,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,225,0,0,0,242,3,0,0,115,48,0,0,0,0, - 2,12,1,4,2,12,1,12,1,12,2,12,1,10,1,2, - 1,14,1,14,2,8,1,16,3,6,1,2,0,2,255,4, - 2,32,1,2,1,12,1,16,1,16,2,8,1,2,255,122, - 25,83,111,117,114,99,101,70,105,108,101,76,111,97,100,101, - 114,46,115,101,116,95,100,97,116,97,78,41,7,114,125,0, - 0,0,114,124,0,0,0,114,126,0,0,0,114,127,0,0, - 0,114,224,0,0,0,114,226,0,0,0,114,225,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,8,1,0,0,228,3,0,0,115,8,0, - 0,0,8,2,4,2,8,5,8,5,114,8,1,0,0,99, + 101,109,46,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,3,0,0,0,67,0,0,0,115,22,0,0, + 0,116,0,124,1,131,1,125,2,124,2,106,1,124,2,106, + 2,100,1,156,2,83,0,41,2,122,33,82,101,116,117,114, + 110,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102, + 111,114,32,116,104,101,32,112,97,116,104,46,41,2,114,169, + 0,0,0,114,234,0,0,0,41,3,114,49,0,0,0,218, + 8,115,116,95,109,116,105,109,101,90,7,115,116,95,115,105, + 122,101,41,3,114,119,0,0,0,114,44,0,0,0,114,238, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,224,0,0,0,233,3,0,0,115,4,0,0,0, + 0,2,8,1,122,27,83,111,117,114,99,101,70,105,108,101, + 76,111,97,100,101,114,46,112,97,116,104,95,115,116,97,116, + 115,99,4,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,5,0,0,0,67,0,0,0,115,24,0,0,0,116, + 0,124,1,131,1,125,4,124,0,106,1,124,2,124,3,124, + 4,100,1,141,3,83,0,41,2,78,169,1,218,5,95,109, + 111,100,101,41,2,114,115,0,0,0,114,225,0,0,0,41, + 5,114,119,0,0,0,114,108,0,0,0,114,107,0,0,0, + 114,26,0,0,0,114,52,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,226,0,0,0,238,3, + 0,0,115,4,0,0,0,0,2,8,1,122,32,83,111,117, + 114,99,101,70,105,108,101,76,111,97,100,101,114,46,95,99, + 97,99,104,101,95,98,121,116,101,99,111,100,101,114,60,0, + 0,0,114,10,1,0,0,99,3,0,0,0,0,0,0,0, + 1,0,0,0,9,0,0,0,11,0,0,0,67,0,0,0, + 115,0,1,0,0,116,0,124,1,131,1,92,2,125,4,125, + 5,103,0,125,6,124,4,114,52,116,1,124,4,131,1,115, + 52,116,0,124,4,131,1,92,2,125,4,125,7,124,6,160, + 2,124,7,161,1,1,0,113,16,116,3,124,6,131,1,68, + 0,93,112,125,7,116,4,124,4,124,7,131,2,125,4,122, + 14,116,5,160,6,124,4,161,1,1,0,87,0,110,82,4, + 0,116,7,107,10,114,112,1,0,1,0,1,0,89,0,113, + 60,89,0,110,60,4,0,116,8,107,10,114,170,1,0,125, + 8,1,0,122,30,116,9,160,10,100,1,124,4,124,8,161, + 3,1,0,87,0,89,0,162,10,1,0,100,2,83,0,87, + 0,53,0,100,2,125,8,126,8,88,0,89,0,110,2,88, + 0,113,60,122,28,116,11,124,1,124,2,124,3,131,3,1, + 0,116,9,160,10,100,3,124,1,161,2,1,0,87,0,110, + 48,4,0,116,8,107,10,114,250,1,0,125,8,1,0,122, + 18,116,9,160,10,100,1,124,1,124,8,161,3,1,0,87, + 0,53,0,100,2,125,8,126,8,88,0,89,0,110,2,88, + 0,100,2,83,0,41,4,122,27,87,114,105,116,101,32,98, + 121,116,101,115,32,100,97,116,97,32,116,111,32,97,32,102, + 105,108,101,46,122,27,99,111,117,108,100,32,110,111,116,32, + 99,114,101,97,116,101,32,123,33,114,125,58,32,123,33,114, + 125,78,122,12,99,114,101,97,116,101,100,32,123,33,114,125, + 41,12,114,47,0,0,0,114,56,0,0,0,114,186,0,0, + 0,114,42,0,0,0,114,38,0,0,0,114,2,0,0,0, + 90,5,109,107,100,105,114,218,15,70,105,108,101,69,120,105, + 115,116,115,69,114,114,111,114,114,50,0,0,0,114,134,0, + 0,0,114,149,0,0,0,114,69,0,0,0,41,9,114,119, + 0,0,0,114,44,0,0,0,114,26,0,0,0,114,11,1, + 0,0,218,6,112,97,114,101,110,116,114,97,0,0,0,114, + 37,0,0,0,114,33,0,0,0,114,228,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,225,0, + 0,0,243,3,0,0,115,48,0,0,0,0,2,12,1,4, + 2,12,1,12,1,12,2,12,1,10,1,2,1,14,1,14, + 2,8,1,16,3,6,1,2,0,2,255,4,2,32,1,2, + 1,12,1,16,1,16,2,8,1,2,255,122,25,83,111,117, + 114,99,101,70,105,108,101,76,111,97,100,101,114,46,115,101, + 116,95,100,97,116,97,78,41,7,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,224,0, + 0,0,114,226,0,0,0,114,225,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,8,1,0,0,229,3,0,0,115,8,0,0,0,8,2, + 4,2,8,5,8,5,114,8,1,0,0,99,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, 64,0,0,0,115,32,0,0,0,101,0,90,1,100,0,90, 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, @@ -1606,93 +1623,95 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,122,45,76,111,97,100,101,114,32,119,104,105,99,104,32, 104,97,110,100,108,101,115,32,115,111,117,114,99,101,108,101, 115,115,32,102,105,108,101,32,105,109,112,111,114,116,115,46, - 99,2,0,0,0,0,0,0,0,5,0,0,0,5,0,0, - 0,67,0,0,0,115,68,0,0,0,124,0,160,0,124,1, - 161,1,125,2,124,0,160,1,124,2,161,1,125,3,124,1, - 124,2,100,1,156,2,125,4,116,2,124,3,124,1,124,4, - 131,3,1,0,116,3,116,4,124,3,131,1,100,2,100,0, - 133,2,25,0,124,1,124,2,100,3,141,3,83,0,41,4, - 78,114,159,0,0,0,114,145,0,0,0,41,2,114,117,0, - 0,0,114,107,0,0,0,41,5,114,179,0,0,0,114,227, - 0,0,0,114,152,0,0,0,114,165,0,0,0,114,235,0, - 0,0,41,5,114,119,0,0,0,114,139,0,0,0,114,44, - 0,0,0,114,26,0,0,0,114,151,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,213,0,0, - 0,21,4,0,0,115,22,0,0,0,0,1,10,1,10,4, - 2,1,2,254,6,4,12,1,2,1,14,1,2,1,2,253, - 122,29,83,111,117,114,99,101,108,101,115,115,70,105,108,101, - 76,111,97,100,101,114,46,103,101,116,95,99,111,100,101,99, - 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, - 39,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, - 116,104,101,114,101,32,105,115,32,110,111,32,115,111,117,114, - 99,101,32,99,111,100,101,46,78,114,3,0,0,0,114,219, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,229,0,0,0,37,4,0,0,115,2,0,0,0, - 0,2,122,31,83,111,117,114,99,101,108,101,115,115,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,78,41,6,114,125,0,0,0,114,124,0,0,0, - 114,126,0,0,0,114,127,0,0,0,114,213,0,0,0,114, - 229,0,0,0,114,3,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,14,1,0,0,17,4,0, - 0,115,6,0,0,0,8,2,4,2,8,16,114,14,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,64,0,0,0,115,92,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, - 4,100,5,132,0,90,5,100,6,100,7,132,0,90,6,100, - 8,100,9,132,0,90,7,100,10,100,11,132,0,90,8,100, - 12,100,13,132,0,90,9,100,14,100,15,132,0,90,10,100, - 16,100,17,132,0,90,11,101,12,100,18,100,19,132,0,131, - 1,90,13,100,20,83,0,41,21,218,19,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,122,93, - 76,111,97,100,101,114,32,102,111,114,32,101,120,116,101,110, - 115,105,111,110,32,109,111,100,117,108,101,115,46,10,10,32, - 32,32,32,84,104,101,32,99,111,110,115,116,114,117,99,116, - 111,114,32,105,115,32,100,101,115,105,103,110,101,100,32,116, - 111,32,119,111,114,107,32,119,105,116,104,32,70,105,108,101, - 70,105,110,100,101,114,46,10,10,32,32,32,32,99,3,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,5,0,0,0,67,0,0,0,115,68,0,0,0,124,0, + 160,0,124,1,161,1,125,2,124,0,160,1,124,2,161,1, + 125,3,124,1,124,2,100,1,156,2,125,4,116,2,124,3, + 124,1,124,4,131,3,1,0,116,3,116,4,124,3,131,1, + 100,2,100,0,133,2,25,0,124,1,124,2,100,3,141,3, + 83,0,41,4,78,114,159,0,0,0,114,145,0,0,0,41, + 2,114,117,0,0,0,114,107,0,0,0,41,5,114,179,0, + 0,0,114,227,0,0,0,114,152,0,0,0,114,165,0,0, + 0,114,235,0,0,0,41,5,114,119,0,0,0,114,139,0, + 0,0,114,44,0,0,0,114,26,0,0,0,114,151,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,213,0,0,0,22,4,0,0,115,22,0,0,0,0,1, + 10,1,10,4,2,1,2,254,6,4,12,1,2,1,14,1, + 2,1,2,253,122,29,83,111,117,114,99,101,108,101,115,115, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,99, + 111,100,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,83,0,41,2,122,39,82,101,116,117,114,110,32, + 78,111,110,101,32,97,115,32,116,104,101,114,101,32,105,115, + 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, + 78,114,3,0,0,0,114,219,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,229,0,0,0,38, + 4,0,0,115,2,0,0,0,0,2,122,31,83,111,117,114, + 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, + 46,103,101,116,95,115,111,117,114,99,101,78,41,6,114,125, + 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, + 0,0,114,213,0,0,0,114,229,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,14,1,0,0,18,4,0,0,115,6,0,0,0,8,2, + 4,2,8,16,114,14,1,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, + 0,0,115,92,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, + 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, + 0,90,7,100,10,100,11,132,0,90,8,100,12,100,13,132, + 0,90,9,100,14,100,15,132,0,90,10,100,16,100,17,132, + 0,90,11,101,12,100,18,100,19,132,0,131,1,90,13,100, + 20,83,0,41,21,218,19,69,120,116,101,110,115,105,111,110, + 70,105,108,101,76,111,97,100,101,114,122,93,76,111,97,100, + 101,114,32,102,111,114,32,101,120,116,101,110,115,105,111,110, + 32,109,111,100,117,108,101,115,46,10,10,32,32,32,32,84, + 104,101,32,99,111,110,115,116,114,117,99,116,111,114,32,105, + 115,32,100,101,115,105,103,110,101,100,32,116,111,32,119,111, + 114,107,32,119,105,116,104,32,70,105,108,101,70,105,110,100, + 101,114,46,10,10,32,32,32,32,99,3,0,0,0,0,0, 0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0, 0,0,115,16,0,0,0,124,1,124,0,95,0,124,2,124, 0,95,1,100,0,83,0,114,110,0,0,0,114,159,0,0, 0,114,4,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,209,0,0,0,54,4,0,0,115,4, + 114,6,0,0,0,114,209,0,0,0,55,4,0,0,115,4, 0,0,0,0,1,6,1,122,28,69,120,116,101,110,115,105, 111,110,70,105,108,101,76,111,97,100,101,114,46,95,95,105, - 110,105,116,95,95,99,2,0,0,0,0,0,0,0,2,0, - 0,0,2,0,0,0,67,0,0,0,115,24,0,0,0,124, - 0,106,0,124,1,106,0,107,2,111,22,124,0,106,1,124, - 1,106,1,107,2,83,0,114,110,0,0,0,114,240,0,0, - 0,114,242,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,243,0,0,0,58,4,0,0,115,6, - 0,0,0,0,1,12,1,10,255,122,26,69,120,116,101,110, + 110,105,116,95,95,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,24, + 0,0,0,124,0,106,0,124,1,106,0,107,2,111,22,124, + 0,106,1,124,1,106,1,107,2,83,0,114,110,0,0,0, + 114,240,0,0,0,114,242,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,243,0,0,0,59,4, + 0,0,115,6,0,0,0,0,1,12,1,10,255,122,26,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,46,95,95,101,113,95,95,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,20,0,0,0,116,0,124,0,106,1,131,1,116, + 0,124,0,106,2,131,1,65,0,83,0,114,110,0,0,0, + 114,244,0,0,0,114,246,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,247,0,0,0,63,4, + 0,0,115,2,0,0,0,0,1,122,28,69,120,116,101,110, 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95, - 95,101,113,95,95,99,1,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,20,0,0,0,116, - 0,124,0,106,1,131,1,116,0,124,0,106,2,131,1,65, - 0,83,0,114,110,0,0,0,114,244,0,0,0,114,246,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,247,0,0,0,62,4,0,0,115,2,0,0,0,0, - 1,122,28,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,95,95,104,97,115,104,95,95,99, - 2,0,0,0,0,0,0,0,3,0,0,0,5,0,0,0, - 67,0,0,0,115,36,0,0,0,116,0,160,1,116,2,106, - 3,124,1,161,2,125,2,116,0,160,4,100,1,124,1,106, - 5,124,0,106,6,161,3,1,0,124,2,83,0,41,2,122, - 38,67,114,101,97,116,101,32,97,110,32,117,110,105,116,105, - 97,108,105,122,101,100,32,101,120,116,101,110,115,105,111,110, - 32,109,111,100,117,108,101,122,38,101,120,116,101,110,115,105, - 111,110,32,109,111,100,117,108,101,32,123,33,114,125,32,108, - 111,97,100,101,100,32,102,114,111,109,32,123,33,114,125,41, - 7,114,134,0,0,0,114,214,0,0,0,114,163,0,0,0, - 90,14,99,114,101,97,116,101,95,100,121,110,97,109,105,99, - 114,149,0,0,0,114,117,0,0,0,114,44,0,0,0,41, - 3,114,119,0,0,0,114,187,0,0,0,114,216,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 212,0,0,0,65,4,0,0,115,18,0,0,0,0,2,4, - 1,4,0,2,255,4,2,6,1,4,0,4,255,4,2,122, - 33,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,2,0,0,0,5, + 95,104,97,115,104,95,95,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,5,0,0,0,67,0,0,0, + 115,36,0,0,0,116,0,160,1,116,2,106,3,124,1,161, + 2,125,2,116,0,160,4,100,1,124,1,106,5,124,0,106, + 6,161,3,1,0,124,2,83,0,41,2,122,38,67,114,101, + 97,116,101,32,97,110,32,117,110,105,116,105,97,108,105,122, + 101,100,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,122,38,101,120,116,101,110,115,105,111,110,32,109, + 111,100,117,108,101,32,123,33,114,125,32,108,111,97,100,101, + 100,32,102,114,111,109,32,123,33,114,125,41,7,114,134,0, + 0,0,114,214,0,0,0,114,163,0,0,0,90,14,99,114, + 101,97,116,101,95,100,121,110,97,109,105,99,114,149,0,0, + 0,114,117,0,0,0,114,44,0,0,0,41,3,114,119,0, + 0,0,114,187,0,0,0,114,216,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,212,0,0,0, + 66,4,0,0,115,18,0,0,0,0,2,4,1,4,0,2, + 255,4,2,6,1,4,0,4,255,4,2,122,33,69,120,116, + 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, + 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5, 0,0,0,67,0,0,0,115,36,0,0,0,116,0,160,1, 116,2,106,3,124,1,161,2,1,0,116,0,160,4,100,1, 124,0,106,5,124,0,106,6,161,3,1,0,100,2,83,0, @@ -1705,46 +1724,47 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,120,101,99,95,100,121,110,97,109,105,99,114,149,0,0, 0,114,117,0,0,0,114,44,0,0,0,114,252,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 217,0,0,0,73,4,0,0,115,10,0,0,0,0,2,14, + 217,0,0,0,74,4,0,0,115,10,0,0,0,0,2,14, 1,6,1,4,0,4,255,122,31,69,120,116,101,110,115,105, 111,110,70,105,108,101,76,111,97,100,101,114,46,101,120,101, 99,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,3,0,0,0,115,36,0, - 0,0,116,0,124,0,106,1,131,1,100,1,25,0,137,0, - 116,2,135,0,102,1,100,2,100,3,132,8,116,3,68,0, - 131,1,131,1,83,0,41,4,122,49,82,101,116,117,114,110, - 32,84,114,117,101,32,105,102,32,116,104,101,32,101,120,116, - 101,110,115,105,111,110,32,109,111,100,117,108,101,32,105,115, - 32,97,32,112,97,99,107,97,103,101,46,114,39,0,0,0, - 99,1,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,51,0,0,0,115,26,0,0,0,124,0,93,18,125,1, - 136,0,100,0,124,1,23,0,107,2,86,0,1,0,113,2, - 100,1,83,0,41,2,114,209,0,0,0,78,114,3,0,0, - 0,169,2,114,32,0,0,0,218,6,115,117,102,102,105,120, - 169,1,90,9,102,105,108,101,95,110,97,109,101,114,3,0, - 0,0,114,6,0,0,0,218,9,60,103,101,110,101,120,112, - 114,62,82,4,0,0,115,4,0,0,0,4,1,2,255,122, - 49,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,105,115,95,112,97,99,107,97,103,101,46, - 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, - 114,62,41,4,114,47,0,0,0,114,44,0,0,0,218,3, - 97,110,121,218,18,69,88,84,69,78,83,73,79,78,95,83, - 85,70,70,73,88,69,83,114,219,0,0,0,114,3,0,0, - 0,114,18,1,0,0,114,6,0,0,0,114,182,0,0,0, - 79,4,0,0,115,8,0,0,0,0,2,14,1,12,1,2, - 255,122,30,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,103, - 101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,122,63,82,101,116,117,114,110,32,78,111,110,101,32,97, - 115,32,97,110,32,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,99,97,110,110,111,116,32,99,114,101, - 97,116,101,32,97,32,99,111,100,101,32,111,98,106,101,99, - 116,46,78,114,3,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,213,0,0, - 0,85,4,0,0,115,2,0,0,0,0,2,122,28,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0, + 0,0,0,0,0,2,0,0,0,4,0,0,0,3,0,0, + 0,115,36,0,0,0,116,0,124,0,106,1,131,1,100,1, + 25,0,137,0,116,2,135,0,102,1,100,2,100,3,132,8, + 116,3,68,0,131,1,131,1,83,0,41,4,122,49,82,101, + 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, + 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, + 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,114, + 39,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,4,0,0,0,51,0,0,0,115,26,0, + 0,0,124,0,93,18,125,1,136,0,100,0,124,1,23,0, + 107,2,86,0,1,0,113,2,100,1,83,0,41,2,114,209, + 0,0,0,78,114,3,0,0,0,169,2,114,32,0,0,0, + 218,6,115,117,102,102,105,120,169,1,90,9,102,105,108,101, + 95,110,97,109,101,114,3,0,0,0,114,6,0,0,0,218, + 9,60,103,101,110,101,120,112,114,62,83,4,0,0,115,4, + 0,0,0,4,1,2,255,122,49,69,120,116,101,110,115,105, + 111,110,70,105,108,101,76,111,97,100,101,114,46,105,115,95, + 112,97,99,107,97,103,101,46,60,108,111,99,97,108,115,62, + 46,60,103,101,110,101,120,112,114,62,41,4,114,47,0,0, + 0,114,44,0,0,0,218,3,97,110,121,218,18,69,88,84, + 69,78,83,73,79,78,95,83,85,70,70,73,88,69,83,114, + 219,0,0,0,114,3,0,0,0,114,18,1,0,0,114,6, + 0,0,0,114,182,0,0,0,80,4,0,0,115,8,0,0, + 0,0,2,14,1,12,1,2,255,122,30,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,122,63,82, + 101,116,117,114,110,32,78,111,110,101,32,97,115,32,97,110, + 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, + 101,32,99,97,110,110,111,116,32,99,114,101,97,116,101,32, + 97,32,99,111,100,101,32,111,98,106,101,99,116,46,78,114, + 3,0,0,0,114,219,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,213,0,0,0,86,4,0, + 0,115,2,0,0,0,0,2,122,28,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,103,101, + 116,95,99,111,100,101,99,2,0,0,0,0,0,0,0,0, 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, 4,0,0,0,100,1,83,0,41,2,122,53,82,101,116,117, 114,110,32,78,111,110,101,32,97,115,32,101,120,116,101,110, @@ -1752,67 +1772,68 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,32,110,111,32,115,111,117,114,99,101,32,99,111,100,101, 46,78,114,3,0,0,0,114,219,0,0,0,114,3,0,0, 0,114,3,0,0,0,114,6,0,0,0,114,229,0,0,0, - 89,4,0,0,115,2,0,0,0,0,2,122,30,69,120,116, + 90,4,0,0,115,2,0,0,0,0,2,122,30,69,120,116, 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, 46,103,101,116,95,115,111,117,114,99,101,99,2,0,0,0, - 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, - 115,6,0,0,0,124,0,106,0,83,0,114,250,0,0,0, - 114,48,0,0,0,114,219,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,179,0,0,0,93,4, - 0,0,115,2,0,0,0,0,3,122,32,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,103, - 101,116,95,102,105,108,101,110,97,109,101,78,41,14,114,125, - 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, - 0,0,114,209,0,0,0,114,243,0,0,0,114,247,0,0, - 0,114,212,0,0,0,114,217,0,0,0,114,182,0,0,0, - 114,213,0,0,0,114,229,0,0,0,114,136,0,0,0,114, - 179,0,0,0,114,3,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,15,1,0,0,46,4,0, - 0,115,22,0,0,0,8,2,4,6,8,4,8,4,8,3, - 8,8,8,6,8,6,8,4,8,4,2,1,114,15,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,64,0,0,0,115,104,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, - 4,100,5,132,0,90,5,100,6,100,7,132,0,90,6,100, - 8,100,9,132,0,90,7,100,10,100,11,132,0,90,8,100, - 12,100,13,132,0,90,9,100,14,100,15,132,0,90,10,100, - 16,100,17,132,0,90,11,100,18,100,19,132,0,90,12,100, - 20,100,21,132,0,90,13,100,22,100,23,132,0,90,14,100, - 24,83,0,41,25,218,14,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,97,38,1,0,0,82,101,112,114,101,115, - 101,110,116,115,32,97,32,110,97,109,101,115,112,97,99,101, - 32,112,97,99,107,97,103,101,39,115,32,112,97,116,104,46, - 32,32,73,116,32,117,115,101,115,32,116,104,101,32,109,111, - 100,117,108,101,32,110,97,109,101,10,32,32,32,32,116,111, - 32,102,105,110,100,32,105,116,115,32,112,97,114,101,110,116, - 32,109,111,100,117,108,101,44,32,97,110,100,32,102,114,111, - 109,32,116,104,101,114,101,32,105,116,32,108,111,111,107,115, - 32,117,112,32,116,104,101,32,112,97,114,101,110,116,39,115, - 10,32,32,32,32,95,95,112,97,116,104,95,95,46,32,32, - 87,104,101,110,32,116,104,105,115,32,99,104,97,110,103,101, - 115,44,32,116,104,101,32,109,111,100,117,108,101,39,115,32, - 111,119,110,32,112,97,116,104,32,105,115,32,114,101,99,111, - 109,112,117,116,101,100,44,10,32,32,32,32,117,115,105,110, - 103,32,112,97,116,104,95,102,105,110,100,101,114,46,32,32, - 70,111,114,32,116,111,112,45,108,101,118,101,108,32,109,111, - 100,117,108,101,115,44,32,116,104,101,32,112,97,114,101,110, - 116,32,109,111,100,117,108,101,39,115,32,112,97,116,104,10, - 32,32,32,32,105,115,32,115,121,115,46,112,97,116,104,46, - 99,4,0,0,0,0,0,0,0,4,0,0,0,3,0,0, - 0,67,0,0,0,115,36,0,0,0,124,1,124,0,95,0, - 124,2,124,0,95,1,116,2,124,0,160,3,161,0,131,1, - 124,0,95,4,124,3,124,0,95,5,100,0,83,0,114,110, - 0,0,0,41,6,218,5,95,110,97,109,101,218,5,95,112, - 97,116,104,114,112,0,0,0,218,16,95,103,101,116,95,112, - 97,114,101,110,116,95,112,97,116,104,218,17,95,108,97,115, - 116,95,112,97,114,101,110,116,95,112,97,116,104,218,12,95, - 112,97,116,104,95,102,105,110,100,101,114,169,4,114,119,0, - 0,0,114,117,0,0,0,114,44,0,0,0,90,11,112,97, - 116,104,95,102,105,110,100,101,114,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,209,0,0,0,106,4,0, - 0,115,8,0,0,0,0,1,6,1,6,1,14,1,122,23, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,6,0,0,0,124,0,106,0,83,0,114, + 250,0,0,0,114,48,0,0,0,114,219,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,179,0, + 0,0,94,4,0,0,115,2,0,0,0,0,3,122,32,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,102,105,108,101,110,97,109,101,78, + 41,14,114,125,0,0,0,114,124,0,0,0,114,126,0,0, + 0,114,127,0,0,0,114,209,0,0,0,114,243,0,0,0, + 114,247,0,0,0,114,212,0,0,0,114,217,0,0,0,114, + 182,0,0,0,114,213,0,0,0,114,229,0,0,0,114,136, + 0,0,0,114,179,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,15,1,0, + 0,47,4,0,0,115,22,0,0,0,8,2,4,6,8,4, + 8,4,8,3,8,8,8,6,8,6,8,4,8,4,2,1, + 114,15,1,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,104, + 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, + 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100, + 6,100,7,132,0,90,6,100,8,100,9,132,0,90,7,100, + 10,100,11,132,0,90,8,100,12,100,13,132,0,90,9,100, + 14,100,15,132,0,90,10,100,16,100,17,132,0,90,11,100, + 18,100,19,132,0,90,12,100,20,100,21,132,0,90,13,100, + 22,100,23,132,0,90,14,100,24,83,0,41,25,218,14,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,97,38,1, + 0,0,82,101,112,114,101,115,101,110,116,115,32,97,32,110, + 97,109,101,115,112,97,99,101,32,112,97,99,107,97,103,101, + 39,115,32,112,97,116,104,46,32,32,73,116,32,117,115,101, + 115,32,116,104,101,32,109,111,100,117,108,101,32,110,97,109, + 101,10,32,32,32,32,116,111,32,102,105,110,100,32,105,116, + 115,32,112,97,114,101,110,116,32,109,111,100,117,108,101,44, + 32,97,110,100,32,102,114,111,109,32,116,104,101,114,101,32, + 105,116,32,108,111,111,107,115,32,117,112,32,116,104,101,32, + 112,97,114,101,110,116,39,115,10,32,32,32,32,95,95,112, + 97,116,104,95,95,46,32,32,87,104,101,110,32,116,104,105, + 115,32,99,104,97,110,103,101,115,44,32,116,104,101,32,109, + 111,100,117,108,101,39,115,32,111,119,110,32,112,97,116,104, + 32,105,115,32,114,101,99,111,109,112,117,116,101,100,44,10, + 32,32,32,32,117,115,105,110,103,32,112,97,116,104,95,102, + 105,110,100,101,114,46,32,32,70,111,114,32,116,111,112,45, + 108,101,118,101,108,32,109,111,100,117,108,101,115,44,32,116, + 104,101,32,112,97,114,101,110,116,32,109,111,100,117,108,101, + 39,115,32,112,97,116,104,10,32,32,32,32,105,115,32,115, + 121,115,46,112,97,116,104,46,99,4,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,3,0,0,0,67,0,0, + 0,115,36,0,0,0,124,1,124,0,95,0,124,2,124,0, + 95,1,116,2,124,0,160,3,161,0,131,1,124,0,95,4, + 124,3,124,0,95,5,100,0,83,0,114,110,0,0,0,41, + 6,218,5,95,110,97,109,101,218,5,95,112,97,116,104,114, + 112,0,0,0,218,16,95,103,101,116,95,112,97,114,101,110, + 116,95,112,97,116,104,218,17,95,108,97,115,116,95,112,97, + 114,101,110,116,95,112,97,116,104,218,12,95,112,97,116,104, + 95,102,105,110,100,101,114,169,4,114,119,0,0,0,114,117, + 0,0,0,114,44,0,0,0,90,11,112,97,116,104,95,102, + 105,110,100,101,114,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,209,0,0,0,107,4,0,0,115,8,0, + 0,0,0,1,6,1,6,1,14,1,122,23,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,105,110,105, + 116,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, 4,0,0,0,3,0,0,0,67,0,0,0,115,38,0,0, 0,124,0,106,0,160,1,100,1,161,1,92,3,125,1,125, 2,125,3,124,2,100,2,107,2,114,30,100,3,83,0,124, @@ -1827,119 +1848,122 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,218,3,100,111,116,90,2,109,101,114,3,0,0,0,114, 3,0,0,0,114,6,0,0,0,218,23,95,102,105,110,100, 95,112,97,114,101,110,116,95,112,97,116,104,95,110,97,109, - 101,115,112,4,0,0,115,8,0,0,0,0,2,18,1,8, + 101,115,113,4,0,0,115,8,0,0,0,0,2,18,1,8, 2,4,3,122,38,95,78,97,109,101,115,112,97,99,101,80, 97,116,104,46,95,102,105,110,100,95,112,97,114,101,110,116, 95,112,97,116,104,95,110,97,109,101,115,99,1,0,0,0, - 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, - 115,28,0,0,0,124,0,160,0,161,0,92,2,125,1,125, - 2,116,1,116,2,106,3,124,1,25,0,124,2,131,2,83, - 0,114,110,0,0,0,41,4,114,30,1,0,0,114,130,0, - 0,0,114,8,0,0,0,218,7,109,111,100,117,108,101,115, - 41,3,114,119,0,0,0,90,18,112,97,114,101,110,116,95, - 109,111,100,117,108,101,95,110,97,109,101,90,14,112,97,116, - 104,95,97,116,116,114,95,110,97,109,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,25,1,0,0,122, - 4,0,0,115,4,0,0,0,0,1,12,1,122,31,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,103,101, - 116,95,112,97,114,101,110,116,95,112,97,116,104,99,1,0, - 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, - 0,0,115,80,0,0,0,116,0,124,0,160,1,161,0,131, - 1,125,1,124,1,124,0,106,2,107,3,114,74,124,0,160, - 3,124,0,106,4,124,1,161,2,125,2,124,2,100,0,107, - 9,114,68,124,2,106,5,100,0,107,8,114,68,124,2,106, - 6,114,68,124,2,106,6,124,0,95,7,124,1,124,0,95, - 2,124,0,106,7,83,0,114,110,0,0,0,41,8,114,112, - 0,0,0,114,25,1,0,0,114,26,1,0,0,114,27,1, - 0,0,114,23,1,0,0,114,140,0,0,0,114,178,0,0, - 0,114,24,1,0,0,41,3,114,119,0,0,0,90,11,112, - 97,114,101,110,116,95,112,97,116,104,114,187,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,12, - 95,114,101,99,97,108,99,117,108,97,116,101,126,4,0,0, - 115,16,0,0,0,0,2,12,1,10,1,14,3,18,1,6, - 1,8,1,6,1,122,27,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,114,101,99,97,108,99,117,108,97, - 116,101,99,1,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,12,0,0,0,116,0,124,0, - 160,1,161,0,131,1,83,0,114,110,0,0,0,41,2,114, - 5,1,0,0,114,32,1,0,0,114,246,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,8,95, - 95,105,116,101,114,95,95,139,4,0,0,115,2,0,0,0, - 0,1,122,23,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,95,105,116,101,114,95,95,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 67,0,0,0,115,28,0,0,0,124,0,160,0,161,0,92, + 2,125,1,125,2,116,1,116,2,106,3,124,1,25,0,124, + 2,131,2,83,0,114,110,0,0,0,41,4,114,30,1,0, + 0,114,130,0,0,0,114,8,0,0,0,218,7,109,111,100, + 117,108,101,115,41,3,114,119,0,0,0,90,18,112,97,114, + 101,110,116,95,109,111,100,117,108,101,95,110,97,109,101,90, + 14,112,97,116,104,95,97,116,116,114,95,110,97,109,101,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,25, + 1,0,0,123,4,0,0,115,4,0,0,0,0,1,12,1, + 122,31,95,78,97,109,101,115,112,97,99,101,80,97,116,104, + 46,95,103,101,116,95,112,97,114,101,110,116,95,112,97,116, + 104,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,4,0,0,0,67,0,0,0,115,80,0,0,0,116, + 0,124,0,160,1,161,0,131,1,125,1,124,1,124,0,106, + 2,107,3,114,74,124,0,160,3,124,0,106,4,124,1,161, + 2,125,2,124,2,100,0,107,9,114,68,124,2,106,5,100, + 0,107,8,114,68,124,2,106,6,114,68,124,2,106,6,124, + 0,95,7,124,1,124,0,95,2,124,0,106,7,83,0,114, + 110,0,0,0,41,8,114,112,0,0,0,114,25,1,0,0, + 114,26,1,0,0,114,27,1,0,0,114,23,1,0,0,114, + 140,0,0,0,114,178,0,0,0,114,24,1,0,0,41,3, + 114,119,0,0,0,90,11,112,97,114,101,110,116,95,112,97, + 116,104,114,187,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,12,95,114,101,99,97,108,99,117, + 108,97,116,101,127,4,0,0,115,16,0,0,0,0,2,12, + 1,10,1,14,3,18,1,6,1,8,1,6,1,122,27,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,114, + 101,99,97,108,99,117,108,97,116,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,12,0,0,0,116,0,124,0,160,1,161,0, + 131,1,83,0,114,110,0,0,0,41,2,114,5,1,0,0, + 114,32,1,0,0,114,246,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,8,95,95,105,116,101, + 114,95,95,140,4,0,0,115,2,0,0,0,0,1,122,23, + 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, + 95,105,116,101,114,95,95,99,2,0,0,0,0,0,0,0, 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, 115,12,0,0,0,124,0,160,0,161,0,124,1,25,0,83, 0,114,110,0,0,0,169,1,114,32,1,0,0,41,2,114, 119,0,0,0,218,5,105,110,100,101,120,114,3,0,0,0, 114,3,0,0,0,114,6,0,0,0,218,11,95,95,103,101, - 116,105,116,101,109,95,95,142,4,0,0,115,2,0,0,0, + 116,105,116,101,109,95,95,143,4,0,0,115,2,0,0,0, 0,1,122,26,95,78,97,109,101,115,112,97,99,101,80,97, 116,104,46,95,95,103,101,116,105,116,101,109,95,95,99,3, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,14,0,0,0,124,2,124,0,106,0,124,1, - 60,0,100,0,83,0,114,110,0,0,0,41,1,114,24,1, - 0,0,41,3,114,119,0,0,0,114,35,1,0,0,114,44, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,11,95,95,115,101,116,105,116,101,109,95,95,145, - 4,0,0,115,2,0,0,0,0,1,122,26,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,95,115,101,116, - 105,116,101,109,95,95,99,1,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0, - 116,0,124,0,160,1,161,0,131,1,83,0,114,110,0,0, - 0,41,2,114,22,0,0,0,114,32,1,0,0,114,246,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,7,95,95,108,101,110,95,95,148,4,0,0,115,2, - 0,0,0,0,1,122,22,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,95,108,101,110,95,95,99,1,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,12,0,0,0,100,1,160,0,124,0,106,1,161, - 1,83,0,41,2,78,122,20,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,40,123,33,114,125,41,41,2,114,62, - 0,0,0,114,24,1,0,0,114,246,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,8,95,95, - 114,101,112,114,95,95,151,4,0,0,115,2,0,0,0,0, - 1,122,23,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,114,101,112,114,95,95,99,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, + 0,0,0,67,0,0,0,115,14,0,0,0,124,2,124,0, + 106,0,124,1,60,0,100,0,83,0,114,110,0,0,0,41, + 1,114,24,1,0,0,41,3,114,119,0,0,0,114,35,1, + 0,0,114,44,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,11,95,95,115,101,116,105,116,101, + 109,95,95,146,4,0,0,115,2,0,0,0,0,1,122,26, + 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, + 95,115,101,116,105,116,101,109,95,95,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,12,0,0,0,116,0,124,0,160,1,161,0, + 131,1,83,0,114,110,0,0,0,41,2,114,22,0,0,0, + 114,32,1,0,0,114,246,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,7,95,95,108,101,110, + 95,95,149,4,0,0,115,2,0,0,0,0,1,122,22,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, + 108,101,110,95,95,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,12, + 0,0,0,100,1,160,0,124,0,106,1,161,1,83,0,41, + 2,78,122,20,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,40,123,33,114,125,41,41,2,114,62,0,0,0,114, + 24,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,8,95,95,114,101,112,114, + 95,95,152,4,0,0,115,2,0,0,0,0,1,122,23,95, + 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, + 114,101,112,114,95,95,99,2,0,0,0,0,0,0,0,0, 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, 12,0,0,0,124,1,124,0,160,0,161,0,107,6,83,0, 114,110,0,0,0,114,34,1,0,0,169,2,114,119,0,0, 0,218,4,105,116,101,109,114,3,0,0,0,114,3,0,0, 0,114,6,0,0,0,218,12,95,95,99,111,110,116,97,105, - 110,115,95,95,154,4,0,0,115,2,0,0,0,0,1,122, + 110,115,95,95,155,4,0,0,115,2,0,0,0,0,1,122, 27,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, 95,95,99,111,110,116,97,105,110,115,95,95,99,2,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,16,0,0,0,124,0,106,0,160,1,124,1,161,1, - 1,0,100,0,83,0,114,110,0,0,0,41,2,114,24,1, - 0,0,114,186,0,0,0,114,40,1,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,186,0,0,0, - 157,4,0,0,115,2,0,0,0,0,1,122,21,95,78,97, - 109,101,115,112,97,99,101,80,97,116,104,46,97,112,112,101, - 110,100,78,41,15,114,125,0,0,0,114,124,0,0,0,114, - 126,0,0,0,114,127,0,0,0,114,209,0,0,0,114,30, - 1,0,0,114,25,1,0,0,114,32,1,0,0,114,33,1, - 0,0,114,36,1,0,0,114,37,1,0,0,114,38,1,0, - 0,114,39,1,0,0,114,42,1,0,0,114,186,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,22,1,0,0,99,4,0,0,115,24,0, - 0,0,8,1,4,6,8,6,8,10,8,4,8,13,8,3, - 8,3,8,3,8,3,8,3,8,3,114,22,1,0,0,99, - 0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 64,0,0,0,115,80,0,0,0,101,0,90,1,100,0,90, - 2,100,1,100,2,132,0,90,3,101,4,100,3,100,4,132, - 0,131,1,90,5,100,5,100,6,132,0,90,6,100,7,100, - 8,132,0,90,7,100,9,100,10,132,0,90,8,100,11,100, - 12,132,0,90,9,100,13,100,14,132,0,90,10,100,15,100, - 16,132,0,90,11,100,17,83,0,41,18,218,16,95,78,97, - 109,101,115,112,97,99,101,76,111,97,100,101,114,99,4,0, - 0,0,0,0,0,0,4,0,0,0,4,0,0,0,67,0, - 0,0,115,18,0,0,0,116,0,124,1,124,2,124,3,131, - 3,124,0,95,1,100,0,83,0,114,110,0,0,0,41,2, - 114,22,1,0,0,114,24,1,0,0,114,28,1,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,209, - 0,0,0,163,4,0,0,115,2,0,0,0,0,1,122,25, - 95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,114, - 46,95,95,105,110,105,116,95,95,99,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, + 0,67,0,0,0,115,16,0,0,0,124,0,106,0,160,1, + 124,1,161,1,1,0,100,0,83,0,114,110,0,0,0,41, + 2,114,24,1,0,0,114,186,0,0,0,114,40,1,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 186,0,0,0,158,4,0,0,115,2,0,0,0,0,1,122, + 21,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 97,112,112,101,110,100,78,41,15,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,209,0, + 0,0,114,30,1,0,0,114,25,1,0,0,114,32,1,0, + 0,114,33,1,0,0,114,36,1,0,0,114,37,1,0,0, + 114,38,1,0,0,114,39,1,0,0,114,42,1,0,0,114, + 186,0,0,0,114,3,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,22,1,0,0,100,4,0, + 0,115,24,0,0,0,8,1,4,6,8,6,8,10,8,4, + 8,13,8,3,8,3,8,3,8,3,8,3,8,3,114,22, + 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,64,0,0,0,115,80,0,0, + 0,101,0,90,1,100,0,90,2,100,1,100,2,132,0,90, + 3,101,4,100,3,100,4,132,0,131,1,90,5,100,5,100, + 6,132,0,90,6,100,7,100,8,132,0,90,7,100,9,100, + 10,132,0,90,8,100,11,100,12,132,0,90,9,100,13,100, + 14,132,0,90,10,100,15,100,16,132,0,90,11,100,17,83, + 0,41,18,218,16,95,78,97,109,101,115,112,97,99,101,76, + 111,97,100,101,114,99,4,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,18, + 0,0,0,116,0,124,1,124,2,124,3,131,3,124,0,95, + 1,100,0,83,0,114,110,0,0,0,41,2,114,22,1,0, + 0,114,24,1,0,0,114,28,1,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,209,0,0,0,164, + 4,0,0,115,2,0,0,0,0,1,122,25,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,46,95,95,105, + 110,105,116,95,95,99,2,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,12, 0,0,0,100,1,160,0,124,1,106,1,161,1,83,0,41, 2,122,115,82,101,116,117,114,110,32,114,101,112,114,32,102, @@ -1954,84 +1978,86 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 62,41,2,114,62,0,0,0,114,125,0,0,0,41,2,114, 193,0,0,0,114,216,0,0,0,114,3,0,0,0,114,3, 0,0,0,114,6,0,0,0,218,11,109,111,100,117,108,101, - 95,114,101,112,114,166,4,0,0,115,2,0,0,0,0,7, + 95,114,101,112,114,167,4,0,0,115,2,0,0,0,0,7, 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, 101,114,46,109,111,100,117,108,101,95,114,101,112,114,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,78,84,114,3,0,0,0,114,219,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,182,0, + 0,0,176,4,0,0,115,2,0,0,0,0,1,122,27,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,41,2,78,84, - 114,3,0,0,0,114,219,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,182,0,0,0,175,4, - 0,0,115,2,0,0,0,0,1,122,27,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,105,115,95,112, - 97,99,107,97,103,101,99,2,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,1,83,0,41,2,78,114,40,0,0,0,114,3,0,0, - 0,114,219,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,229,0,0,0,178,4,0,0,115,2, - 0,0,0,0,1,122,27,95,78,97,109,101,115,112,97,99, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,99,2,0,0,0,0,0,0,0,2,0,0,0,6, - 0,0,0,67,0,0,0,115,16,0,0,0,116,0,100,1, - 100,2,100,3,100,4,100,5,141,4,83,0,41,6,78,114, - 40,0,0,0,122,8,60,115,116,114,105,110,103,62,114,215, - 0,0,0,84,41,1,114,231,0,0,0,41,1,114,232,0, - 0,0,114,219,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,213,0,0,0,181,4,0,0,115, - 2,0,0,0,0,1,122,25,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,46,103,101,116,95,99,111,100, - 101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, + 0,0,0,115,4,0,0,0,100,1,83,0,41,2,78,114, + 40,0,0,0,114,3,0,0,0,114,219,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,229,0, + 0,0,179,4,0,0,115,2,0,0,0,0,1,122,27,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,67, + 0,0,0,115,16,0,0,0,116,0,100,1,100,2,100,3, + 100,4,100,5,141,4,83,0,41,6,78,114,40,0,0,0, + 122,8,60,115,116,114,105,110,103,62,114,215,0,0,0,84, + 41,1,114,231,0,0,0,41,1,114,232,0,0,0,114,219, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,213,0,0,0,182,4,0,0,115,2,0,0,0, + 0,1,122,25,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,103,101,116,95,99,111,100,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,114, 210,0,0,0,114,3,0,0,0,114,211,0,0,0,114,3, 0,0,0,114,3,0,0,0,114,6,0,0,0,114,212,0, - 0,0,184,4,0,0,115,2,0,0,0,0,1,122,30,95, + 0,0,185,4,0,0,115,2,0,0,0,0,1,122,30,95, 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, 99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,0, - 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, - 0,0,115,4,0,0,0,100,0,83,0,114,110,0,0,0, - 114,3,0,0,0,114,252,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,217,0,0,0,187,4, - 0,0,115,2,0,0,0,0,1,122,28,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,101,120,101,99, - 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,67,0,0,0,115,26,0,0, - 0,116,0,160,1,100,1,124,0,106,2,161,2,1,0,116, - 0,160,3,124,0,124,1,161,2,83,0,41,2,122,98,76, - 111,97,100,32,97,32,110,97,109,101,115,112,97,99,101,32, - 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,105, - 110,115,116,101,97,100,46,10,10,32,32,32,32,32,32,32, - 32,122,38,110,97,109,101,115,112,97,99,101,32,109,111,100, - 117,108,101,32,108,111,97,100,101,100,32,119,105,116,104,32, - 112,97,116,104,32,123,33,114,125,41,4,114,134,0,0,0, - 114,149,0,0,0,114,24,1,0,0,114,218,0,0,0,114, - 219,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,220,0,0,0,190,4,0,0,115,8,0,0, - 0,0,7,6,1,4,255,4,2,122,28,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,108,111,97,100, - 95,109,111,100,117,108,101,78,41,12,114,125,0,0,0,114, - 124,0,0,0,114,126,0,0,0,114,209,0,0,0,114,207, - 0,0,0,114,44,1,0,0,114,182,0,0,0,114,229,0, - 0,0,114,213,0,0,0,114,212,0,0,0,114,217,0,0, - 0,114,220,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,43,1,0,0,162, - 4,0,0,115,18,0,0,0,8,1,8,3,2,1,10,8, - 8,3,8,3,8,3,8,3,8,3,114,43,1,0,0,99, - 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 64,0,0,0,115,106,0,0,0,101,0,90,1,100,0,90, - 2,100,1,90,3,101,4,100,2,100,3,132,0,131,1,90, - 5,101,4,100,4,100,5,132,0,131,1,90,6,101,4,100, - 6,100,7,132,0,131,1,90,7,101,4,100,8,100,9,132, - 0,131,1,90,8,101,4,100,17,100,11,100,12,132,1,131, - 1,90,9,101,4,100,18,100,13,100,14,132,1,131,1,90, - 10,101,4,100,19,100,15,100,16,132,1,131,1,90,11,100, - 10,83,0,41,20,218,10,80,97,116,104,70,105,110,100,101, - 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, - 100,101,114,32,102,111,114,32,115,121,115,46,112,97,116,104, - 32,97,110,100,32,112,97,99,107,97,103,101,32,95,95,112, - 97,116,104,95,95,32,97,116,116,114,105,98,117,116,101,115, - 46,99,1,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, + 0,0,67,0,0,0,115,4,0,0,0,100,0,83,0,114, + 110,0,0,0,114,3,0,0,0,114,252,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,217,0, + 0,0,188,4,0,0,115,2,0,0,0,0,1,122,28,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, + 67,0,0,0,115,26,0,0,0,116,0,160,1,100,1,124, + 0,106,2,161,2,1,0,116,0,160,3,124,0,124,1,161, + 2,83,0,41,2,122,98,76,111,97,100,32,97,32,110,97, + 109,101,115,112,97,99,101,32,109,111,100,117,108,101,46,10, + 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, + 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,32,85,115,101,32,101,120,101,99,95,109,111, + 100,117,108,101,40,41,32,105,110,115,116,101,97,100,46,10, + 10,32,32,32,32,32,32,32,32,122,38,110,97,109,101,115, + 112,97,99,101,32,109,111,100,117,108,101,32,108,111,97,100, + 101,100,32,119,105,116,104,32,112,97,116,104,32,123,33,114, + 125,41,4,114,134,0,0,0,114,149,0,0,0,114,24,1, + 0,0,114,218,0,0,0,114,219,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,220,0,0,0, + 191,4,0,0,115,8,0,0,0,0,7,6,1,4,255,4, + 2,122,28,95,78,97,109,101,115,112,97,99,101,76,111,97, + 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,78, + 41,12,114,125,0,0,0,114,124,0,0,0,114,126,0,0, + 0,114,209,0,0,0,114,207,0,0,0,114,44,1,0,0, + 114,182,0,0,0,114,229,0,0,0,114,213,0,0,0,114, + 212,0,0,0,114,217,0,0,0,114,220,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,43,1,0,0,163,4,0,0,115,18,0,0,0, + 8,1,8,3,2,1,10,8,8,3,8,3,8,3,8,3, + 8,3,114,43,1,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,64,0,0,0, + 115,106,0,0,0,101,0,90,1,100,0,90,2,100,1,90, + 3,101,4,100,2,100,3,132,0,131,1,90,5,101,4,100, + 4,100,5,132,0,131,1,90,6,101,4,100,6,100,7,132, + 0,131,1,90,7,101,4,100,8,100,9,132,0,131,1,90, + 8,101,4,100,17,100,11,100,12,132,1,131,1,90,9,101, + 4,100,18,100,13,100,14,132,1,131,1,90,10,101,4,100, + 19,100,15,100,16,132,1,131,1,90,11,100,10,83,0,41, + 20,218,10,80,97,116,104,70,105,110,100,101,114,122,62,77, + 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32, + 102,111,114,32,115,121,115,46,112,97,116,104,32,97,110,100, + 32,112,97,99,107,97,103,101,32,95,95,112,97,116,104,95, + 95,32,97,116,116,114,105,98,117,116,101,115,46,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, 0,0,67,0,0,0,115,64,0,0,0,116,0,116,1,106, 2,160,3,161,0,131,1,68,0,93,44,92,2,125,1,125, 2,124,2,100,1,107,8,114,40,116,1,106,2,124,1,61, @@ -2051,79 +2077,80 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 104,101,218,5,105,116,101,109,115,114,128,0,0,0,114,46, 1,0,0,41,3,114,193,0,0,0,114,117,0,0,0,218, 6,102,105,110,100,101,114,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,46,1,0,0,208,4,0,0,115, + 0,114,6,0,0,0,114,46,1,0,0,209,4,0,0,115, 10,0,0,0,0,4,22,1,8,1,10,1,10,1,122,28, 80,97,116,104,70,105,110,100,101,114,46,105,110,118,97,108, 105,100,97,116,101,95,99,97,99,104,101,115,99,2,0,0, - 0,0,0,0,0,3,0,0,0,9,0,0,0,67,0,0, - 0,115,84,0,0,0,116,0,106,1,100,1,107,9,114,28, - 116,0,106,1,115,28,116,2,160,3,100,2,116,4,161,2, - 1,0,116,0,106,1,68,0,93,44,125,2,122,14,124,2, - 124,1,131,1,87,0,2,0,1,0,83,0,4,0,116,5, - 107,10,114,76,1,0,1,0,1,0,89,0,113,34,89,0, - 113,34,88,0,113,34,100,1,83,0,41,3,122,46,83,101, - 97,114,99,104,32,115,121,115,46,112,97,116,104,95,104,111, - 111,107,115,32,102,111,114,32,97,32,102,105,110,100,101,114, - 32,102,111,114,32,39,112,97,116,104,39,46,78,122,23,115, - 121,115,46,112,97,116,104,95,104,111,111,107,115,32,105,115, - 32,101,109,112,116,121,41,6,114,8,0,0,0,218,10,112, - 97,116,104,95,104,111,111,107,115,114,75,0,0,0,114,76, - 0,0,0,114,138,0,0,0,114,118,0,0,0,41,3,114, - 193,0,0,0,114,44,0,0,0,90,4,104,111,111,107,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,11, - 95,112,97,116,104,95,104,111,111,107,115,218,4,0,0,115, - 16,0,0,0,0,3,16,1,12,1,10,1,2,1,14,1, - 14,1,12,2,122,22,80,97,116,104,70,105,110,100,101,114, - 46,95,112,97,116,104,95,104,111,111,107,115,99,2,0,0, - 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, - 0,115,104,0,0,0,124,1,100,1,107,2,114,44,122,12, - 116,0,160,1,161,0,125,1,87,0,110,22,4,0,116,2, - 107,10,114,42,1,0,1,0,1,0,89,0,100,2,83,0, - 88,0,122,14,116,3,106,4,124,1,25,0,125,2,87,0, - 110,40,4,0,116,5,107,10,114,98,1,0,1,0,1,0, - 124,0,160,6,124,1,161,1,125,2,124,2,116,3,106,4, - 124,1,60,0,89,0,110,2,88,0,124,2,83,0,41,3, - 122,210,71,101,116,32,116,104,101,32,102,105,110,100,101,114, - 32,102,111,114,32,116,104,101,32,112,97,116,104,32,101,110, - 116,114,121,32,102,114,111,109,32,115,121,115,46,112,97,116, - 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, - 46,10,10,32,32,32,32,32,32,32,32,73,102,32,116,104, - 101,32,112,97,116,104,32,101,110,116,114,121,32,105,115,32, - 110,111,116,32,105,110,32,116,104,101,32,99,97,99,104,101, - 44,32,102,105,110,100,32,116,104,101,32,97,112,112,114,111, - 112,114,105,97,116,101,32,102,105,110,100,101,114,10,32,32, - 32,32,32,32,32,32,97,110,100,32,99,97,99,104,101,32, - 105,116,46,32,73,102,32,110,111,32,102,105,110,100,101,114, - 32,105,115,32,97,118,97,105,108,97,98,108,101,44,32,115, - 116,111,114,101,32,78,111,110,101,46,10,10,32,32,32,32, - 32,32,32,32,114,40,0,0,0,78,41,7,114,2,0,0, - 0,114,55,0,0,0,114,2,1,0,0,114,8,0,0,0, - 114,48,1,0,0,218,8,75,101,121,69,114,114,111,114,114, - 52,1,0,0,41,3,114,193,0,0,0,114,44,0,0,0, - 114,50,1,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,20,95,112,97,116,104,95,105,109,112,111, - 114,116,101,114,95,99,97,99,104,101,231,4,0,0,115,22, - 0,0,0,0,8,8,1,2,1,12,1,14,3,8,1,2, - 1,14,1,14,1,10,1,16,1,122,31,80,97,116,104,70, - 105,110,100,101,114,46,95,112,97,116,104,95,105,109,112,111, - 114,116,101,114,95,99,97,99,104,101,99,3,0,0,0,0, - 0,0,0,6,0,0,0,4,0,0,0,67,0,0,0,115, - 82,0,0,0,116,0,124,2,100,1,131,2,114,26,124,2, - 160,1,124,1,161,1,92,2,125,3,125,4,110,14,124,2, - 160,2,124,1,161,1,125,3,103,0,125,4,124,3,100,0, - 107,9,114,60,116,3,160,4,124,1,124,3,161,2,83,0, - 116,3,160,5,124,1,100,0,161,2,125,5,124,4,124,5, - 95,6,124,5,83,0,41,2,78,114,137,0,0,0,41,7, - 114,128,0,0,0,114,137,0,0,0,114,206,0,0,0,114, - 134,0,0,0,114,201,0,0,0,114,183,0,0,0,114,178, - 0,0,0,41,6,114,193,0,0,0,114,139,0,0,0,114, - 50,1,0,0,114,140,0,0,0,114,141,0,0,0,114,187, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,16,95,108,101,103,97,99,121,95,103,101,116,95, - 115,112,101,99,253,4,0,0,115,18,0,0,0,0,4,10, - 1,16,2,10,1,4,1,8,1,12,1,12,1,6,1,122, - 27,80,97,116,104,70,105,110,100,101,114,46,95,108,101,103, - 97,99,121,95,103,101,116,95,115,112,101,99,78,99,4,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,9,0,0, + 0,67,0,0,0,115,84,0,0,0,116,0,106,1,100,1, + 107,9,114,28,116,0,106,1,115,28,116,2,160,3,100,2, + 116,4,161,2,1,0,116,0,106,1,68,0,93,44,125,2, + 122,14,124,2,124,1,131,1,87,0,2,0,1,0,83,0, + 4,0,116,5,107,10,114,76,1,0,1,0,1,0,89,0, + 113,34,89,0,113,34,88,0,113,34,100,1,83,0,41,3, + 122,46,83,101,97,114,99,104,32,115,121,115,46,112,97,116, + 104,95,104,111,111,107,115,32,102,111,114,32,97,32,102,105, + 110,100,101,114,32,102,111,114,32,39,112,97,116,104,39,46, + 78,122,23,115,121,115,46,112,97,116,104,95,104,111,111,107, + 115,32,105,115,32,101,109,112,116,121,41,6,114,8,0,0, + 0,218,10,112,97,116,104,95,104,111,111,107,115,114,75,0, + 0,0,114,76,0,0,0,114,138,0,0,0,114,118,0,0, + 0,41,3,114,193,0,0,0,114,44,0,0,0,90,4,104, + 111,111,107,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,11,95,112,97,116,104,95,104,111,111,107,115,219, + 4,0,0,115,16,0,0,0,0,3,16,1,12,1,10,1, + 2,1,14,1,14,1,12,2,122,22,80,97,116,104,70,105, + 110,100,101,114,46,95,112,97,116,104,95,104,111,111,107,115, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,104,0,0,0,124,1, + 100,1,107,2,114,44,122,12,116,0,160,1,161,0,125,1, + 87,0,110,22,4,0,116,2,107,10,114,42,1,0,1,0, + 1,0,89,0,100,2,83,0,88,0,122,14,116,3,106,4, + 124,1,25,0,125,2,87,0,110,40,4,0,116,5,107,10, + 114,98,1,0,1,0,1,0,124,0,160,6,124,1,161,1, + 125,2,124,2,116,3,106,4,124,1,60,0,89,0,110,2, + 88,0,124,2,83,0,41,3,122,210,71,101,116,32,116,104, + 101,32,102,105,110,100,101,114,32,102,111,114,32,116,104,101, + 32,112,97,116,104,32,101,110,116,114,121,32,102,114,111,109, + 32,115,121,115,46,112,97,116,104,95,105,109,112,111,114,116, + 101,114,95,99,97,99,104,101,46,10,10,32,32,32,32,32, + 32,32,32,73,102,32,116,104,101,32,112,97,116,104,32,101, + 110,116,114,121,32,105,115,32,110,111,116,32,105,110,32,116, + 104,101,32,99,97,99,104,101,44,32,102,105,110,100,32,116, + 104,101,32,97,112,112,114,111,112,114,105,97,116,101,32,102, + 105,110,100,101,114,10,32,32,32,32,32,32,32,32,97,110, + 100,32,99,97,99,104,101,32,105,116,46,32,73,102,32,110, + 111,32,102,105,110,100,101,114,32,105,115,32,97,118,97,105, + 108,97,98,108,101,44,32,115,116,111,114,101,32,78,111,110, + 101,46,10,10,32,32,32,32,32,32,32,32,114,40,0,0, + 0,78,41,7,114,2,0,0,0,114,55,0,0,0,114,2, + 1,0,0,114,8,0,0,0,114,48,1,0,0,218,8,75, + 101,121,69,114,114,111,114,114,52,1,0,0,41,3,114,193, + 0,0,0,114,44,0,0,0,114,50,1,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,20,95,112, + 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, + 104,101,232,4,0,0,115,22,0,0,0,0,8,8,1,2, + 1,12,1,14,3,8,1,2,1,14,1,14,1,10,1,16, + 1,122,31,80,97,116,104,70,105,110,100,101,114,46,95,112, + 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, + 104,101,99,3,0,0,0,0,0,0,0,0,0,0,0,6, + 0,0,0,4,0,0,0,67,0,0,0,115,82,0,0,0, + 116,0,124,2,100,1,131,2,114,26,124,2,160,1,124,1, + 161,1,92,2,125,3,125,4,110,14,124,2,160,2,124,1, + 161,1,125,3,103,0,125,4,124,3,100,0,107,9,114,60, + 116,3,160,4,124,1,124,3,161,2,83,0,116,3,160,5, + 124,1,100,0,161,2,125,5,124,4,124,5,95,6,124,5, + 83,0,41,2,78,114,137,0,0,0,41,7,114,128,0,0, + 0,114,137,0,0,0,114,206,0,0,0,114,134,0,0,0, + 114,201,0,0,0,114,183,0,0,0,114,178,0,0,0,41, + 6,114,193,0,0,0,114,139,0,0,0,114,50,1,0,0, + 114,140,0,0,0,114,141,0,0,0,114,187,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,16, + 95,108,101,103,97,99,121,95,103,101,116,95,115,112,101,99, + 254,4,0,0,115,18,0,0,0,0,4,10,1,16,2,10, + 1,4,1,8,1,12,1,12,1,6,1,122,27,80,97,116, + 104,70,105,110,100,101,114,46,95,108,101,103,97,99,121,95, + 103,101,116,95,115,112,101,99,78,99,4,0,0,0,0,0, 0,0,0,0,0,0,9,0,0,0,5,0,0,0,67,0, 0,0,115,166,0,0,0,103,0,125,4,124,2,68,0,93, 134,125,5,116,0,124,5,116,1,116,2,102,2,131,2,115, @@ -2151,84 +2178,85 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 101,95,112,97,116,104,90,5,101,110,116,114,121,114,50,1, 0,0,114,187,0,0,0,114,141,0,0,0,114,3,0,0, 0,114,3,0,0,0,114,6,0,0,0,218,9,95,103,101, - 116,95,115,112,101,99,12,5,0,0,115,40,0,0,0,0, + 116,95,115,112,101,99,13,5,0,0,115,40,0,0,0,0, 5,4,1,8,1,14,1,2,1,10,1,8,1,10,1,14, 2,12,1,8,1,2,1,10,1,8,1,6,1,8,1,8, 5,12,2,12,1,6,1,122,20,80,97,116,104,70,105,110, 100,101,114,46,95,103,101,116,95,115,112,101,99,99,4,0, - 0,0,0,0,0,0,6,0,0,0,5,0,0,0,67,0, - 0,0,115,100,0,0,0,124,2,100,1,107,8,114,14,116, - 0,106,1,125,2,124,0,160,2,124,1,124,2,124,3,161, - 3,125,4,124,4,100,1,107,8,114,40,100,1,83,0,124, - 4,106,3,100,1,107,8,114,92,124,4,106,4,125,5,124, - 5,114,86,100,1,124,4,95,5,116,6,124,1,124,5,124, - 0,106,2,131,3,124,4,95,4,124,4,83,0,100,1,83, - 0,110,4,124,4,83,0,100,1,83,0,41,2,122,141,84, - 114,121,32,116,111,32,102,105,110,100,32,97,32,115,112,101, - 99,32,102,111,114,32,39,102,117,108,108,110,97,109,101,39, - 32,111,110,32,115,121,115,46,112,97,116,104,32,111,114,32, - 39,112,97,116,104,39,46,10,10,32,32,32,32,32,32,32, - 32,84,104,101,32,115,101,97,114,99,104,32,105,115,32,98, - 97,115,101,100,32,111,110,32,115,121,115,46,112,97,116,104, - 95,104,111,111,107,115,32,97,110,100,32,115,121,115,46,112, - 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, - 104,101,46,10,32,32,32,32,32,32,32,32,78,41,7,114, - 8,0,0,0,114,44,0,0,0,114,58,1,0,0,114,140, - 0,0,0,114,178,0,0,0,114,181,0,0,0,114,22,1, - 0,0,41,6,114,193,0,0,0,114,139,0,0,0,114,44, - 0,0,0,114,202,0,0,0,114,187,0,0,0,114,57,1, + 0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0, + 0,0,67,0,0,0,115,100,0,0,0,124,2,100,1,107, + 8,114,14,116,0,106,1,125,2,124,0,160,2,124,1,124, + 2,124,3,161,3,125,4,124,4,100,1,107,8,114,40,100, + 1,83,0,124,4,106,3,100,1,107,8,114,92,124,4,106, + 4,125,5,124,5,114,86,100,1,124,4,95,5,116,6,124, + 1,124,5,124,0,106,2,131,3,124,4,95,4,124,4,83, + 0,100,1,83,0,110,4,124,4,83,0,100,1,83,0,41, + 2,122,141,84,114,121,32,116,111,32,102,105,110,100,32,97, + 32,115,112,101,99,32,102,111,114,32,39,102,117,108,108,110, + 97,109,101,39,32,111,110,32,115,121,115,46,112,97,116,104, + 32,111,114,32,39,112,97,116,104,39,46,10,10,32,32,32, + 32,32,32,32,32,84,104,101,32,115,101,97,114,99,104,32, + 105,115,32,98,97,115,101,100,32,111,110,32,115,121,115,46, + 112,97,116,104,95,104,111,111,107,115,32,97,110,100,32,115, + 121,115,46,112,97,116,104,95,105,109,112,111,114,116,101,114, + 95,99,97,99,104,101,46,10,32,32,32,32,32,32,32,32, + 78,41,7,114,8,0,0,0,114,44,0,0,0,114,58,1, + 0,0,114,140,0,0,0,114,178,0,0,0,114,181,0,0, + 0,114,22,1,0,0,41,6,114,193,0,0,0,114,139,0, + 0,0,114,44,0,0,0,114,202,0,0,0,114,187,0,0, + 0,114,57,1,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,203,0,0,0,45,5,0,0,115,26, + 0,0,0,0,6,8,1,6,1,14,1,8,1,4,1,10, + 1,6,1,4,3,6,1,16,1,4,2,6,2,122,20,80, + 97,116,104,70,105,110,100,101,114,46,102,105,110,100,95,115, + 112,101,99,99,3,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,4,0,0,0,67,0,0,0,115,30,0,0, + 0,124,0,160,0,124,1,124,2,161,2,125,3,124,3,100, + 1,107,8,114,24,100,1,83,0,124,3,106,1,83,0,41, + 2,122,170,102,105,110,100,32,116,104,101,32,109,111,100,117, + 108,101,32,111,110,32,115,121,115,46,112,97,116,104,32,111, + 114,32,39,112,97,116,104,39,32,98,97,115,101,100,32,111, + 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,115, + 32,97,110,100,10,32,32,32,32,32,32,32,32,115,121,115, + 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, + 97,99,104,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,102, + 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, + 97,100,46,10,10,32,32,32,32,32,32,32,32,78,114,204, + 0,0,0,114,205,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,206,0,0,0,69,5,0,0, + 115,8,0,0,0,0,8,12,1,8,1,4,1,122,22,80, + 97,116,104,70,105,110,100,101,114,46,102,105,110,100,95,109, + 111,100,117,108,101,41,1,78,41,2,78,78,41,1,78,41, + 12,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, + 114,127,0,0,0,114,207,0,0,0,114,46,1,0,0,114, + 52,1,0,0,114,54,1,0,0,114,55,1,0,0,114,58, + 1,0,0,114,203,0,0,0,114,206,0,0,0,114,3,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,203,0,0,0,44,5,0,0,115,26,0,0,0,0, - 6,8,1,6,1,14,1,8,1,4,1,10,1,6,1,4, - 3,6,1,16,1,4,2,6,2,122,20,80,97,116,104,70, - 105,110,100,101,114,46,102,105,110,100,95,115,112,101,99,99, - 3,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, - 67,0,0,0,115,30,0,0,0,124,0,160,0,124,1,124, - 2,161,2,125,3,124,3,100,1,107,8,114,24,100,1,83, - 0,124,3,106,1,83,0,41,2,122,170,102,105,110,100,32, - 116,104,101,32,109,111,100,117,108,101,32,111,110,32,115,121, - 115,46,112,97,116,104,32,111,114,32,39,112,97,116,104,39, - 32,98,97,115,101,100,32,111,110,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,115,32,97,110,100,10,32,32,32, - 32,32,32,32,32,115,121,115,46,112,97,116,104,95,105,109, - 112,111,114,116,101,114,95,99,97,99,104,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, - 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, - 32,32,32,32,32,78,114,204,0,0,0,114,205,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 206,0,0,0,68,5,0,0,115,8,0,0,0,0,8,12, - 1,8,1,4,1,122,22,80,97,116,104,70,105,110,100,101, - 114,46,102,105,110,100,95,109,111,100,117,108,101,41,1,78, - 41,2,78,78,41,1,78,41,12,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,127,0,0,0,114,207,0, - 0,0,114,46,1,0,0,114,52,1,0,0,114,54,1,0, - 0,114,55,1,0,0,114,58,1,0,0,114,203,0,0,0, - 114,206,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,45,1,0,0,204,4, - 0,0,115,30,0,0,0,8,2,4,2,2,1,10,9,2, - 1,10,12,2,1,10,21,2,1,10,14,2,1,12,31,2, - 1,12,23,2,1,114,45,1,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, - 90,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5, - 101,6,90,7,100,6,100,7,132,0,90,8,100,8,100,9, - 132,0,90,9,100,19,100,11,100,12,132,1,90,10,100,13, - 100,14,132,0,90,11,101,12,100,15,100,16,132,0,131,1, - 90,13,100,17,100,18,132,0,90,14,100,10,83,0,41,20, - 218,10,70,105,108,101,70,105,110,100,101,114,122,172,70,105, - 108,101,45,98,97,115,101,100,32,102,105,110,100,101,114,46, - 10,10,32,32,32,32,73,110,116,101,114,97,99,116,105,111, - 110,115,32,119,105,116,104,32,116,104,101,32,102,105,108,101, - 32,115,121,115,116,101,109,32,97,114,101,32,99,97,99,104, - 101,100,32,102,111,114,32,112,101,114,102,111,114,109,97,110, - 99,101,44,32,98,101,105,110,103,10,32,32,32,32,114,101, - 102,114,101,115,104,101,100,32,119,104,101,110,32,116,104,101, - 32,100,105,114,101,99,116,111,114,121,32,116,104,101,32,102, - 105,110,100,101,114,32,105,115,32,104,97,110,100,108,105,110, - 103,32,104,97,115,32,98,101,101,110,32,109,111,100,105,102, - 105,101,100,46,10,10,32,32,32,32,99,2,0,0,0,0, + 0,114,45,1,0,0,205,4,0,0,115,30,0,0,0,8, + 2,4,2,2,1,10,9,2,1,10,12,2,1,10,21,2, + 1,10,14,2,1,12,31,2,1,12,23,2,1,114,45,1, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,64,0,0,0,115,90,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, + 132,0,90,4,100,4,100,5,132,0,90,5,101,6,90,7, + 100,6,100,7,132,0,90,8,100,8,100,9,132,0,90,9, + 100,19,100,11,100,12,132,1,90,10,100,13,100,14,132,0, + 90,11,101,12,100,15,100,16,132,0,131,1,90,13,100,17, + 100,18,132,0,90,14,100,10,83,0,41,20,218,10,70,105, + 108,101,70,105,110,100,101,114,122,172,70,105,108,101,45,98, + 97,115,101,100,32,102,105,110,100,101,114,46,10,10,32,32, + 32,32,73,110,116,101,114,97,99,116,105,111,110,115,32,119, + 105,116,104,32,116,104,101,32,102,105,108,101,32,115,121,115, + 116,101,109,32,97,114,101,32,99,97,99,104,101,100,32,102, + 111,114,32,112,101,114,102,111,114,109,97,110,99,101,44,32, + 98,101,105,110,103,10,32,32,32,32,114,101,102,114,101,115, + 104,101,100,32,119,104,101,110,32,116,104,101,32,100,105,114, + 101,99,116,111,114,121,32,116,104,101,32,102,105,110,100,101, + 114,32,105,115,32,104,97,110,100,108,105,110,103,32,104,97, + 115,32,98,101,101,110,32,109,111,100,105,102,105,101,100,46, + 10,10,32,32,32,32,99,2,0,0,0,0,0,0,0,0, 0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,115, 84,0,0,0,103,0,125,3,124,2,68,0,93,32,92,2, 137,0,125,4,124,3,160,0,135,0,102,1,100,1,100,2, @@ -2245,60 +2273,61 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,32,97,110,100,32,116,104,101,32,102,105,108,101,32,115, 117,102,102,105,120,101,115,32,116,104,101,32,108,111,97,100, 101,114,10,32,32,32,32,32,32,32,32,114,101,99,111,103, - 110,105,122,101,115,46,99,1,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,51,0,0,0,115,22,0,0,0, - 124,0,93,14,125,1,124,1,136,0,102,2,86,0,1,0, - 113,2,100,0,83,0,114,110,0,0,0,114,3,0,0,0, - 114,16,1,0,0,169,1,114,140,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,19,1,0,0,97,5,0,0,115, - 4,0,0,0,4,0,2,0,122,38,70,105,108,101,70,105, - 110,100,101,114,46,95,95,105,110,105,116,95,95,46,60,108, - 111,99,97,108,115,62,46,60,103,101,110,101,120,112,114,62, - 114,71,0,0,0,114,105,0,0,0,78,41,7,114,167,0, - 0,0,218,8,95,108,111,97,100,101,114,115,114,44,0,0, - 0,218,11,95,112,97,116,104,95,109,116,105,109,101,218,3, - 115,101,116,218,11,95,112,97,116,104,95,99,97,99,104,101, - 218,19,95,114,101,108,97,120,101,100,95,112,97,116,104,95, - 99,97,99,104,101,41,5,114,119,0,0,0,114,44,0,0, - 0,218,14,108,111,97,100,101,114,95,100,101,116,97,105,108, - 115,90,7,108,111,97,100,101,114,115,114,189,0,0,0,114, - 3,0,0,0,114,60,1,0,0,114,6,0,0,0,114,209, - 0,0,0,91,5,0,0,115,16,0,0,0,0,4,4,1, - 12,1,26,1,6,2,10,1,6,1,8,1,122,19,70,105, + 110,105,122,101,115,46,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,51,0,0,0,115, + 22,0,0,0,124,0,93,14,125,1,124,1,136,0,102,2, + 86,0,1,0,113,2,100,0,83,0,114,110,0,0,0,114, + 3,0,0,0,114,16,1,0,0,169,1,114,140,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,19,1,0,0,98, + 5,0,0,115,4,0,0,0,4,0,2,0,122,38,70,105, 108,101,70,105,110,100,101,114,46,95,95,105,110,105,116,95, - 95,99,1,0,0,0,0,0,0,0,1,0,0,0,2,0, - 0,0,67,0,0,0,115,10,0,0,0,100,1,124,0,95, - 0,100,2,83,0,41,3,122,31,73,110,118,97,108,105,100, - 97,116,101,32,116,104,101,32,100,105,114,101,99,116,111,114, - 121,32,109,116,105,109,101,46,114,105,0,0,0,78,41,1, - 114,62,1,0,0,114,246,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,46,1,0,0,105,5, - 0,0,115,2,0,0,0,0,2,122,28,70,105,108,101,70, - 105,110,100,101,114,46,105,110,118,97,108,105,100,97,116,101, - 95,99,97,99,104,101,115,99,2,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,42,0,0, - 0,124,0,160,0,124,1,161,1,125,2,124,2,100,1,107, - 8,114,26,100,1,103,0,102,2,83,0,124,2,106,1,124, - 2,106,2,112,38,103,0,102,2,83,0,41,2,122,197,84, - 114,121,32,116,111,32,102,105,110,100,32,97,32,108,111,97, - 100,101,114,32,102,111,114,32,116,104,101,32,115,112,101,99, - 105,102,105,101,100,32,109,111,100,117,108,101,44,32,111,114, - 32,116,104,101,32,110,97,109,101,115,112,97,99,101,10,32, - 32,32,32,32,32,32,32,112,97,99,107,97,103,101,32,112, - 111,114,116,105,111,110,115,46,32,82,101,116,117,114,110,115, - 32,40,108,111,97,100,101,114,44,32,108,105,115,116,45,111, - 102,45,112,111,114,116,105,111,110,115,41,46,10,10,32,32, - 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 32,32,85,115,101,32,102,105,110,100,95,115,112,101,99,40, - 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, - 32,32,32,32,78,41,3,114,203,0,0,0,114,140,0,0, - 0,114,178,0,0,0,41,3,114,119,0,0,0,114,139,0, - 0,0,114,187,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,137,0,0,0,111,5,0,0,115, - 8,0,0,0,0,7,10,1,8,1,8,1,122,22,70,105, - 108,101,70,105,110,100,101,114,46,102,105,110,100,95,108,111, - 97,100,101,114,99,6,0,0,0,0,0,0,0,7,0,0, + 95,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, + 120,112,114,62,114,71,0,0,0,114,105,0,0,0,78,41, + 7,114,167,0,0,0,218,8,95,108,111,97,100,101,114,115, + 114,44,0,0,0,218,11,95,112,97,116,104,95,109,116,105, + 109,101,218,3,115,101,116,218,11,95,112,97,116,104,95,99, + 97,99,104,101,218,19,95,114,101,108,97,120,101,100,95,112, + 97,116,104,95,99,97,99,104,101,41,5,114,119,0,0,0, + 114,44,0,0,0,218,14,108,111,97,100,101,114,95,100,101, + 116,97,105,108,115,90,7,108,111,97,100,101,114,115,114,189, + 0,0,0,114,3,0,0,0,114,60,1,0,0,114,6,0, + 0,0,114,209,0,0,0,92,5,0,0,115,16,0,0,0, + 0,4,4,1,12,1,26,1,6,2,10,1,6,1,8,1, + 122,19,70,105,108,101,70,105,110,100,101,114,46,95,95,105, + 110,105,116,95,95,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,2,0,0,0,67,0,0,0,115,10, + 0,0,0,100,1,124,0,95,0,100,2,83,0,41,3,122, + 31,73,110,118,97,108,105,100,97,116,101,32,116,104,101,32, + 100,105,114,101,99,116,111,114,121,32,109,116,105,109,101,46, + 114,105,0,0,0,78,41,1,114,62,1,0,0,114,246,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,46,1,0,0,106,5,0,0,115,2,0,0,0,0, + 2,122,28,70,105,108,101,70,105,110,100,101,114,46,105,110, + 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 3,0,0,0,67,0,0,0,115,42,0,0,0,124,0,160, + 0,124,1,161,1,125,2,124,2,100,1,107,8,114,26,100, + 1,103,0,102,2,83,0,124,2,106,1,124,2,106,2,112, + 38,103,0,102,2,83,0,41,2,122,197,84,114,121,32,116, + 111,32,102,105,110,100,32,97,32,108,111,97,100,101,114,32, + 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, + 100,32,109,111,100,117,108,101,44,32,111,114,32,116,104,101, + 32,110,97,109,101,115,112,97,99,101,10,32,32,32,32,32, + 32,32,32,112,97,99,107,97,103,101,32,112,111,114,116,105, + 111,110,115,46,32,82,101,116,117,114,110,115,32,40,108,111, + 97,100,101,114,44,32,108,105,115,116,45,111,102,45,112,111, + 114,116,105,111,110,115,41,46,10,10,32,32,32,32,32,32, + 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, + 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, + 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, + 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, + 78,41,3,114,203,0,0,0,114,140,0,0,0,114,178,0, + 0,0,41,3,114,119,0,0,0,114,139,0,0,0,114,187, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,137,0,0,0,112,5,0,0,115,8,0,0,0, + 0,7,10,1,8,1,8,1,122,22,70,105,108,101,70,105, + 110,100,101,114,46,102,105,110,100,95,108,111,97,100,101,114, + 99,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0, 0,6,0,0,0,67,0,0,0,115,26,0,0,0,124,1, 124,2,124,3,131,2,125,6,116,0,124,2,124,3,124,6, 124,4,100,1,141,4,83,0,41,2,78,114,177,0,0,0, @@ -2306,114 +2335,115 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,139,0,0,0,114,44,0,0,0,90,4,115, 109,115,108,114,202,0,0,0,114,140,0,0,0,114,3,0, 0,0,114,3,0,0,0,114,6,0,0,0,114,58,1,0, - 0,123,5,0,0,115,8,0,0,0,0,1,10,1,8,1, + 0,124,5,0,0,115,8,0,0,0,0,1,10,1,8,1, 2,255,122,20,70,105,108,101,70,105,110,100,101,114,46,95, 103,101,116,95,115,112,101,99,78,99,3,0,0,0,0,0, - 0,0,14,0,0,0,8,0,0,0,67,0,0,0,115,102, - 1,0,0,100,1,125,3,124,1,160,0,100,2,161,1,100, - 3,25,0,125,4,122,24,116,1,124,0,106,2,112,34,116, - 3,160,4,161,0,131,1,106,5,125,5,87,0,110,24,4, - 0,116,6,107,10,114,66,1,0,1,0,1,0,100,4,125, - 5,89,0,110,2,88,0,124,5,124,0,106,7,107,3,114, - 92,124,0,160,8,161,0,1,0,124,5,124,0,95,7,116, - 9,131,0,114,114,124,0,106,10,125,6,124,4,160,11,161, - 0,125,7,110,10,124,0,106,12,125,6,124,4,125,7,124, - 7,124,6,107,6,114,218,116,13,124,0,106,2,124,4,131, - 2,125,8,124,0,106,14,68,0,93,58,92,2,125,9,125, - 10,100,5,124,9,23,0,125,11,116,13,124,8,124,11,131, - 2,125,12,116,15,124,12,131,1,114,208,124,0,160,16,124, - 10,124,1,124,12,124,8,103,1,124,2,161,5,2,0,1, - 0,83,0,113,150,116,17,124,8,131,1,125,3,124,0,106, - 14,68,0,93,86,92,2,125,9,125,10,116,13,124,0,106, - 2,124,4,124,9,23,0,131,2,125,12,116,18,106,19,100, - 6,124,12,100,3,100,7,141,3,1,0,124,7,124,9,23, - 0,124,6,107,6,144,1,114,54,116,15,124,12,131,1,144, - 1,114,54,124,0,160,16,124,10,124,1,124,12,100,8,124, - 2,161,5,2,0,1,0,83,0,113,224,124,3,144,1,114, - 98,116,18,160,19,100,9,124,8,161,2,1,0,116,18,160, - 20,124,1,100,8,161,2,125,13,124,8,103,1,124,13,95, - 21,124,13,83,0,100,8,83,0,41,10,122,111,84,114,121, - 32,116,111,32,102,105,110,100,32,97,32,115,112,101,99,32, - 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, - 100,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, - 32,32,32,82,101,116,117,114,110,115,32,116,104,101,32,109, - 97,116,99,104,105,110,103,32,115,112,101,99,44,32,111,114, - 32,78,111,110,101,32,105,102,32,110,111,116,32,102,111,117, - 110,100,46,10,32,32,32,32,32,32,32,32,70,114,71,0, - 0,0,114,28,0,0,0,114,105,0,0,0,114,209,0,0, - 0,122,9,116,114,121,105,110,103,32,123,125,41,1,90,9, - 118,101,114,98,111,115,105,116,121,78,122,25,112,111,115,115, - 105,98,108,101,32,110,97,109,101,115,112,97,99,101,32,102, - 111,114,32,123,125,41,22,114,41,0,0,0,114,49,0,0, - 0,114,44,0,0,0,114,2,0,0,0,114,55,0,0,0, - 114,9,1,0,0,114,50,0,0,0,114,62,1,0,0,218, - 11,95,102,105,108,108,95,99,97,99,104,101,114,7,0,0, - 0,114,65,1,0,0,114,106,0,0,0,114,64,1,0,0, - 114,38,0,0,0,114,61,1,0,0,114,54,0,0,0,114, - 58,1,0,0,114,56,0,0,0,114,134,0,0,0,114,149, - 0,0,0,114,183,0,0,0,114,178,0,0,0,41,14,114, - 119,0,0,0,114,139,0,0,0,114,202,0,0,0,90,12, - 105,115,95,110,97,109,101,115,112,97,99,101,90,11,116,97, - 105,108,95,109,111,100,117,108,101,114,169,0,0,0,90,5, - 99,97,99,104,101,90,12,99,97,99,104,101,95,109,111,100, - 117,108,101,90,9,98,97,115,101,95,112,97,116,104,114,17, - 1,0,0,114,188,0,0,0,90,13,105,110,105,116,95,102, - 105,108,101,110,97,109,101,90,9,102,117,108,108,95,112,97, - 116,104,114,187,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,203,0,0,0,128,5,0,0,115, - 74,0,0,0,0,5,4,1,14,1,2,1,24,1,14,1, - 10,1,10,1,8,1,6,2,6,1,6,1,10,2,6,1, - 4,2,8,1,12,1,14,1,8,1,10,1,8,1,26,4, - 8,2,14,1,16,1,16,1,14,1,10,1,10,1,2,0, - 2,255,10,2,6,1,12,1,12,1,8,1,4,1,122,20, - 70,105,108,101,70,105,110,100,101,114,46,102,105,110,100,95, - 115,112,101,99,99,1,0,0,0,0,0,0,0,9,0,0, - 0,10,0,0,0,67,0,0,0,115,190,0,0,0,124,0, - 106,0,125,1,122,22,116,1,160,2,124,1,112,22,116,1, - 160,3,161,0,161,1,125,2,87,0,110,30,4,0,116,4, - 116,5,116,6,102,3,107,10,114,58,1,0,1,0,1,0, - 103,0,125,2,89,0,110,2,88,0,116,7,106,8,160,9, - 100,1,161,1,115,84,116,10,124,2,131,1,124,0,95,11, - 110,74,116,10,131,0,125,3,124,2,68,0,93,56,125,4, - 124,4,160,12,100,2,161,1,92,3,125,5,125,6,125,7, - 124,6,114,136,100,3,160,13,124,5,124,7,160,14,161,0, - 161,2,125,8,110,4,124,5,125,8,124,3,160,15,124,8, - 161,1,1,0,113,94,124,3,124,0,95,11,116,7,106,8, - 160,9,116,16,161,1,114,186,100,4,100,5,132,0,124,2, - 68,0,131,1,124,0,95,17,100,6,83,0,41,7,122,68, - 70,105,108,108,32,116,104,101,32,99,97,99,104,101,32,111, - 102,32,112,111,116,101,110,116,105,97,108,32,109,111,100,117, - 108,101,115,32,97,110,100,32,112,97,99,107,97,103,101,115, - 32,102,111,114,32,116,104,105,115,32,100,105,114,101,99,116, - 111,114,121,46,114,0,0,0,0,114,71,0,0,0,114,61, - 0,0,0,99,1,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,83,0,0,0,115,20,0,0,0,104,0,124, - 0,93,12,125,1,124,1,160,0,161,0,146,2,113,4,83, - 0,114,3,0,0,0,41,1,114,106,0,0,0,41,2,114, - 32,0,0,0,90,2,102,110,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,9,60,115,101,116,99,111,109, - 112,62,205,5,0,0,115,4,0,0,0,6,0,2,0,122, - 41,70,105,108,101,70,105,110,100,101,114,46,95,102,105,108, - 108,95,99,97,99,104,101,46,60,108,111,99,97,108,115,62, - 46,60,115,101,116,99,111,109,112,62,78,41,18,114,44,0, - 0,0,114,2,0,0,0,114,6,1,0,0,114,55,0,0, - 0,114,2,1,0,0,218,15,80,101,114,109,105,115,115,105, - 111,110,69,114,114,111,114,218,18,78,111,116,65,68,105,114, - 101,99,116,111,114,121,69,114,114,111,114,114,8,0,0,0, - 114,9,0,0,0,114,10,0,0,0,114,63,1,0,0,114, - 64,1,0,0,114,101,0,0,0,114,62,0,0,0,114,106, - 0,0,0,218,3,97,100,100,114,11,0,0,0,114,65,1, - 0,0,41,9,114,119,0,0,0,114,44,0,0,0,114,7, - 1,0,0,90,21,108,111,119,101,114,95,115,117,102,102,105, - 120,95,99,111,110,116,101,110,116,115,114,41,1,0,0,114, - 117,0,0,0,114,29,1,0,0,114,17,1,0,0,90,8, - 110,101,119,95,110,97,109,101,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,67,1,0,0,176,5,0,0, - 115,34,0,0,0,0,2,6,1,2,1,22,1,20,3,10, - 3,12,1,12,7,6,1,8,1,16,1,4,1,18,2,4, - 1,12,1,6,1,12,1,122,22,70,105,108,101,70,105,110, - 100,101,114,46,95,102,105,108,108,95,99,97,99,104,101,99, - 1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 0,0,0,0,0,0,14,0,0,0,8,0,0,0,67,0, + 0,0,115,102,1,0,0,100,1,125,3,124,1,160,0,100, + 2,161,1,100,3,25,0,125,4,122,24,116,1,124,0,106, + 2,112,34,116,3,160,4,161,0,131,1,106,5,125,5,87, + 0,110,24,4,0,116,6,107,10,114,66,1,0,1,0,1, + 0,100,4,125,5,89,0,110,2,88,0,124,5,124,0,106, + 7,107,3,114,92,124,0,160,8,161,0,1,0,124,5,124, + 0,95,7,116,9,131,0,114,114,124,0,106,10,125,6,124, + 4,160,11,161,0,125,7,110,10,124,0,106,12,125,6,124, + 4,125,7,124,7,124,6,107,6,114,218,116,13,124,0,106, + 2,124,4,131,2,125,8,124,0,106,14,68,0,93,58,92, + 2,125,9,125,10,100,5,124,9,23,0,125,11,116,13,124, + 8,124,11,131,2,125,12,116,15,124,12,131,1,114,208,124, + 0,160,16,124,10,124,1,124,12,124,8,103,1,124,2,161, + 5,2,0,1,0,83,0,113,150,116,17,124,8,131,1,125, + 3,124,0,106,14,68,0,93,86,92,2,125,9,125,10,116, + 13,124,0,106,2,124,4,124,9,23,0,131,2,125,12,116, + 18,106,19,100,6,124,12,100,3,100,7,141,3,1,0,124, + 7,124,9,23,0,124,6,107,6,144,1,114,54,116,15,124, + 12,131,1,144,1,114,54,124,0,160,16,124,10,124,1,124, + 12,100,8,124,2,161,5,2,0,1,0,83,0,113,224,124, + 3,144,1,114,98,116,18,160,19,100,9,124,8,161,2,1, + 0,116,18,160,20,124,1,100,8,161,2,125,13,124,8,103, + 1,124,13,95,21,124,13,83,0,100,8,83,0,41,10,122, + 111,84,114,121,32,116,111,32,102,105,110,100,32,97,32,115, + 112,101,99,32,102,111,114,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,46,10,10,32, + 32,32,32,32,32,32,32,82,101,116,117,114,110,115,32,116, + 104,101,32,109,97,116,99,104,105,110,103,32,115,112,101,99, + 44,32,111,114,32,78,111,110,101,32,105,102,32,110,111,116, + 32,102,111,117,110,100,46,10,32,32,32,32,32,32,32,32, + 70,114,71,0,0,0,114,28,0,0,0,114,105,0,0,0, + 114,209,0,0,0,122,9,116,114,121,105,110,103,32,123,125, + 41,1,90,9,118,101,114,98,111,115,105,116,121,78,122,25, + 112,111,115,115,105,98,108,101,32,110,97,109,101,115,112,97, + 99,101,32,102,111,114,32,123,125,41,22,114,41,0,0,0, + 114,49,0,0,0,114,44,0,0,0,114,2,0,0,0,114, + 55,0,0,0,114,9,1,0,0,114,50,0,0,0,114,62, + 1,0,0,218,11,95,102,105,108,108,95,99,97,99,104,101, + 114,7,0,0,0,114,65,1,0,0,114,106,0,0,0,114, + 64,1,0,0,114,38,0,0,0,114,61,1,0,0,114,54, + 0,0,0,114,58,1,0,0,114,56,0,0,0,114,134,0, + 0,0,114,149,0,0,0,114,183,0,0,0,114,178,0,0, + 0,41,14,114,119,0,0,0,114,139,0,0,0,114,202,0, + 0,0,90,12,105,115,95,110,97,109,101,115,112,97,99,101, + 90,11,116,97,105,108,95,109,111,100,117,108,101,114,169,0, + 0,0,90,5,99,97,99,104,101,90,12,99,97,99,104,101, + 95,109,111,100,117,108,101,90,9,98,97,115,101,95,112,97, + 116,104,114,17,1,0,0,114,188,0,0,0,90,13,105,110, + 105,116,95,102,105,108,101,110,97,109,101,90,9,102,117,108, + 108,95,112,97,116,104,114,187,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,203,0,0,0,129, + 5,0,0,115,74,0,0,0,0,5,4,1,14,1,2,1, + 24,1,14,1,10,1,10,1,8,1,6,2,6,1,6,1, + 10,2,6,1,4,2,8,1,12,1,14,1,8,1,10,1, + 8,1,26,4,8,2,14,1,16,1,16,1,14,1,10,1, + 10,1,2,0,2,255,10,2,6,1,12,1,12,1,8,1, + 4,1,122,20,70,105,108,101,70,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,99,1,0,0,0,0,0,0, + 0,0,0,0,0,9,0,0,0,10,0,0,0,67,0,0, + 0,115,190,0,0,0,124,0,106,0,125,1,122,22,116,1, + 160,2,124,1,112,22,116,1,160,3,161,0,161,1,125,2, + 87,0,110,30,4,0,116,4,116,5,116,6,102,3,107,10, + 114,58,1,0,1,0,1,0,103,0,125,2,89,0,110,2, + 88,0,116,7,106,8,160,9,100,1,161,1,115,84,116,10, + 124,2,131,1,124,0,95,11,110,74,116,10,131,0,125,3, + 124,2,68,0,93,56,125,4,124,4,160,12,100,2,161,1, + 92,3,125,5,125,6,125,7,124,6,114,136,100,3,160,13, + 124,5,124,7,160,14,161,0,161,2,125,8,110,4,124,5, + 125,8,124,3,160,15,124,8,161,1,1,0,113,94,124,3, + 124,0,95,11,116,7,106,8,160,9,116,16,161,1,114,186, + 100,4,100,5,132,0,124,2,68,0,131,1,124,0,95,17, + 100,6,83,0,41,7,122,68,70,105,108,108,32,116,104,101, + 32,99,97,99,104,101,32,111,102,32,112,111,116,101,110,116, + 105,97,108,32,109,111,100,117,108,101,115,32,97,110,100,32, + 112,97,99,107,97,103,101,115,32,102,111,114,32,116,104,105, + 115,32,100,105,114,101,99,116,111,114,121,46,114,0,0,0, + 0,114,71,0,0,0,114,61,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, + 83,0,0,0,115,20,0,0,0,104,0,124,0,93,12,125, + 1,124,1,160,0,161,0,146,2,113,4,83,0,114,3,0, + 0,0,41,1,114,106,0,0,0,41,2,114,32,0,0,0, + 90,2,102,110,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,9,60,115,101,116,99,111,109,112,62,206,5, + 0,0,115,4,0,0,0,6,0,2,0,122,41,70,105,108, + 101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,97, + 99,104,101,46,60,108,111,99,97,108,115,62,46,60,115,101, + 116,99,111,109,112,62,78,41,18,114,44,0,0,0,114,2, + 0,0,0,114,6,1,0,0,114,55,0,0,0,114,2,1, + 0,0,218,15,80,101,114,109,105,115,115,105,111,110,69,114, + 114,111,114,218,18,78,111,116,65,68,105,114,101,99,116,111, + 114,121,69,114,114,111,114,114,8,0,0,0,114,9,0,0, + 0,114,10,0,0,0,114,63,1,0,0,114,64,1,0,0, + 114,101,0,0,0,114,62,0,0,0,114,106,0,0,0,218, + 3,97,100,100,114,11,0,0,0,114,65,1,0,0,41,9, + 114,119,0,0,0,114,44,0,0,0,114,7,1,0,0,90, + 21,108,111,119,101,114,95,115,117,102,102,105,120,95,99,111, + 110,116,101,110,116,115,114,41,1,0,0,114,117,0,0,0, + 114,29,1,0,0,114,17,1,0,0,90,8,110,101,119,95, + 110,97,109,101,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,67,1,0,0,177,5,0,0,115,34,0,0, + 0,0,2,6,1,2,1,22,1,20,3,10,3,12,1,12, + 7,6,1,8,1,16,1,4,1,18,2,4,1,12,1,6, + 1,12,1,122,22,70,105,108,101,70,105,110,100,101,114,46, + 95,102,105,108,108,95,99,97,99,104,101,99,1,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, 7,0,0,0,115,18,0,0,0,135,0,135,1,102,2,100, 1,100,2,132,8,125,2,124,2,83,0,41,3,97,20,1, 0,0,65,32,99,108,97,115,115,32,109,101,116,104,111,100, @@ -2433,70 +2463,71 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 32,97,32,100,105,114,101,99,116,111,114,121,44,32,73,109, 112,111,114,116,69,114,114,111,114,32,105,115,10,32,32,32, 32,32,32,32,32,114,97,105,115,101,100,46,10,10,32,32, - 32,32,32,32,32,32,99,1,0,0,0,0,0,0,0,1, - 0,0,0,4,0,0,0,19,0,0,0,115,34,0,0,0, - 116,0,124,0,131,1,115,20,116,1,100,1,124,0,100,2, - 141,2,130,1,136,0,124,0,102,1,136,1,158,2,142,0, - 83,0,41,3,122,45,80,97,116,104,32,104,111,111,107,32, - 102,111,114,32,105,109,112,111,114,116,108,105,98,46,109,97, - 99,104,105,110,101,114,121,46,70,105,108,101,70,105,110,100, - 101,114,46,122,30,111,110,108,121,32,100,105,114,101,99,116, - 111,114,105,101,115,32,97,114,101,32,115,117,112,112,111,114, - 116,101,100,114,48,0,0,0,41,2,114,56,0,0,0,114, - 118,0,0,0,114,48,0,0,0,169,2,114,193,0,0,0, - 114,66,1,0,0,114,3,0,0,0,114,6,0,0,0,218, - 24,112,97,116,104,95,104,111,111,107,95,102,111,114,95,70, - 105,108,101,70,105,110,100,101,114,217,5,0,0,115,6,0, - 0,0,0,2,8,1,12,1,122,54,70,105,108,101,70,105, - 110,100,101,114,46,112,97,116,104,95,104,111,111,107,46,60, - 108,111,99,97,108,115,62,46,112,97,116,104,95,104,111,111, - 107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,114, - 114,3,0,0,0,41,3,114,193,0,0,0,114,66,1,0, - 0,114,73,1,0,0,114,3,0,0,0,114,72,1,0,0, - 114,6,0,0,0,218,9,112,97,116,104,95,104,111,111,107, - 207,5,0,0,115,4,0,0,0,0,10,14,6,122,20,70, - 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, - 111,111,107,99,1,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,115,12,0,0,0,100,1,160, - 0,124,0,106,1,161,1,83,0,41,2,78,122,16,70,105, - 108,101,70,105,110,100,101,114,40,123,33,114,125,41,41,2, - 114,62,0,0,0,114,44,0,0,0,114,246,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,39, - 1,0,0,225,5,0,0,115,2,0,0,0,0,1,122,19, - 70,105,108,101,70,105,110,100,101,114,46,95,95,114,101,112, - 114,95,95,41,1,78,41,15,114,125,0,0,0,114,124,0, - 0,0,114,126,0,0,0,114,127,0,0,0,114,209,0,0, - 0,114,46,1,0,0,114,143,0,0,0,114,206,0,0,0, - 114,137,0,0,0,114,58,1,0,0,114,203,0,0,0,114, - 67,1,0,0,114,207,0,0,0,114,74,1,0,0,114,39, - 1,0,0,114,3,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,59,1,0,0,82,5,0,0, - 115,22,0,0,0,8,2,4,7,8,14,8,4,4,2,8, - 12,8,5,10,48,8,31,2,1,10,17,114,59,1,0,0, - 99,4,0,0,0,0,0,0,0,6,0,0,0,8,0,0, - 0,67,0,0,0,115,146,0,0,0,124,0,160,0,100,1, - 161,1,125,4,124,0,160,0,100,2,161,1,125,5,124,4, - 115,66,124,5,114,36,124,5,106,1,125,4,110,30,124,2, - 124,3,107,2,114,56,116,2,124,1,124,2,131,2,125,4, - 110,10,116,3,124,1,124,2,131,2,125,4,124,5,115,84, - 116,4,124,1,124,2,124,4,100,3,141,3,125,5,122,36, - 124,5,124,0,100,2,60,0,124,4,124,0,100,1,60,0, - 124,2,124,0,100,4,60,0,124,3,124,0,100,5,60,0, - 87,0,110,20,4,0,116,5,107,10,114,140,1,0,1,0, - 1,0,89,0,110,2,88,0,100,0,83,0,41,6,78,218, - 10,95,95,108,111,97,100,101,114,95,95,218,8,95,95,115, - 112,101,99,95,95,114,60,1,0,0,90,8,95,95,102,105, - 108,101,95,95,90,10,95,95,99,97,99,104,101,100,95,95, - 41,6,218,3,103,101,116,114,140,0,0,0,114,14,1,0, - 0,114,8,1,0,0,114,190,0,0,0,218,9,69,120,99, - 101,112,116,105,111,110,41,6,90,2,110,115,114,117,0,0, - 0,90,8,112,97,116,104,110,97,109,101,90,9,99,112,97, - 116,104,110,97,109,101,114,140,0,0,0,114,187,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,231, - 5,0,0,115,34,0,0,0,0,2,10,1,10,1,4,1, - 4,1,8,1,8,1,12,2,10,1,4,1,14,1,2,1, - 8,1,8,1,8,1,12,1,14,2,114,79,1,0,0,99, + 32,32,32,32,32,32,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,4,0,0,0,19,0,0,0,115, + 34,0,0,0,116,0,124,0,131,1,115,20,116,1,100,1, + 124,0,100,2,141,2,130,1,136,0,124,0,102,1,136,1, + 158,2,142,0,83,0,41,3,122,45,80,97,116,104,32,104, + 111,111,107,32,102,111,114,32,105,109,112,111,114,116,108,105, + 98,46,109,97,99,104,105,110,101,114,121,46,70,105,108,101, + 70,105,110,100,101,114,46,122,30,111,110,108,121,32,100,105, + 114,101,99,116,111,114,105,101,115,32,97,114,101,32,115,117, + 112,112,111,114,116,101,100,114,48,0,0,0,41,2,114,56, + 0,0,0,114,118,0,0,0,114,48,0,0,0,169,2,114, + 193,0,0,0,114,66,1,0,0,114,3,0,0,0,114,6, + 0,0,0,218,24,112,97,116,104,95,104,111,111,107,95,102, + 111,114,95,70,105,108,101,70,105,110,100,101,114,218,5,0, + 0,115,6,0,0,0,0,2,8,1,12,1,122,54,70,105, + 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, + 111,107,46,60,108,111,99,97,108,115,62,46,112,97,116,104, + 95,104,111,111,107,95,102,111,114,95,70,105,108,101,70,105, + 110,100,101,114,114,3,0,0,0,41,3,114,193,0,0,0, + 114,66,1,0,0,114,73,1,0,0,114,3,0,0,0,114, + 72,1,0,0,114,6,0,0,0,218,9,112,97,116,104,95, + 104,111,111,107,208,5,0,0,115,4,0,0,0,0,10,14, + 6,122,20,70,105,108,101,70,105,110,100,101,114,46,112,97, + 116,104,95,104,111,111,107,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,12,0,0,0,100,1,160,0,124,0,106,1,161,1,83, + 0,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, + 40,123,33,114,125,41,41,2,114,62,0,0,0,114,44,0, + 0,0,114,246,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,39,1,0,0,226,5,0,0,115, + 2,0,0,0,0,1,122,19,70,105,108,101,70,105,110,100, + 101,114,46,95,95,114,101,112,114,95,95,41,1,78,41,15, + 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, + 127,0,0,0,114,209,0,0,0,114,46,1,0,0,114,143, + 0,0,0,114,206,0,0,0,114,137,0,0,0,114,58,1, + 0,0,114,203,0,0,0,114,67,1,0,0,114,207,0,0, + 0,114,74,1,0,0,114,39,1,0,0,114,3,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 59,1,0,0,83,5,0,0,115,22,0,0,0,8,2,4, + 7,8,14,8,4,4,2,8,12,8,5,10,48,8,31,2, + 1,10,17,114,59,1,0,0,99,4,0,0,0,0,0,0, + 0,0,0,0,0,6,0,0,0,8,0,0,0,67,0,0, + 0,115,146,0,0,0,124,0,160,0,100,1,161,1,125,4, + 124,0,160,0,100,2,161,1,125,5,124,4,115,66,124,5, + 114,36,124,5,106,1,125,4,110,30,124,2,124,3,107,2, + 114,56,116,2,124,1,124,2,131,2,125,4,110,10,116,3, + 124,1,124,2,131,2,125,4,124,5,115,84,116,4,124,1, + 124,2,124,4,100,3,141,3,125,5,122,36,124,5,124,0, + 100,2,60,0,124,4,124,0,100,1,60,0,124,2,124,0, + 100,4,60,0,124,3,124,0,100,5,60,0,87,0,110,20, + 4,0,116,5,107,10,114,140,1,0,1,0,1,0,89,0, + 110,2,88,0,100,0,83,0,41,6,78,218,10,95,95,108, + 111,97,100,101,114,95,95,218,8,95,95,115,112,101,99,95, + 95,114,60,1,0,0,90,8,95,95,102,105,108,101,95,95, + 90,10,95,95,99,97,99,104,101,100,95,95,41,6,218,3, + 103,101,116,114,140,0,0,0,114,14,1,0,0,114,8,1, + 0,0,114,190,0,0,0,218,9,69,120,99,101,112,116,105, + 111,110,41,6,90,2,110,115,114,117,0,0,0,90,8,112, + 97,116,104,110,97,109,101,90,9,99,112,97,116,104,110,97, + 109,101,114,140,0,0,0,114,187,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,14,95,102,105, + 120,95,117,112,95,109,111,100,117,108,101,232,5,0,0,115, + 34,0,0,0,0,2,10,1,10,1,4,1,4,1,8,1, + 8,1,12,2,10,1,4,1,14,1,2,1,8,1,8,1, + 8,1,12,1,14,2,114,79,1,0,0,99,0,0,0,0, 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, 67,0,0,0,115,38,0,0,0,116,0,116,1,160,2,161, 0,102,2,125,0,116,3,116,4,102,2,125,1,116,5,116, @@ -2513,101 +2544,102 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,114,89,0,0,0,41,3,90,10,101,120,116,101,110,115, 105,111,110,115,90,6,115,111,117,114,99,101,90,8,98,121, 116,101,99,111,100,101,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,184,0,0,0,254,5,0,0,115,8, + 114,6,0,0,0,114,184,0,0,0,255,5,0,0,115,8, 0,0,0,0,5,12,1,8,1,8,1,114,184,0,0,0, - 99,1,0,0,0,0,0,0,0,12,0,0,0,9,0,0, - 0,67,0,0,0,115,178,1,0,0,124,0,97,0,116,0, - 106,1,97,1,116,0,106,2,97,2,116,1,106,3,116,4, - 25,0,125,1,100,1,68,0,93,48,125,2,124,2,116,1, - 106,3,107,7,114,56,116,0,160,5,124,2,161,1,125,3, - 110,10,116,1,106,3,124,2,25,0,125,3,116,6,124,1, - 124,2,124,3,131,3,1,0,113,30,100,2,100,3,103,1, - 102,2,100,4,100,5,100,3,103,2,102,2,102,2,125,4, - 124,4,68,0,93,110,92,2,125,5,125,6,116,7,100,6, - 100,7,132,0,124,6,68,0,131,1,131,1,115,136,116,8, - 130,1,124,6,100,8,25,0,125,7,124,5,116,1,106,3, - 107,6,114,170,116,1,106,3,124,5,25,0,125,8,1,0, - 113,226,113,106,122,20,116,0,160,5,124,5,161,1,125,8, - 87,0,1,0,113,226,87,0,113,106,4,0,116,9,107,10, - 114,214,1,0,1,0,1,0,89,0,113,106,89,0,113,106, - 88,0,113,106,116,9,100,9,131,1,130,1,116,6,124,1, - 100,10,124,8,131,3,1,0,116,6,124,1,100,11,124,7, - 131,3,1,0,116,6,124,1,100,12,100,13,160,10,124,6, - 161,1,131,3,1,0,116,6,124,1,100,14,100,15,100,16, - 132,0,124,6,68,0,131,1,131,3,1,0,116,0,160,5, - 100,17,161,1,125,9,116,6,124,1,100,17,124,9,131,3, - 1,0,116,0,160,5,100,18,161,1,125,10,116,6,124,1, - 100,18,124,10,131,3,1,0,124,5,100,4,107,2,144,1, - 114,110,116,0,160,5,100,19,161,1,125,11,116,6,124,1, - 100,20,124,11,131,3,1,0,116,6,124,1,100,21,116,11, - 131,0,131,3,1,0,116,12,160,13,116,2,160,14,161,0, - 161,1,1,0,124,5,100,4,107,2,144,1,114,174,116,15, - 160,16,100,22,161,1,1,0,100,23,116,12,107,6,144,1, - 114,174,100,24,116,17,95,18,100,25,83,0,41,26,122,205, - 83,101,116,117,112,32,116,104,101,32,112,97,116,104,45,98, - 97,115,101,100,32,105,109,112,111,114,116,101,114,115,32,102, - 111,114,32,105,109,112,111,114,116,108,105,98,32,98,121,32, - 105,109,112,111,114,116,105,110,103,32,110,101,101,100,101,100, - 10,32,32,32,32,98,117,105,108,116,45,105,110,32,109,111, - 100,117,108,101,115,32,97,110,100,32,105,110,106,101,99,116, - 105,110,103,32,116,104,101,109,32,105,110,116,111,32,116,104, - 101,32,103,108,111,98,97,108,32,110,97,109,101,115,112,97, - 99,101,46,10,10,32,32,32,32,79,116,104,101,114,32,99, - 111,109,112,111,110,101,110,116,115,32,97,114,101,32,101,120, - 116,114,97,99,116,101,100,32,102,114,111,109,32,116,104,101, - 32,99,111,114,101,32,98,111,111,116,115,116,114,97,112,32, - 109,111,100,117,108,101,46,10,10,32,32,32,32,41,4,114, - 64,0,0,0,114,75,0,0,0,218,8,98,117,105,108,116, - 105,110,115,114,160,0,0,0,90,5,112,111,115,105,120,250, - 1,47,90,2,110,116,250,1,92,99,1,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,115,0,0,0,115,26, - 0,0,0,124,0,93,18,125,1,116,0,124,1,131,1,100, - 0,107,2,86,0,1,0,113,2,100,1,83,0,41,2,114, - 39,0,0,0,78,41,1,114,22,0,0,0,41,2,114,32, - 0,0,0,114,95,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,19,1,0,0,34,6,0,0, - 115,4,0,0,0,4,0,2,0,122,25,95,115,101,116,117, - 112,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, - 120,112,114,62,114,73,0,0,0,122,30,105,109,112,111,114, - 116,108,105,98,32,114,101,113,117,105,114,101,115,32,112,111, - 115,105,120,32,111,114,32,110,116,114,2,0,0,0,114,35, - 0,0,0,114,31,0,0,0,114,40,0,0,0,114,58,0, - 0,0,99,1,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,83,0,0,0,115,22,0,0,0,104,0,124,0, - 93,14,125,1,100,0,124,1,155,0,157,2,146,2,113,4, - 83,0,41,1,114,74,0,0,0,114,3,0,0,0,41,2, - 114,32,0,0,0,218,1,115,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,68,1,0,0,50,6,0,0, - 115,4,0,0,0,6,0,2,0,122,25,95,115,101,116,117, - 112,46,60,108,111,99,97,108,115,62,46,60,115,101,116,99, - 111,109,112,62,90,7,95,116,104,114,101,97,100,90,8,95, - 119,101,97,107,114,101,102,90,6,119,105,110,114,101,103,114, - 192,0,0,0,114,7,0,0,0,122,4,46,112,121,119,122, - 6,95,100,46,112,121,100,84,78,41,19,114,134,0,0,0, - 114,8,0,0,0,114,163,0,0,0,114,31,1,0,0,114, - 125,0,0,0,90,18,95,98,117,105,108,116,105,110,95,102, - 114,111,109,95,110,97,109,101,114,129,0,0,0,218,3,97, - 108,108,114,23,0,0,0,114,118,0,0,0,114,36,0,0, - 0,114,13,0,0,0,114,21,1,0,0,114,167,0,0,0, - 114,80,1,0,0,114,102,0,0,0,114,186,0,0,0,114, - 191,0,0,0,114,195,0,0,0,41,12,218,17,95,98,111, - 111,116,115,116,114,97,112,95,109,111,100,117,108,101,90,11, - 115,101,108,102,95,109,111,100,117,108,101,90,12,98,117,105, - 108,116,105,110,95,110,97,109,101,90,14,98,117,105,108,116, - 105,110,95,109,111,100,117,108,101,90,10,111,115,95,100,101, - 116,97,105,108,115,90,10,98,117,105,108,116,105,110,95,111, - 115,114,31,0,0,0,114,35,0,0,0,90,9,111,115,95, - 109,111,100,117,108,101,90,13,116,104,114,101,97,100,95,109, - 111,100,117,108,101,90,14,119,101,97,107,114,101,102,95,109, - 111,100,117,108,101,90,13,119,105,110,114,101,103,95,109,111, - 100,117,108,101,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,6,95,115,101,116,117,112,9,6,0,0,115, - 78,0,0,0,0,8,4,1,6,1,6,3,10,1,8,1, - 10,1,12,2,10,1,14,3,22,1,12,2,22,1,8,1, - 10,1,10,1,6,2,2,1,10,1,10,1,14,1,12,2, - 8,1,12,1,12,1,18,1,22,3,10,1,12,3,10,1, - 12,3,10,1,10,1,12,3,14,1,14,1,10,1,10,1, - 10,1,114,87,1,0,0,99,1,0,0,0,0,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,12,0,0, + 0,9,0,0,0,67,0,0,0,115,178,1,0,0,124,0, + 97,0,116,0,106,1,97,1,116,0,106,2,97,2,116,1, + 106,3,116,4,25,0,125,1,100,1,68,0,93,48,125,2, + 124,2,116,1,106,3,107,7,114,56,116,0,160,5,124,2, + 161,1,125,3,110,10,116,1,106,3,124,2,25,0,125,3, + 116,6,124,1,124,2,124,3,131,3,1,0,113,30,100,2, + 100,3,103,1,102,2,100,4,100,5,100,3,103,2,102,2, + 102,2,125,4,124,4,68,0,93,110,92,2,125,5,125,6, + 116,7,100,6,100,7,132,0,124,6,68,0,131,1,131,1, + 115,136,116,8,130,1,124,6,100,8,25,0,125,7,124,5, + 116,1,106,3,107,6,114,170,116,1,106,3,124,5,25,0, + 125,8,1,0,113,226,113,106,122,20,116,0,160,5,124,5, + 161,1,125,8,87,0,1,0,113,226,87,0,113,106,4,0, + 116,9,107,10,114,214,1,0,1,0,1,0,89,0,113,106, + 89,0,113,106,88,0,113,106,116,9,100,9,131,1,130,1, + 116,6,124,1,100,10,124,8,131,3,1,0,116,6,124,1, + 100,11,124,7,131,3,1,0,116,6,124,1,100,12,100,13, + 160,10,124,6,161,1,131,3,1,0,116,6,124,1,100,14, + 100,15,100,16,132,0,124,6,68,0,131,1,131,3,1,0, + 116,0,160,5,100,17,161,1,125,9,116,6,124,1,100,17, + 124,9,131,3,1,0,116,0,160,5,100,18,161,1,125,10, + 116,6,124,1,100,18,124,10,131,3,1,0,124,5,100,4, + 107,2,144,1,114,110,116,0,160,5,100,19,161,1,125,11, + 116,6,124,1,100,20,124,11,131,3,1,0,116,6,124,1, + 100,21,116,11,131,0,131,3,1,0,116,12,160,13,116,2, + 160,14,161,0,161,1,1,0,124,5,100,4,107,2,144,1, + 114,174,116,15,160,16,100,22,161,1,1,0,100,23,116,12, + 107,6,144,1,114,174,100,24,116,17,95,18,100,25,83,0, + 41,26,122,205,83,101,116,117,112,32,116,104,101,32,112,97, + 116,104,45,98,97,115,101,100,32,105,109,112,111,114,116,101, + 114,115,32,102,111,114,32,105,109,112,111,114,116,108,105,98, + 32,98,121,32,105,109,112,111,114,116,105,110,103,32,110,101, + 101,100,101,100,10,32,32,32,32,98,117,105,108,116,45,105, + 110,32,109,111,100,117,108,101,115,32,97,110,100,32,105,110, + 106,101,99,116,105,110,103,32,116,104,101,109,32,105,110,116, + 111,32,116,104,101,32,103,108,111,98,97,108,32,110,97,109, + 101,115,112,97,99,101,46,10,10,32,32,32,32,79,116,104, + 101,114,32,99,111,109,112,111,110,101,110,116,115,32,97,114, + 101,32,101,120,116,114,97,99,116,101,100,32,102,114,111,109, + 32,116,104,101,32,99,111,114,101,32,98,111,111,116,115,116, + 114,97,112,32,109,111,100,117,108,101,46,10,10,32,32,32, + 32,41,4,114,64,0,0,0,114,75,0,0,0,218,8,98, + 117,105,108,116,105,110,115,114,160,0,0,0,90,5,112,111, + 115,105,120,250,1,47,90,2,110,116,250,1,92,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,115,0,0,0,115,26,0,0,0,124,0,93,18,125, + 1,116,0,124,1,131,1,100,0,107,2,86,0,1,0,113, + 2,100,1,83,0,41,2,114,39,0,0,0,78,41,1,114, + 22,0,0,0,41,2,114,32,0,0,0,114,95,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 19,1,0,0,35,6,0,0,115,4,0,0,0,4,0,2, + 0,122,25,95,115,101,116,117,112,46,60,108,111,99,97,108, + 115,62,46,60,103,101,110,101,120,112,114,62,114,73,0,0, + 0,122,30,105,109,112,111,114,116,108,105,98,32,114,101,113, + 117,105,114,101,115,32,112,111,115,105,120,32,111,114,32,110, + 116,114,2,0,0,0,114,35,0,0,0,114,31,0,0,0, + 114,40,0,0,0,114,58,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,83, + 0,0,0,115,22,0,0,0,104,0,124,0,93,14,125,1, + 100,0,124,1,155,0,157,2,146,2,113,4,83,0,41,1, + 114,74,0,0,0,114,3,0,0,0,41,2,114,32,0,0, + 0,218,1,115,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,68,1,0,0,51,6,0,0,115,4,0,0, + 0,6,0,2,0,122,25,95,115,101,116,117,112,46,60,108, + 111,99,97,108,115,62,46,60,115,101,116,99,111,109,112,62, + 90,7,95,116,104,114,101,97,100,90,8,95,119,101,97,107, + 114,101,102,90,6,119,105,110,114,101,103,114,192,0,0,0, + 114,7,0,0,0,122,4,46,112,121,119,122,6,95,100,46, + 112,121,100,84,78,41,19,114,134,0,0,0,114,8,0,0, + 0,114,163,0,0,0,114,31,1,0,0,114,125,0,0,0, + 90,18,95,98,117,105,108,116,105,110,95,102,114,111,109,95, + 110,97,109,101,114,129,0,0,0,218,3,97,108,108,114,23, + 0,0,0,114,118,0,0,0,114,36,0,0,0,114,13,0, + 0,0,114,21,1,0,0,114,167,0,0,0,114,80,1,0, + 0,114,102,0,0,0,114,186,0,0,0,114,191,0,0,0, + 114,195,0,0,0,41,12,218,17,95,98,111,111,116,115,116, + 114,97,112,95,109,111,100,117,108,101,90,11,115,101,108,102, + 95,109,111,100,117,108,101,90,12,98,117,105,108,116,105,110, + 95,110,97,109,101,90,14,98,117,105,108,116,105,110,95,109, + 111,100,117,108,101,90,10,111,115,95,100,101,116,97,105,108, + 115,90,10,98,117,105,108,116,105,110,95,111,115,114,31,0, + 0,0,114,35,0,0,0,90,9,111,115,95,109,111,100,117, + 108,101,90,13,116,104,114,101,97,100,95,109,111,100,117,108, + 101,90,14,119,101,97,107,114,101,102,95,109,111,100,117,108, + 101,90,13,119,105,110,114,101,103,95,109,111,100,117,108,101, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 6,95,115,101,116,117,112,10,6,0,0,115,78,0,0,0, + 0,8,4,1,6,1,6,3,10,1,8,1,10,1,12,2, + 10,1,14,3,22,1,12,2,22,1,8,1,10,1,10,1, + 6,2,2,1,10,1,10,1,14,1,12,2,8,1,12,1, + 12,1,18,1,22,3,10,1,12,3,10,1,12,3,10,1, + 10,1,12,3,14,1,14,1,10,1,10,1,10,1,114,87, + 1,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, 2,0,0,0,4,0,0,0,67,0,0,0,115,50,0,0, 0,116,0,124,0,131,1,1,0,116,1,131,0,125,1,116, 2,106,3,160,4,116,5,106,6,124,1,142,0,103,1,161, @@ -2621,7 +2653,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 104,114,186,0,0,0,114,45,1,0,0,41,2,114,86,1, 0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,111, 97,100,101,114,115,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,8,95,105,110,115,116,97,108,108,74,6, + 6,0,0,0,218,8,95,105,110,115,116,97,108,108,75,6, 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, 89,1,0,0,41,63,114,127,0,0,0,114,12,0,0,0, 90,37,95,67,65,83,69,95,73,78,83,69,78,83,73,84, @@ -2653,7 +2685,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 111,100,117,108,101,62,1,0,0,0,115,126,0,0,0,4, 22,4,1,4,1,2,1,2,255,4,4,8,17,8,5,8, 5,8,6,8,6,8,12,8,10,8,9,8,5,8,7,8, - 9,12,22,10,127,0,7,16,1,12,2,4,1,4,2,6, + 9,12,22,10,127,0,8,16,1,12,2,4,1,4,2,6, 2,6,2,8,2,18,71,8,40,8,19,8,12,8,12,8, 28,8,17,8,33,8,28,8,24,16,13,14,10,12,11,8, 14,6,3,6,1,2,255,12,68,14,64,14,29,16,127,0, diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index 299d1c5653b..b7968944993 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -1,121 +1,122 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__zipimport[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,82,1,0,0,100,0,90,0,100,1, - 100,2,108,1,90,2,100,1,100,3,108,1,109,3,90,3, - 109,4,90,4,1,0,100,1,100,2,108,5,90,6,100,1, - 100,2,108,7,90,7,100,1,100,2,108,8,90,8,100,1, - 100,2,108,9,90,9,100,1,100,2,108,10,90,10,100,1, - 100,2,108,11,90,11,100,4,100,5,103,2,90,12,101,2, - 106,13,90,13,101,2,106,14,100,6,100,2,133,2,25,0, - 90,15,71,0,100,7,100,4,132,0,100,4,101,16,131,3, - 90,17,105,0,90,18,101,19,101,10,131,1,90,20,100,8, - 90,21,100,9,90,22,100,10,90,23,71,0,100,11,100,5, - 132,0,100,5,131,2,90,24,101,13,100,12,23,0,100,13, - 100,13,102,3,101,13,100,14,23,0,100,15,100,13,102,3, - 100,16,100,17,102,4,90,25,100,18,100,19,132,0,90,26, - 100,20,100,21,132,0,90,27,100,22,100,23,132,0,90,28, - 100,24,100,25,132,0,90,29,100,26,90,30,100,15,97,31, - 100,27,100,28,132,0,90,32,100,29,100,30,132,0,90,33, - 100,31,100,32,132,0,90,34,100,33,100,34,132,0,90,35, - 101,19,101,35,106,36,131,1,90,37,100,35,100,36,132,0, - 90,38,100,37,100,38,132,0,90,39,100,39,100,40,132,0, - 90,40,100,41,100,42,132,0,90,41,100,43,100,44,132,0, - 90,42,100,45,100,46,132,0,90,43,71,0,100,47,100,48, - 132,0,100,48,131,2,90,44,100,2,83,0,41,49,97,80, - 2,0,0,122,105,112,105,109,112,111,114,116,32,112,114,111, - 118,105,100,101,115,32,115,117,112,112,111,114,116,32,102,111, - 114,32,105,109,112,111,114,116,105,110,103,32,80,121,116,104, - 111,110,32,109,111,100,117,108,101,115,32,102,114,111,109,32, - 90,105,112,32,97,114,99,104,105,118,101,115,46,10,10,84, - 104,105,115,32,109,111,100,117,108,101,32,101,120,112,111,114, - 116,115,32,116,104,114,101,101,32,111,98,106,101,99,116,115, - 58,10,45,32,122,105,112,105,109,112,111,114,116,101,114,58, - 32,97,32,99,108,97,115,115,59,32,105,116,115,32,99,111, - 110,115,116,114,117,99,116,111,114,32,116,97,107,101,115,32, - 97,32,112,97,116,104,32,116,111,32,97,32,90,105,112,32, - 97,114,99,104,105,118,101,46,10,45,32,90,105,112,73,109, - 112,111,114,116,69,114,114,111,114,58,32,101,120,99,101,112, - 116,105,111,110,32,114,97,105,115,101,100,32,98,121,32,122, - 105,112,105,109,112,111,114,116,101,114,32,111,98,106,101,99, - 116,115,46,32,73,116,39,115,32,97,10,32,32,115,117,98, - 99,108,97,115,115,32,111,102,32,73,109,112,111,114,116,69, - 114,114,111,114,44,32,115,111,32,105,116,32,99,97,110,32, - 98,101,32,99,97,117,103,104,116,32,97,115,32,73,109,112, - 111,114,116,69,114,114,111,114,44,32,116,111,111,46,10,45, - 32,95,122,105,112,95,100,105,114,101,99,116,111,114,121,95, - 99,97,99,104,101,58,32,97,32,100,105,99,116,44,32,109, - 97,112,112,105,110,103,32,97,114,99,104,105,118,101,32,112, - 97,116,104,115,32,116,111,32,122,105,112,32,100,105,114,101, - 99,116,111,114,121,10,32,32,105,110,102,111,32,100,105,99, - 116,115,44,32,97,115,32,117,115,101,100,32,105,110,32,122, - 105,112,105,109,112,111,114,116,101,114,46,95,102,105,108,101, - 115,46,10,10,73,116,32,105,115,32,117,115,117,97,108,108, - 121,32,110,111,116,32,110,101,101,100,101,100,32,116,111,32, - 117,115,101,32,116,104,101,32,122,105,112,105,109,112,111,114, - 116,32,109,111,100,117,108,101,32,101,120,112,108,105,99,105, - 116,108,121,59,32,105,116,32,105,115,10,117,115,101,100,32, - 98,121,32,116,104,101,32,98,117,105,108,116,105,110,32,105, - 109,112,111,114,116,32,109,101,99,104,97,110,105,115,109,32, - 102,111,114,32,115,121,115,46,112,97,116,104,32,105,116,101, - 109,115,32,116,104,97,116,32,97,114,101,32,112,97,116,104, - 115,10,116,111,32,90,105,112,32,97,114,99,104,105,118,101, - 115,46,10,233,0,0,0,0,78,41,2,218,14,95,117,110, - 112,97,99,107,95,117,105,110,116,49,54,218,14,95,117,110, - 112,97,99,107,95,117,105,110,116,51,50,218,14,90,105,112, - 73,109,112,111,114,116,69,114,114,111,114,218,11,122,105,112, - 105,109,112,111,114,116,101,114,233,1,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0, - 0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100, - 1,83,0,41,2,114,3,0,0,0,78,41,3,218,8,95, - 95,110,97,109,101,95,95,218,10,95,95,109,111,100,117,108, - 101,95,95,218,12,95,95,113,117,97,108,110,97,109,101,95, - 95,169,0,114,9,0,0,0,114,9,0,0,0,250,18,60, - 102,114,111,122,101,110,32,122,105,112,105,109,112,111,114,116, - 62,114,3,0,0,0,33,0,0,0,115,2,0,0,0,8, - 1,233,22,0,0,0,115,4,0,0,0,80,75,5,6,105, - 255,255,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,64,0,0,0,115,108,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, - 90,4,100,25,100,5,100,6,132,1,90,5,100,26,100,7, - 100,8,132,1,90,6,100,9,100,10,132,0,90,7,100,11, - 100,12,132,0,90,8,100,13,100,14,132,0,90,9,100,15, - 100,16,132,0,90,10,100,17,100,18,132,0,90,11,100,19, - 100,20,132,0,90,12,100,21,100,22,132,0,90,13,100,23, - 100,24,132,0,90,14,100,4,83,0,41,27,114,4,0,0, - 0,97,255,1,0,0,122,105,112,105,109,112,111,114,116,101, - 114,40,97,114,99,104,105,118,101,112,97,116,104,41,32,45, - 62,32,122,105,112,105,109,112,111,114,116,101,114,32,111,98, - 106,101,99,116,10,10,32,32,32,32,67,114,101,97,116,101, - 32,97,32,110,101,119,32,122,105,112,105,109,112,111,114,116, - 101,114,32,105,110,115,116,97,110,99,101,46,32,39,97,114, - 99,104,105,118,101,112,97,116,104,39,32,109,117,115,116,32, - 98,101,32,97,32,112,97,116,104,32,116,111,10,32,32,32, - 32,97,32,122,105,112,102,105,108,101,44,32,111,114,32,116, - 111,32,97,32,115,112,101,99,105,102,105,99,32,112,97,116, - 104,32,105,110,115,105,100,101,32,97,32,122,105,112,102,105, - 108,101,46,32,70,111,114,32,101,120,97,109,112,108,101,44, - 32,105,116,32,99,97,110,32,98,101,10,32,32,32,32,39, - 47,116,109,112,47,109,121,105,109,112,111,114,116,46,122,105, - 112,39,44,32,111,114,32,39,47,116,109,112,47,109,121,105, - 109,112,111,114,116,46,122,105,112,47,109,121,100,105,114,101, - 99,116,111,114,121,39,44,32,105,102,32,109,121,100,105,114, - 101,99,116,111,114,121,32,105,115,32,97,10,32,32,32,32, - 118,97,108,105,100,32,100,105,114,101,99,116,111,114,121,32, - 105,110,115,105,100,101,32,116,104,101,32,97,114,99,104,105, - 118,101,46,10,10,32,32,32,32,39,90,105,112,73,109,112, - 111,114,116,69,114,114,111,114,32,105,115,32,114,97,105,115, - 101,100,32,105,102,32,39,97,114,99,104,105,118,101,112,97, - 116,104,39,32,100,111,101,115,110,39,116,32,112,111,105,110, - 116,32,116,111,32,97,32,118,97,108,105,100,32,90,105,112, - 10,32,32,32,32,97,114,99,104,105,118,101,46,10,10,32, - 32,32,32,84,104,101,32,39,97,114,99,104,105,118,101,39, - 32,97,116,116,114,105,98,117,116,101,32,111,102,32,122,105, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,64,0,0,0,115,82,1,0,0,100,0, + 90,0,100,1,100,2,108,1,90,2,100,1,100,3,108,1, + 109,3,90,3,109,4,90,4,1,0,100,1,100,2,108,5, + 90,6,100,1,100,2,108,7,90,7,100,1,100,2,108,8, + 90,8,100,1,100,2,108,9,90,9,100,1,100,2,108,10, + 90,10,100,1,100,2,108,11,90,11,100,4,100,5,103,2, + 90,12,101,2,106,13,90,13,101,2,106,14,100,6,100,2, + 133,2,25,0,90,15,71,0,100,7,100,4,132,0,100,4, + 101,16,131,3,90,17,105,0,90,18,101,19,101,10,131,1, + 90,20,100,8,90,21,100,9,90,22,100,10,90,23,71,0, + 100,11,100,5,132,0,100,5,131,2,90,24,101,13,100,12, + 23,0,100,13,100,13,102,3,101,13,100,14,23,0,100,15, + 100,13,102,3,100,16,100,17,102,4,90,25,100,18,100,19, + 132,0,90,26,100,20,100,21,132,0,90,27,100,22,100,23, + 132,0,90,28,100,24,100,25,132,0,90,29,100,26,90,30, + 100,15,97,31,100,27,100,28,132,0,90,32,100,29,100,30, + 132,0,90,33,100,31,100,32,132,0,90,34,100,33,100,34, + 132,0,90,35,101,19,101,35,106,36,131,1,90,37,100,35, + 100,36,132,0,90,38,100,37,100,38,132,0,90,39,100,39, + 100,40,132,0,90,40,100,41,100,42,132,0,90,41,100,43, + 100,44,132,0,90,42,100,45,100,46,132,0,90,43,71,0, + 100,47,100,48,132,0,100,48,131,2,90,44,100,2,83,0, + 41,49,97,80,2,0,0,122,105,112,105,109,112,111,114,116, + 32,112,114,111,118,105,100,101,115,32,115,117,112,112,111,114, + 116,32,102,111,114,32,105,109,112,111,114,116,105,110,103,32, + 80,121,116,104,111,110,32,109,111,100,117,108,101,115,32,102, + 114,111,109,32,90,105,112,32,97,114,99,104,105,118,101,115, + 46,10,10,84,104,105,115,32,109,111,100,117,108,101,32,101, + 120,112,111,114,116,115,32,116,104,114,101,101,32,111,98,106, + 101,99,116,115,58,10,45,32,122,105,112,105,109,112,111,114, + 116,101,114,58,32,97,32,99,108,97,115,115,59,32,105,116, + 115,32,99,111,110,115,116,114,117,99,116,111,114,32,116,97, + 107,101,115,32,97,32,112,97,116,104,32,116,111,32,97,32, + 90,105,112,32,97,114,99,104,105,118,101,46,10,45,32,90, + 105,112,73,109,112,111,114,116,69,114,114,111,114,58,32,101, + 120,99,101,112,116,105,111,110,32,114,97,105,115,101,100,32, + 98,121,32,122,105,112,105,109,112,111,114,116,101,114,32,111, + 98,106,101,99,116,115,46,32,73,116,39,115,32,97,10,32, + 32,115,117,98,99,108,97,115,115,32,111,102,32,73,109,112, + 111,114,116,69,114,114,111,114,44,32,115,111,32,105,116,32, + 99,97,110,32,98,101,32,99,97,117,103,104,116,32,97,115, + 32,73,109,112,111,114,116,69,114,114,111,114,44,32,116,111, + 111,46,10,45,32,95,122,105,112,95,100,105,114,101,99,116, + 111,114,121,95,99,97,99,104,101,58,32,97,32,100,105,99, + 116,44,32,109,97,112,112,105,110,103,32,97,114,99,104,105, + 118,101,32,112,97,116,104,115,32,116,111,32,122,105,112,32, + 100,105,114,101,99,116,111,114,121,10,32,32,105,110,102,111, + 32,100,105,99,116,115,44,32,97,115,32,117,115,101,100,32, + 105,110,32,122,105,112,105,109,112,111,114,116,101,114,46,95, + 102,105,108,101,115,46,10,10,73,116,32,105,115,32,117,115, + 117,97,108,108,121,32,110,111,116,32,110,101,101,100,101,100, + 32,116,111,32,117,115,101,32,116,104,101,32,122,105,112,105, + 109,112,111,114,116,32,109,111,100,117,108,101,32,101,120,112, + 108,105,99,105,116,108,121,59,32,105,116,32,105,115,10,117, + 115,101,100,32,98,121,32,116,104,101,32,98,117,105,108,116, + 105,110,32,105,109,112,111,114,116,32,109,101,99,104,97,110, + 105,115,109,32,102,111,114,32,115,121,115,46,112,97,116,104, + 32,105,116,101,109,115,32,116,104,97,116,32,97,114,101,32, + 112,97,116,104,115,10,116,111,32,90,105,112,32,97,114,99, + 104,105,118,101,115,46,10,233,0,0,0,0,78,41,2,218, + 14,95,117,110,112,97,99,107,95,117,105,110,116,49,54,218, + 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,218, + 14,90,105,112,73,109,112,111,114,116,69,114,114,111,114,218, + 11,122,105,112,105,109,112,111,114,116,101,114,233,1,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,64,0,0,0,115,12,0,0,0,101, + 0,90,1,100,0,90,2,100,1,83,0,41,2,114,3,0, + 0,0,78,41,3,218,8,95,95,110,97,109,101,95,95,218, + 10,95,95,109,111,100,117,108,101,95,95,218,12,95,95,113, + 117,97,108,110,97,109,101,95,95,169,0,114,9,0,0,0, + 114,9,0,0,0,250,18,60,102,114,111,122,101,110,32,122, + 105,112,105,109,112,111,114,116,62,114,3,0,0,0,33,0, + 0,0,115,2,0,0,0,8,1,233,22,0,0,0,115,4, + 0,0,0,80,75,5,6,105,255,255,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,64,0,0,0,115,108,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,25, + 100,5,100,6,132,1,90,5,100,26,100,7,100,8,132,1, + 90,6,100,9,100,10,132,0,90,7,100,11,100,12,132,0, + 90,8,100,13,100,14,132,0,90,9,100,15,100,16,132,0, + 90,10,100,17,100,18,132,0,90,11,100,19,100,20,132,0, + 90,12,100,21,100,22,132,0,90,13,100,23,100,24,132,0, + 90,14,100,4,83,0,41,27,114,4,0,0,0,97,255,1, + 0,0,122,105,112,105,109,112,111,114,116,101,114,40,97,114, + 99,104,105,118,101,112,97,116,104,41,32,45,62,32,122,105, 112,105,109,112,111,114,116,101,114,32,111,98,106,101,99,116, - 115,32,99,111,110,116,97,105,110,115,32,116,104,101,32,110, - 97,109,101,32,111,102,32,116,104,101,10,32,32,32,32,122, - 105,112,102,105,108,101,32,116,97,114,103,101,116,101,100,46, - 10,32,32,32,32,99,2,0,0,0,0,0,0,0,8,0, + 10,10,32,32,32,32,67,114,101,97,116,101,32,97,32,110, + 101,119,32,122,105,112,105,109,112,111,114,116,101,114,32,105, + 110,115,116,97,110,99,101,46,32,39,97,114,99,104,105,118, + 101,112,97,116,104,39,32,109,117,115,116,32,98,101,32,97, + 32,112,97,116,104,32,116,111,10,32,32,32,32,97,32,122, + 105,112,102,105,108,101,44,32,111,114,32,116,111,32,97,32, + 115,112,101,99,105,102,105,99,32,112,97,116,104,32,105,110, + 115,105,100,101,32,97,32,122,105,112,102,105,108,101,46,32, + 70,111,114,32,101,120,97,109,112,108,101,44,32,105,116,32, + 99,97,110,32,98,101,10,32,32,32,32,39,47,116,109,112, + 47,109,121,105,109,112,111,114,116,46,122,105,112,39,44,32, + 111,114,32,39,47,116,109,112,47,109,121,105,109,112,111,114, + 116,46,122,105,112,47,109,121,100,105,114,101,99,116,111,114, + 121,39,44,32,105,102,32,109,121,100,105,114,101,99,116,111, + 114,121,32,105,115,32,97,10,32,32,32,32,118,97,108,105, + 100,32,100,105,114,101,99,116,111,114,121,32,105,110,115,105, + 100,101,32,116,104,101,32,97,114,99,104,105,118,101,46,10, + 10,32,32,32,32,39,90,105,112,73,109,112,111,114,116,69, + 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, + 102,32,39,97,114,99,104,105,118,101,112,97,116,104,39,32, + 100,111,101,115,110,39,116,32,112,111,105,110,116,32,116,111, + 32,97,32,118,97,108,105,100,32,90,105,112,10,32,32,32, + 32,97,114,99,104,105,118,101,46,10,10,32,32,32,32,84, + 104,101,32,39,97,114,99,104,105,118,101,39,32,97,116,116, + 114,105,98,117,116,101,32,111,102,32,122,105,112,105,109,112, + 111,114,116,101,114,32,111,98,106,101,99,116,115,32,99,111, + 110,116,97,105,110,115,32,116,104,101,32,110,97,109,101,32, + 111,102,32,116,104,101,10,32,32,32,32,122,105,112,102,105, + 108,101,32,116,97,114,103,101,116,101,100,46,10,32,32,32, + 32,99,2,0,0,0,0,0,0,0,0,0,0,0,8,0, 0,0,9,0,0,0,67,0,0,0,115,36,1,0,0,116, 0,124,1,116,1,131,2,115,28,100,1,100,0,108,2,125, 2,124,2,160,3,124,1,161,1,125,1,124,1,115,44,116, @@ -165,61 +166,17 @@ const unsigned char _Py_M__zipimport[] = { 1,16,3,14,2,12,1,4,2,2,1,12,1,14,1,8, 1,14,1,6,1,6,2,22,1,8,1,122,20,122,105,112, 105,109,112,111,114,116,101,114,46,95,95,105,110,105,116,95, - 95,78,99,3,0,0,0,0,0,0,0,5,0,0,0,4, - 0,0,0,67,0,0,0,115,78,0,0,0,116,0,124,0, - 124,1,131,2,125,3,124,3,100,1,107,9,114,26,124,0, - 103,0,102,2,83,0,116,1,124,0,124,1,131,2,125,4, - 116,2,124,0,124,4,131,2,114,70,100,1,124,0,106,3, - 155,0,116,4,155,0,124,4,155,0,157,3,103,1,102,2, - 83,0,100,1,103,0,102,2,83,0,41,2,97,239,1,0, - 0,102,105,110,100,95,108,111,97,100,101,114,40,102,117,108, - 108,110,97,109,101,44,32,112,97,116,104,61,78,111,110,101, - 41,32,45,62,32,115,101,108,102,44,32,115,116,114,32,111, - 114,32,78,111,110,101,46,10,10,32,32,32,32,32,32,32, - 32,83,101,97,114,99,104,32,102,111,114,32,97,32,109,111, - 100,117,108,101,32,115,112,101,99,105,102,105,101,100,32,98, - 121,32,39,102,117,108,108,110,97,109,101,39,46,32,39,102, - 117,108,108,110,97,109,101,39,32,109,117,115,116,32,98,101, - 32,116,104,101,10,32,32,32,32,32,32,32,32,102,117,108, - 108,121,32,113,117,97,108,105,102,105,101,100,32,40,100,111, - 116,116,101,100,41,32,109,111,100,117,108,101,32,110,97,109, - 101,46,32,73,116,32,114,101,116,117,114,110,115,32,116,104, - 101,32,122,105,112,105,109,112,111,114,116,101,114,10,32,32, - 32,32,32,32,32,32,105,110,115,116,97,110,99,101,32,105, - 116,115,101,108,102,32,105,102,32,116,104,101,32,109,111,100, - 117,108,101,32,119,97,115,32,102,111,117,110,100,44,32,97, - 32,115,116,114,105,110,103,32,99,111,110,116,97,105,110,105, - 110,103,32,116,104,101,10,32,32,32,32,32,32,32,32,102, - 117,108,108,32,112,97,116,104,32,110,97,109,101,32,105,102, - 32,105,116,39,115,32,112,111,115,115,105,98,108,121,32,97, - 32,112,111,114,116,105,111,110,32,111,102,32,97,32,110,97, - 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,44, - 10,32,32,32,32,32,32,32,32,111,114,32,78,111,110,101, - 32,111,116,104,101,114,119,105,115,101,46,32,84,104,101,32, - 111,112,116,105,111,110,97,108,32,39,112,97,116,104,39,32, - 97,114,103,117,109,101,110,116,32,105,115,32,105,103,110,111, - 114,101,100,32,45,45,32,105,116,39,115,10,32,32,32,32, - 32,32,32,32,116,104,101,114,101,32,102,111,114,32,99,111, - 109,112,97,116,105,98,105,108,105,116,121,32,119,105,116,104, - 32,116,104,101,32,105,109,112,111,114,116,101,114,32,112,114, - 111,116,111,99,111,108,46,10,32,32,32,32,32,32,32,32, - 78,41,5,218,16,95,103,101,116,95,109,111,100,117,108,101, - 95,105,110,102,111,218,16,95,103,101,116,95,109,111,100,117, - 108,101,95,112,97,116,104,218,7,95,105,115,95,100,105,114, - 114,29,0,0,0,114,20,0,0,0,41,5,114,32,0,0, - 0,218,8,102,117,108,108,110,97,109,101,114,13,0,0,0, - 218,2,109,105,218,7,109,111,100,112,97,116,104,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,11,102,105, - 110,100,95,108,111,97,100,101,114,109,0,0,0,115,14,0, - 0,0,0,10,10,1,8,2,8,7,10,1,10,4,24,2, - 122,23,122,105,112,105,109,112,111,114,116,101,114,46,102,105, - 110,100,95,108,111,97,100,101,114,99,3,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,16, - 0,0,0,124,0,160,0,124,1,124,2,161,2,100,1,25, - 0,83,0,41,2,97,139,1,0,0,102,105,110,100,95,109, - 111,100,117,108,101,40,102,117,108,108,110,97,109,101,44,32, - 112,97,116,104,61,78,111,110,101,41,32,45,62,32,115,101, - 108,102,32,111,114,32,78,111,110,101,46,10,10,32,32,32, + 95,78,99,3,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,4,0,0,0,67,0,0,0,115,78,0,0,0, + 116,0,124,0,124,1,131,2,125,3,124,3,100,1,107,9, + 114,26,124,0,103,0,102,2,83,0,116,1,124,0,124,1, + 131,2,125,4,116,2,124,0,124,4,131,2,114,70,100,1, + 124,0,106,3,155,0,116,4,155,0,124,4,155,0,157,3, + 103,1,102,2,83,0,100,1,103,0,102,2,83,0,41,2, + 97,239,1,0,0,102,105,110,100,95,108,111,97,100,101,114, + 40,102,117,108,108,110,97,109,101,44,32,112,97,116,104,61, + 78,111,110,101,41,32,45,62,32,115,101,108,102,44,32,115, + 116,114,32,111,114,32,78,111,110,101,46,10,10,32,32,32, 32,32,32,32,32,83,101,97,114,99,104,32,102,111,114,32, 97,32,109,111,100,117,108,101,32,115,112,101,99,105,102,105, 101,100,32,98,121,32,39,102,117,108,108,110,97,109,101,39, @@ -232,42 +189,87 @@ const unsigned char _Py_M__zipimport[] = { 114,10,32,32,32,32,32,32,32,32,105,110,115,116,97,110, 99,101,32,105,116,115,101,108,102,32,105,102,32,116,104,101, 32,109,111,100,117,108,101,32,119,97,115,32,102,111,117,110, - 100,44,32,111,114,32,78,111,110,101,32,105,102,32,105,116, - 32,119,97,115,110,39,116,46,10,32,32,32,32,32,32,32, - 32,84,104,101,32,111,112,116,105,111,110,97,108,32,39,112, - 97,116,104,39,32,97,114,103,117,109,101,110,116,32,105,115, - 32,105,103,110,111,114,101,100,32,45,45,32,105,116,39,115, - 32,116,104,101,114,101,32,102,111,114,32,99,111,109,112,97, - 116,105,98,105,108,105,116,121,10,32,32,32,32,32,32,32, - 32,119,105,116,104,32,116,104,101,32,105,109,112,111,114,116, - 101,114,32,112,114,111,116,111,99,111,108,46,10,32,32,32, - 32,32,32,32,32,114,0,0,0,0,41,1,114,41,0,0, - 0,41,3,114,32,0,0,0,114,38,0,0,0,114,13,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,218,11,102,105,110,100,95,109,111,100,117,108,101,141,0, - 0,0,115,2,0,0,0,0,9,122,23,122,105,112,105,109, - 112,111,114,116,101,114,46,102,105,110,100,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,5,0,0,0,3, - 0,0,0,67,0,0,0,115,20,0,0,0,116,0,124,0, - 124,1,131,2,92,3,125,2,125,3,125,4,124,2,83,0, - 41,1,122,163,103,101,116,95,99,111,100,101,40,102,117,108, - 108,110,97,109,101,41,32,45,62,32,99,111,100,101,32,111, - 98,106,101,99,116,46,10,10,32,32,32,32,32,32,32,32, - 82,101,116,117,114,110,32,116,104,101,32,99,111,100,101,32, - 111,98,106,101,99,116,32,102,111,114,32,116,104,101,32,115, - 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,46, - 32,82,97,105,115,101,32,90,105,112,73,109,112,111,114,116, - 69,114,114,111,114,10,32,32,32,32,32,32,32,32,105,102, - 32,116,104,101,32,109,111,100,117,108,101,32,99,111,117,108, - 100,110,39,116,32,98,101,32,102,111,117,110,100,46,10,32, - 32,32,32,32,32,32,32,169,1,218,16,95,103,101,116,95, - 109,111,100,117,108,101,95,99,111,100,101,169,5,114,32,0, - 0,0,114,38,0,0,0,218,4,99,111,100,101,218,9,105, - 115,112,97,99,107,97,103,101,114,40,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,8,103,101, - 116,95,99,111,100,101,153,0,0,0,115,4,0,0,0,0, - 6,16,1,122,20,122,105,112,105,109,112,111,114,116,101,114, - 46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,0, + 100,44,32,97,32,115,116,114,105,110,103,32,99,111,110,116, + 97,105,110,105,110,103,32,116,104,101,10,32,32,32,32,32, + 32,32,32,102,117,108,108,32,112,97,116,104,32,110,97,109, + 101,32,105,102,32,105,116,39,115,32,112,111,115,115,105,98, + 108,121,32,97,32,112,111,114,116,105,111,110,32,111,102,32, + 97,32,110,97,109,101,115,112,97,99,101,32,112,97,99,107, + 97,103,101,44,10,32,32,32,32,32,32,32,32,111,114,32, + 78,111,110,101,32,111,116,104,101,114,119,105,115,101,46,32, + 84,104,101,32,111,112,116,105,111,110,97,108,32,39,112,97, + 116,104,39,32,97,114,103,117,109,101,110,116,32,105,115,32, + 105,103,110,111,114,101,100,32,45,45,32,105,116,39,115,10, + 32,32,32,32,32,32,32,32,116,104,101,114,101,32,102,111, + 114,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32, + 119,105,116,104,32,116,104,101,32,105,109,112,111,114,116,101, + 114,32,112,114,111,116,111,99,111,108,46,10,32,32,32,32, + 32,32,32,32,78,41,5,218,16,95,103,101,116,95,109,111, + 100,117,108,101,95,105,110,102,111,218,16,95,103,101,116,95, + 109,111,100,117,108,101,95,112,97,116,104,218,7,95,105,115, + 95,100,105,114,114,29,0,0,0,114,20,0,0,0,41,5, + 114,32,0,0,0,218,8,102,117,108,108,110,97,109,101,114, + 13,0,0,0,218,2,109,105,218,7,109,111,100,112,97,116, + 104,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,11,102,105,110,100,95,108,111,97,100,101,114,109,0,0, + 0,115,14,0,0,0,0,10,10,1,8,2,8,7,10,1, + 10,4,24,2,122,23,122,105,112,105,109,112,111,114,116,101, + 114,46,102,105,110,100,95,108,111,97,100,101,114,99,3,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,16,0,0,0,124,0,160,0,124, + 1,124,2,161,2,100,1,25,0,83,0,41,2,97,139,1, + 0,0,102,105,110,100,95,109,111,100,117,108,101,40,102,117, + 108,108,110,97,109,101,44,32,112,97,116,104,61,78,111,110, + 101,41,32,45,62,32,115,101,108,102,32,111,114,32,78,111, + 110,101,46,10,10,32,32,32,32,32,32,32,32,83,101,97, + 114,99,104,32,102,111,114,32,97,32,109,111,100,117,108,101, + 32,115,112,101,99,105,102,105,101,100,32,98,121,32,39,102, + 117,108,108,110,97,109,101,39,46,32,39,102,117,108,108,110, + 97,109,101,39,32,109,117,115,116,32,98,101,32,116,104,101, + 10,32,32,32,32,32,32,32,32,102,117,108,108,121,32,113, + 117,97,108,105,102,105,101,100,32,40,100,111,116,116,101,100, + 41,32,109,111,100,117,108,101,32,110,97,109,101,46,32,73, + 116,32,114,101,116,117,114,110,115,32,116,104,101,32,122,105, + 112,105,109,112,111,114,116,101,114,10,32,32,32,32,32,32, + 32,32,105,110,115,116,97,110,99,101,32,105,116,115,101,108, + 102,32,105,102,32,116,104,101,32,109,111,100,117,108,101,32, + 119,97,115,32,102,111,117,110,100,44,32,111,114,32,78,111, + 110,101,32,105,102,32,105,116,32,119,97,115,110,39,116,46, + 10,32,32,32,32,32,32,32,32,84,104,101,32,111,112,116, + 105,111,110,97,108,32,39,112,97,116,104,39,32,97,114,103, + 117,109,101,110,116,32,105,115,32,105,103,110,111,114,101,100, + 32,45,45,32,105,116,39,115,32,116,104,101,114,101,32,102, + 111,114,32,99,111,109,112,97,116,105,98,105,108,105,116,121, + 10,32,32,32,32,32,32,32,32,119,105,116,104,32,116,104, + 101,32,105,109,112,111,114,116,101,114,32,112,114,111,116,111, + 99,111,108,46,10,32,32,32,32,32,32,32,32,114,0,0, + 0,0,41,1,114,41,0,0,0,41,3,114,32,0,0,0, + 114,38,0,0,0,114,13,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,11,102,105,110,100,95, + 109,111,100,117,108,101,141,0,0,0,115,2,0,0,0,0, + 9,122,23,122,105,112,105,109,112,111,114,116,101,114,46,102, + 105,110,100,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,3,0,0,0,67, + 0,0,0,115,20,0,0,0,116,0,124,0,124,1,131,2, + 92,3,125,2,125,3,125,4,124,2,83,0,41,1,122,163, + 103,101,116,95,99,111,100,101,40,102,117,108,108,110,97,109, + 101,41,32,45,62,32,99,111,100,101,32,111,98,106,101,99, + 116,46,10,10,32,32,32,32,32,32,32,32,82,101,116,117, + 114,110,32,116,104,101,32,99,111,100,101,32,111,98,106,101, + 99,116,32,102,111,114,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,109,111,100,117,108,101,46,32,82,97,105, + 115,101,32,90,105,112,73,109,112,111,114,116,69,114,114,111, + 114,10,32,32,32,32,32,32,32,32,105,102,32,116,104,101, + 32,109,111,100,117,108,101,32,99,111,117,108,100,110,39,116, + 32,98,101,32,102,111,117,110,100,46,10,32,32,32,32,32, + 32,32,32,169,1,218,16,95,103,101,116,95,109,111,100,117, + 108,101,95,99,111,100,101,169,5,114,32,0,0,0,114,38, + 0,0,0,218,4,99,111,100,101,218,9,105,115,112,97,99, + 107,97,103,101,114,40,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,8,103,101,116,95,99,111, + 100,101,153,0,0,0,115,4,0,0,0,0,6,16,1,122, + 20,122,105,112,105,109,112,111,114,116,101,114,46,103,101,116, + 95,99,111,100,101,99,2,0,0,0,0,0,0,0,0,0, 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,118, 0,0,0,116,0,114,16,124,1,160,1,116,0,116,2,161, 2,125,1,124,1,125,2,124,1,160,3,124,0,106,4,116, @@ -298,82 +300,83 @@ const unsigned char _Py_M__zipimport[] = { 0,0,0,0,6,4,1,12,2,4,1,16,1,22,2,2, 1,14,1,14,1,18,1,122,20,122,105,112,105,109,112,111, 114,116,101,114,46,103,101,116,95,100,97,116,97,99,2,0, - 0,0,0,0,0,0,5,0,0,0,3,0,0,0,67,0, - 0,0,115,20,0,0,0,116,0,124,0,124,1,131,2,92, - 3,125,2,125,3,125,4,124,4,83,0,41,1,122,106,103, - 101,116,95,102,105,108,101,110,97,109,101,40,102,117,108,108, - 110,97,109,101,41,32,45,62,32,102,105,108,101,110,97,109, - 101,32,115,116,114,105,110,103,46,10,10,32,32,32,32,32, - 32,32,32,82,101,116,117,114,110,32,116,104,101,32,102,105, - 108,101,110,97,109,101,32,102,111,114,32,116,104,101,32,115, - 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,46, - 10,32,32,32,32,32,32,32,32,114,43,0,0,0,114,45, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,12,103,101,116,95,102,105,108,101,110,97,109,101, - 184,0,0,0,115,4,0,0,0,0,7,16,1,122,24,122, - 105,112,105,109,112,111,114,116,101,114,46,103,101,116,95,102, - 105,108,101,110,97,109,101,99,2,0,0,0,0,0,0,0, - 6,0,0,0,8,0,0,0,67,0,0,0,115,128,0,0, - 0,116,0,124,0,124,1,131,2,125,2,124,2,100,1,107, - 8,114,36,116,1,100,2,124,1,155,2,157,2,124,1,100, - 3,141,2,130,1,116,2,124,0,124,1,131,2,125,3,124, - 2,114,64,116,3,160,4,124,3,100,4,161,2,125,4,110, - 10,124,3,155,0,100,5,157,2,125,4,122,14,124,0,106, - 5,124,4,25,0,125,5,87,0,110,22,4,0,116,6,107, - 10,114,110,1,0,1,0,1,0,89,0,100,1,83,0,88, - 0,116,7,124,0,106,8,124,5,131,2,160,9,161,0,83, - 0,41,6,122,253,103,101,116,95,115,111,117,114,99,101,40, - 102,117,108,108,110,97,109,101,41,32,45,62,32,115,111,117, - 114,99,101,32,115,116,114,105,110,103,46,10,10,32,32,32, - 32,32,32,32,32,82,101,116,117,114,110,32,116,104,101,32, - 115,111,117,114,99,101,32,99,111,100,101,32,102,111,114,32, - 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,117,108,101,46,32,82,97,105,115,101,32,90,105,112,73, - 109,112,111,114,116,69,114,114,111,114,10,32,32,32,32,32, - 32,32,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,99,111,117,108,100,110,39,116,32,98,101,32,102,111,117, - 110,100,44,32,114,101,116,117,114,110,32,78,111,110,101,32, - 105,102,32,116,104,101,32,97,114,99,104,105,118,101,32,100, - 111,101,115,10,32,32,32,32,32,32,32,32,99,111,110,116, - 97,105,110,32,116,104,101,32,109,111,100,117,108,101,44,32, - 98,117,116,32,104,97,115,32,110,111,32,115,111,117,114,99, - 101,32,102,111,114,32,105,116,46,10,32,32,32,32,32,32, - 32,32,78,250,18,99,97,110,39,116,32,102,105,110,100,32, - 109,111,100,117,108,101,32,169,1,218,4,110,97,109,101,250, - 11,95,95,105,110,105,116,95,95,46,112,121,250,3,46,112, - 121,41,10,114,35,0,0,0,114,3,0,0,0,114,36,0, - 0,0,114,21,0,0,0,114,30,0,0,0,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0, - 218,6,100,101,99,111,100,101,41,6,114,32,0,0,0,114, - 38,0,0,0,114,39,0,0,0,114,13,0,0,0,218,8, - 102,117,108,108,112,97,116,104,114,54,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,10,103,101, - 116,95,115,111,117,114,99,101,195,0,0,0,115,24,0,0, - 0,0,7,10,1,8,1,18,2,10,1,4,1,14,2,10, - 2,2,1,14,1,14,2,8,1,122,22,122,105,112,105,109, - 112,111,114,116,101,114,46,103,101,116,95,115,111,117,114,99, - 101,99,2,0,0,0,0,0,0,0,3,0,0,0,4,0, - 0,0,67,0,0,0,115,40,0,0,0,116,0,124,0,124, - 1,131,2,125,2,124,2,100,1,107,8,114,36,116,1,100, - 2,124,1,155,2,157,2,124,1,100,3,141,2,130,1,124, - 2,83,0,41,4,122,171,105,115,95,112,97,99,107,97,103, - 101,40,102,117,108,108,110,97,109,101,41,32,45,62,32,98, - 111,111,108,46,10,10,32,32,32,32,32,32,32,32,82,101, - 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, - 32,109,111,100,117,108,101,32,115,112,101,99,105,102,105,101, - 100,32,98,121,32,102,117,108,108,110,97,109,101,32,105,115, - 32,97,32,112,97,99,107,97,103,101,46,10,32,32,32,32, - 32,32,32,32,82,97,105,115,101,32,90,105,112,73,109,112, - 111,114,116,69,114,114,111,114,32,105,102,32,116,104,101,32, - 109,111,100,117,108,101,32,99,111,117,108,100,110,39,116,32, - 98,101,32,102,111,117,110,100,46,10,32,32,32,32,32,32, - 32,32,78,114,57,0,0,0,114,58,0,0,0,41,2,114, - 35,0,0,0,114,3,0,0,0,41,3,114,32,0,0,0, - 114,38,0,0,0,114,39,0,0,0,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,218,10,105,115,95,112,97, - 99,107,97,103,101,221,0,0,0,115,8,0,0,0,0,6, - 10,1,8,1,18,1,122,22,122,105,112,105,109,112,111,114, - 116,101,114,46,105,115,95,112,97,99,107,97,103,101,99,2, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,3,0, + 0,0,67,0,0,0,115,20,0,0,0,116,0,124,0,124, + 1,131,2,92,3,125,2,125,3,125,4,124,4,83,0,41, + 1,122,106,103,101,116,95,102,105,108,101,110,97,109,101,40, + 102,117,108,108,110,97,109,101,41,32,45,62,32,102,105,108, + 101,110,97,109,101,32,115,116,114,105,110,103,46,10,10,32, + 32,32,32,32,32,32,32,82,101,116,117,114,110,32,116,104, + 101,32,102,105,108,101,110,97,109,101,32,102,111,114,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,46,10,32,32,32,32,32,32,32,32,114,43,0, + 0,0,114,45,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,12,103,101,116,95,102,105,108,101, + 110,97,109,101,184,0,0,0,115,4,0,0,0,0,7,16, + 1,122,24,122,105,112,105,109,112,111,114,116,101,114,46,103, + 101,116,95,102,105,108,101,110,97,109,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,6,0,0,0,8,0,0,0, + 67,0,0,0,115,128,0,0,0,116,0,124,0,124,1,131, + 2,125,2,124,2,100,1,107,8,114,36,116,1,100,2,124, + 1,155,2,157,2,124,1,100,3,141,2,130,1,116,2,124, + 0,124,1,131,2,125,3,124,2,114,64,116,3,160,4,124, + 3,100,4,161,2,125,4,110,10,124,3,155,0,100,5,157, + 2,125,4,122,14,124,0,106,5,124,4,25,0,125,5,87, + 0,110,22,4,0,116,6,107,10,114,110,1,0,1,0,1, + 0,89,0,100,1,83,0,88,0,116,7,124,0,106,8,124, + 5,131,2,160,9,161,0,83,0,41,6,122,253,103,101,116, + 95,115,111,117,114,99,101,40,102,117,108,108,110,97,109,101, + 41,32,45,62,32,115,111,117,114,99,101,32,115,116,114,105, + 110,103,46,10,10,32,32,32,32,32,32,32,32,82,101,116, + 117,114,110,32,116,104,101,32,115,111,117,114,99,101,32,99, + 111,100,101,32,102,111,114,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,46,32,82,97, + 105,115,101,32,90,105,112,73,109,112,111,114,116,69,114,114, + 111,114,10,32,32,32,32,32,32,32,32,105,102,32,116,104, + 101,32,109,111,100,117,108,101,32,99,111,117,108,100,110,39, + 116,32,98,101,32,102,111,117,110,100,44,32,114,101,116,117, + 114,110,32,78,111,110,101,32,105,102,32,116,104,101,32,97, + 114,99,104,105,118,101,32,100,111,101,115,10,32,32,32,32, + 32,32,32,32,99,111,110,116,97,105,110,32,116,104,101,32, + 109,111,100,117,108,101,44,32,98,117,116,32,104,97,115,32, + 110,111,32,115,111,117,114,99,101,32,102,111,114,32,105,116, + 46,10,32,32,32,32,32,32,32,32,78,250,18,99,97,110, + 39,116,32,102,105,110,100,32,109,111,100,117,108,101,32,169, + 1,218,4,110,97,109,101,250,11,95,95,105,110,105,116,95, + 95,46,112,121,250,3,46,112,121,41,10,114,35,0,0,0, + 114,3,0,0,0,114,36,0,0,0,114,21,0,0,0,114, + 30,0,0,0,114,28,0,0,0,114,26,0,0,0,114,52, + 0,0,0,114,29,0,0,0,218,6,100,101,99,111,100,101, + 41,6,114,32,0,0,0,114,38,0,0,0,114,39,0,0, + 0,114,13,0,0,0,218,8,102,117,108,108,112,97,116,104, + 114,54,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,218,10,103,101,116,95,115,111,117,114,99,101, + 195,0,0,0,115,24,0,0,0,0,7,10,1,8,1,18, + 2,10,1,4,1,14,2,10,2,2,1,14,1,14,2,8, + 1,122,22,122,105,112,105,109,112,111,114,116,101,114,46,103, + 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, + 0,0,115,40,0,0,0,116,0,124,0,124,1,131,2,125, + 2,124,2,100,1,107,8,114,36,116,1,100,2,124,1,155, + 2,157,2,124,1,100,3,141,2,130,1,124,2,83,0,41, + 4,122,171,105,115,95,112,97,99,107,97,103,101,40,102,117, + 108,108,110,97,109,101,41,32,45,62,32,98,111,111,108,46, + 10,10,32,32,32,32,32,32,32,32,82,101,116,117,114,110, + 32,84,114,117,101,32,105,102,32,116,104,101,32,109,111,100, + 117,108,101,32,115,112,101,99,105,102,105,101,100,32,98,121, + 32,102,117,108,108,110,97,109,101,32,105,115,32,97,32,112, + 97,99,107,97,103,101,46,10,32,32,32,32,32,32,32,32, + 82,97,105,115,101,32,90,105,112,73,109,112,111,114,116,69, + 114,114,111,114,32,105,102,32,116,104,101,32,109,111,100,117, + 108,101,32,99,111,117,108,100,110,39,116,32,98,101,32,102, + 111,117,110,100,46,10,32,32,32,32,32,32,32,32,78,114, + 57,0,0,0,114,58,0,0,0,41,2,114,35,0,0,0, + 114,3,0,0,0,41,3,114,32,0,0,0,114,38,0,0, + 0,114,39,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,10,105,115,95,112,97,99,107,97,103, + 101,221,0,0,0,115,8,0,0,0,0,6,10,1,8,1, + 18,1,122,22,122,105,112,105,109,112,111,114,116,101,114,46, + 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, 0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,67, 0,0,0,115,248,0,0,0,116,0,124,0,124,1,131,2, 92,3,125,2,125,3,125,4,116,1,106,2,160,3,124,1, @@ -433,70 +436,71 @@ const unsigned char _Py_M__zipimport[] = { 1,6,1,16,1,16,1,6,1,8,1,8,2,2,1,14, 1,14,1,22,1,14,1,122,23,122,105,112,105,109,112,111, 114,116,101,114,46,108,111,97,100,95,109,111,100,117,108,101, - 99,2,0,0,0,0,0,0,0,3,0,0,0,8,0,0, - 0,67,0,0,0,115,88,0,0,0,122,20,124,0,160,0, - 124,1,161,1,115,18,87,0,100,1,83,0,87,0,110,22, - 4,0,116,1,107,10,114,42,1,0,1,0,1,0,89,0, - 100,1,83,0,88,0,116,2,106,3,115,78,100,2,100,3, - 108,4,109,5,125,2,1,0,124,2,160,6,116,2,161,1, - 1,0,100,4,116,2,95,3,116,2,124,0,124,1,131,2, - 83,0,41,5,122,204,82,101,116,117,114,110,32,116,104,101, - 32,82,101,115,111,117,114,99,101,82,101,97,100,101,114,32, - 102,111,114,32,97,32,112,97,99,107,97,103,101,32,105,110, - 32,97,32,122,105,112,32,102,105,108,101,46,10,10,32,32, - 32,32,32,32,32,32,73,102,32,39,102,117,108,108,110,97, - 109,101,39,32,105,115,32,97,32,112,97,99,107,97,103,101, - 32,119,105,116,104,105,110,32,116,104,101,32,122,105,112,32, - 102,105,108,101,44,32,114,101,116,117,114,110,32,116,104,101, - 10,32,32,32,32,32,32,32,32,39,82,101,115,111,117,114, - 99,101,82,101,97,100,101,114,39,32,111,98,106,101,99,116, - 32,102,111,114,32,116,104,101,32,112,97,99,107,97,103,101, - 46,32,32,79,116,104,101,114,119,105,115,101,32,114,101,116, - 117,114,110,32,78,111,110,101,46,10,32,32,32,32,32,32, - 32,32,78,114,0,0,0,0,41,1,218,14,82,101,115,111, - 117,114,99,101,82,101,97,100,101,114,84,41,7,114,65,0, - 0,0,114,3,0,0,0,218,24,95,90,105,112,73,109,112, - 111,114,116,82,101,115,111,117,114,99,101,82,101,97,100,101, - 114,218,11,95,114,101,103,105,115,116,101,114,101,100,90,13, - 105,109,112,111,114,116,108,105,98,46,97,98,99,114,79,0, - 0,0,90,8,114,101,103,105,115,116,101,114,41,3,114,32, - 0,0,0,114,38,0,0,0,114,79,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,19,103,101, - 116,95,114,101,115,111,117,114,99,101,95,114,101,97,100,101, - 114,16,1,0,0,115,20,0,0,0,0,6,2,1,10,1, - 10,1,14,1,8,1,6,1,12,1,10,1,6,1,122,31, - 122,105,112,105,109,112,111,114,116,101,114,46,103,101,116,95, - 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,99, - 1,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0, - 67,0,0,0,115,24,0,0,0,100,1,124,0,106,0,155, - 0,116,1,155,0,124,0,106,2,155,0,100,2,157,5,83, - 0,41,3,78,122,21,60,122,105,112,105,109,112,111,114,116, - 101,114,32,111,98,106,101,99,116,32,34,122,2,34,62,41, - 3,114,29,0,0,0,114,20,0,0,0,114,31,0,0,0, - 41,1,114,32,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,8,95,95,114,101,112,114,95,95, - 34,1,0,0,115,2,0,0,0,0,1,122,20,122,105,112, - 105,109,112,111,114,116,101,114,46,95,95,114,101,112,114,95, - 95,41,1,78,41,1,78,41,15,114,6,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,7,95,95,100,111,99,95, - 95,114,34,0,0,0,114,41,0,0,0,114,42,0,0,0, - 114,48,0,0,0,114,55,0,0,0,114,56,0,0,0,114, - 64,0,0,0,114,65,0,0,0,114,78,0,0,0,114,82, - 0,0,0,114,83,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,114,4,0,0, - 0,45,0,0,0,115,24,0,0,0,8,1,4,17,8,46, - 10,32,10,12,8,10,8,21,8,11,8,26,8,13,8,38, - 8,18,122,12,95,95,105,110,105,116,95,95,46,112,121,99, - 84,114,60,0,0,0,70,41,3,122,4,46,112,121,99,84, - 70,41,3,114,61,0,0,0,70,70,99,2,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, - 20,0,0,0,124,0,106,0,124,1,160,1,100,1,161,1, - 100,2,25,0,23,0,83,0,41,3,78,218,1,46,233,2, - 0,0,0,41,2,114,31,0,0,0,218,10,114,112,97,114, - 116,105,116,105,111,110,41,2,114,32,0,0,0,114,38,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,36,0,0,0,52,1,0,0,115,2,0,0,0,0, - 1,114,36,0,0,0,99,2,0,0,0,0,0,0,0,3, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,88,0,0,0,122,20, + 124,0,160,0,124,1,161,1,115,18,87,0,100,1,83,0, + 87,0,110,22,4,0,116,1,107,10,114,42,1,0,1,0, + 1,0,89,0,100,1,83,0,88,0,116,2,106,3,115,78, + 100,2,100,3,108,4,109,5,125,2,1,0,124,2,160,6, + 116,2,161,1,1,0,100,4,116,2,95,3,116,2,124,0, + 124,1,131,2,83,0,41,5,122,204,82,101,116,117,114,110, + 32,116,104,101,32,82,101,115,111,117,114,99,101,82,101,97, + 100,101,114,32,102,111,114,32,97,32,112,97,99,107,97,103, + 101,32,105,110,32,97,32,122,105,112,32,102,105,108,101,46, + 10,10,32,32,32,32,32,32,32,32,73,102,32,39,102,117, + 108,108,110,97,109,101,39,32,105,115,32,97,32,112,97,99, + 107,97,103,101,32,119,105,116,104,105,110,32,116,104,101,32, + 122,105,112,32,102,105,108,101,44,32,114,101,116,117,114,110, + 32,116,104,101,10,32,32,32,32,32,32,32,32,39,82,101, + 115,111,117,114,99,101,82,101,97,100,101,114,39,32,111,98, + 106,101,99,116,32,102,111,114,32,116,104,101,32,112,97,99, + 107,97,103,101,46,32,32,79,116,104,101,114,119,105,115,101, + 32,114,101,116,117,114,110,32,78,111,110,101,46,10,32,32, + 32,32,32,32,32,32,78,114,0,0,0,0,41,1,218,14, + 82,101,115,111,117,114,99,101,82,101,97,100,101,114,84,41, + 7,114,65,0,0,0,114,3,0,0,0,218,24,95,90,105, + 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, + 101,97,100,101,114,218,11,95,114,101,103,105,115,116,101,114, + 101,100,90,13,105,109,112,111,114,116,108,105,98,46,97,98, + 99,114,79,0,0,0,90,8,114,101,103,105,115,116,101,114, + 41,3,114,32,0,0,0,114,38,0,0,0,114,79,0,0, + 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,19,103,101,116,95,114,101,115,111,117,114,99,101,95,114, + 101,97,100,101,114,16,1,0,0,115,20,0,0,0,0,6, + 2,1,10,1,10,1,14,1,8,1,6,1,12,1,10,1, + 6,1,122,31,122,105,112,105,109,112,111,114,116,101,114,46, + 103,101,116,95,114,101,115,111,117,114,99,101,95,114,101,97, + 100,101,114,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,5,0,0,0,67,0,0,0,115,24,0,0, + 0,100,1,124,0,106,0,155,0,116,1,155,0,124,0,106, + 2,155,0,100,2,157,5,83,0,41,3,78,122,21,60,122, + 105,112,105,109,112,111,114,116,101,114,32,111,98,106,101,99, + 116,32,34,122,2,34,62,41,3,114,29,0,0,0,114,20, + 0,0,0,114,31,0,0,0,41,1,114,32,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,8, + 95,95,114,101,112,114,95,95,34,1,0,0,115,2,0,0, + 0,0,1,122,20,122,105,112,105,109,112,111,114,116,101,114, + 46,95,95,114,101,112,114,95,95,41,1,78,41,1,78,41, + 15,114,6,0,0,0,114,7,0,0,0,114,8,0,0,0, + 218,7,95,95,100,111,99,95,95,114,34,0,0,0,114,41, + 0,0,0,114,42,0,0,0,114,48,0,0,0,114,55,0, + 0,0,114,56,0,0,0,114,64,0,0,0,114,65,0,0, + 0,114,78,0,0,0,114,82,0,0,0,114,83,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,4,0,0,0,45,0,0,0,115,24,0, + 0,0,8,1,4,17,8,46,10,32,10,12,8,10,8,21, + 8,11,8,26,8,13,8,38,8,18,122,12,95,95,105,110, + 105,116,95,95,46,112,121,99,84,114,60,0,0,0,70,41, + 3,122,4,46,112,121,99,84,70,41,3,114,61,0,0,0, + 70,70,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,67,0,0,0,115,20,0,0,0, + 124,0,106,0,124,1,160,1,100,1,161,1,100,2,25,0, + 23,0,83,0,41,3,78,218,1,46,233,2,0,0,0,41, + 2,114,31,0,0,0,218,10,114,112,97,114,116,105,116,105, + 111,110,41,2,114,32,0,0,0,114,38,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,114,36,0, + 0,0,52,1,0,0,115,2,0,0,0,0,1,114,36,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,3, 0,0,0,2,0,0,0,67,0,0,0,115,18,0,0,0, 124,1,116,0,23,0,125,2,124,2,124,0,106,1,107,6, 83,0,169,1,78,41,2,114,20,0,0,0,114,28,0,0, @@ -504,223 +508,224 @@ const unsigned char _Py_M__zipimport[] = { 105,114,112,97,116,104,114,9,0,0,0,114,9,0,0,0, 114,10,0,0,0,114,37,0,0,0,56,1,0,0,115,4, 0,0,0,0,4,8,2,114,37,0,0,0,99,2,0,0, - 0,0,0,0,0,7,0,0,0,4,0,0,0,67,0,0, - 0,115,56,0,0,0,116,0,124,0,124,1,131,2,125,2, - 116,1,68,0,93,36,92,3,125,3,125,4,125,5,124,2, - 124,3,23,0,125,6,124,6,124,0,106,2,107,6,114,14, - 124,5,2,0,1,0,83,0,113,14,100,0,83,0,114,88, - 0,0,0,41,3,114,36,0,0,0,218,16,95,122,105,112, - 95,115,101,97,114,99,104,111,114,100,101,114,114,28,0,0, - 0,41,7,114,32,0,0,0,114,38,0,0,0,114,13,0, - 0,0,218,6,115,117,102,102,105,120,218,10,105,115,98,121, - 116,101,99,111,100,101,114,47,0,0,0,114,63,0,0,0, - 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,114, - 35,0,0,0,65,1,0,0,115,12,0,0,0,0,1,10, - 1,14,1,8,1,10,1,10,1,114,35,0,0,0,99,1, - 0,0,0,0,0,0,0,26,0,0,0,9,0,0,0,67, - 0,0,0,115,254,4,0,0,122,16,116,0,160,1,124,0, - 100,1,161,2,125,1,87,0,110,38,4,0,116,2,107,10, - 114,54,1,0,1,0,1,0,116,3,100,2,124,0,155,2, - 157,2,124,0,100,3,141,2,130,1,89,0,110,2,88,0, - 124,1,144,4,143,168,1,0,122,36,124,1,160,4,116,5, - 11,0,100,4,161,2,1,0,124,1,160,6,161,0,125,2, - 124,1,160,7,116,5,161,1,125,3,87,0,110,38,4,0, - 116,2,107,10,114,138,1,0,1,0,1,0,116,3,100,5, - 124,0,155,2,157,2,124,0,100,3,141,2,130,1,89,0, - 110,2,88,0,116,8,124,3,131,1,116,5,107,3,114,170, + 0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0, + 0,67,0,0,0,115,56,0,0,0,116,0,124,0,124,1, + 131,2,125,2,116,1,68,0,93,36,92,3,125,3,125,4, + 125,5,124,2,124,3,23,0,125,6,124,6,124,0,106,2, + 107,6,114,14,124,5,2,0,1,0,83,0,113,14,100,0, + 83,0,114,88,0,0,0,41,3,114,36,0,0,0,218,16, + 95,122,105,112,95,115,101,97,114,99,104,111,114,100,101,114, + 114,28,0,0,0,41,7,114,32,0,0,0,114,38,0,0, + 0,114,13,0,0,0,218,6,115,117,102,102,105,120,218,10, + 105,115,98,121,116,101,99,111,100,101,114,47,0,0,0,114, + 63,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,114,35,0,0,0,65,1,0,0,115,12,0,0, + 0,0,1,10,1,14,1,8,1,10,1,10,1,114,35,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,26, + 0,0,0,9,0,0,0,67,0,0,0,115,254,4,0,0, + 122,16,116,0,160,1,124,0,100,1,161,2,125,1,87,0, + 110,38,4,0,116,2,107,10,114,54,1,0,1,0,1,0, + 116,3,100,2,124,0,155,2,157,2,124,0,100,3,141,2, + 130,1,89,0,110,2,88,0,124,1,144,4,143,168,1,0, + 122,36,124,1,160,4,116,5,11,0,100,4,161,2,1,0, + 124,1,160,6,161,0,125,2,124,1,160,7,116,5,161,1, + 125,3,87,0,110,38,4,0,116,2,107,10,114,138,1,0, + 1,0,1,0,116,3,100,5,124,0,155,2,157,2,124,0, + 100,3,141,2,130,1,89,0,110,2,88,0,116,8,124,3, + 131,1,116,5,107,3,114,170,116,3,100,5,124,0,155,2, + 157,2,124,0,100,3,141,2,130,1,124,3,100,0,100,6, + 133,2,25,0,116,9,107,3,144,1,114,180,122,24,124,1, + 160,4,100,7,100,4,161,2,1,0,124,1,160,6,161,0, + 125,4,87,0,110,38,4,0,116,2,107,10,114,250,1,0, + 1,0,1,0,116,3,100,5,124,0,155,2,157,2,124,0, + 100,3,141,2,130,1,89,0,110,2,88,0,116,10,124,4, + 116,11,24,0,116,5,24,0,100,7,131,2,125,5,122,22, + 124,1,160,4,124,5,161,1,1,0,124,1,160,7,161,0, + 125,6,87,0,110,40,4,0,116,2,107,10,144,1,114,76, + 1,0,1,0,1,0,116,3,100,5,124,0,155,2,157,2, + 124,0,100,3,141,2,130,1,89,0,110,2,88,0,124,6, + 160,12,116,9,161,1,125,7,124,7,100,7,107,0,144,1, + 114,116,116,3,100,8,124,0,155,2,157,2,124,0,100,3, + 141,2,130,1,124,6,124,7,124,7,116,5,23,0,133,2, + 25,0,125,3,116,8,124,3,131,1,116,5,107,3,144,1, + 114,164,116,3,100,9,124,0,155,2,157,2,124,0,100,3, + 141,2,130,1,124,4,116,8,124,6,131,1,24,0,124,7, + 23,0,125,2,116,13,124,3,100,10,100,11,133,2,25,0, + 131,1,125,8,116,13,124,3,100,11,100,12,133,2,25,0, + 131,1,125,9,124,2,124,8,107,0,144,1,114,240,116,3, + 100,13,124,0,155,2,157,2,124,0,100,3,141,2,130,1, + 124,2,124,9,107,0,144,2,114,12,116,3,100,14,124,0, + 155,2,157,2,124,0,100,3,141,2,130,1,124,2,124,8, + 56,0,125,2,124,2,124,9,24,0,125,10,124,10,100,7, + 107,0,144,2,114,56,116,3,100,15,124,0,155,2,157,2, + 124,0,100,3,141,2,130,1,105,0,125,11,100,7,125,12, + 122,14,124,1,160,4,124,2,161,1,1,0,87,0,110,40, + 4,0,116,2,107,10,144,2,114,118,1,0,1,0,1,0, 116,3,100,5,124,0,155,2,157,2,124,0,100,3,141,2, - 130,1,124,3,100,0,100,6,133,2,25,0,116,9,107,3, - 144,1,114,180,122,24,124,1,160,4,100,7,100,4,161,2, - 1,0,124,1,160,6,161,0,125,4,87,0,110,38,4,0, - 116,2,107,10,114,250,1,0,1,0,1,0,116,3,100,5, - 124,0,155,2,157,2,124,0,100,3,141,2,130,1,89,0, - 110,2,88,0,116,10,124,4,116,11,24,0,116,5,24,0, - 100,7,131,2,125,5,122,22,124,1,160,4,124,5,161,1, - 1,0,124,1,160,7,161,0,125,6,87,0,110,40,4,0, - 116,2,107,10,144,1,114,76,1,0,1,0,1,0,116,3, - 100,5,124,0,155,2,157,2,124,0,100,3,141,2,130,1, - 89,0,110,2,88,0,124,6,160,12,116,9,161,1,125,7, - 124,7,100,7,107,0,144,1,114,116,116,3,100,8,124,0, - 155,2,157,2,124,0,100,3,141,2,130,1,124,6,124,7, - 124,7,116,5,23,0,133,2,25,0,125,3,116,8,124,3, - 131,1,116,5,107,3,144,1,114,164,116,3,100,9,124,0, - 155,2,157,2,124,0,100,3,141,2,130,1,124,4,116,8, - 124,6,131,1,24,0,124,7,23,0,125,2,116,13,124,3, - 100,10,100,11,133,2,25,0,131,1,125,8,116,13,124,3, - 100,11,100,12,133,2,25,0,131,1,125,9,124,2,124,8, - 107,0,144,1,114,240,116,3,100,13,124,0,155,2,157,2, - 124,0,100,3,141,2,130,1,124,2,124,9,107,0,144,2, - 114,12,116,3,100,14,124,0,155,2,157,2,124,0,100,3, - 141,2,130,1,124,2,124,8,56,0,125,2,124,2,124,9, - 24,0,125,10,124,10,100,7,107,0,144,2,114,56,116,3, - 100,15,124,0,155,2,157,2,124,0,100,3,141,2,130,1, - 105,0,125,11,100,7,125,12,122,14,124,1,160,4,124,2, - 161,1,1,0,87,0,110,40,4,0,116,2,107,10,144,2, - 114,118,1,0,1,0,1,0,116,3,100,5,124,0,155,2, - 157,2,124,0,100,3,141,2,130,1,89,0,110,2,88,0, - 124,1,160,7,100,16,161,1,125,3,116,8,124,3,131,1, - 100,6,107,0,144,2,114,152,116,14,100,17,131,1,130,1, - 124,3,100,0,100,6,133,2,25,0,100,18,107,3,144,2, - 114,174,144,4,113,226,116,8,124,3,131,1,100,16,107,3, - 144,2,114,196,116,14,100,17,131,1,130,1,116,15,124,3, - 100,19,100,20,133,2,25,0,131,1,125,13,116,15,124,3, - 100,20,100,10,133,2,25,0,131,1,125,14,116,15,124,3, - 100,10,100,21,133,2,25,0,131,1,125,15,116,15,124,3, - 100,21,100,11,133,2,25,0,131,1,125,16,116,13,124,3, - 100,11,100,12,133,2,25,0,131,1,125,17,116,13,124,3, - 100,12,100,22,133,2,25,0,131,1,125,18,116,13,124,3, - 100,22,100,23,133,2,25,0,131,1,125,4,116,15,124,3, - 100,23,100,24,133,2,25,0,131,1,125,19,116,15,124,3, - 100,24,100,25,133,2,25,0,131,1,125,20,116,15,124,3, - 100,25,100,26,133,2,25,0,131,1,125,21,116,13,124,3, - 100,27,100,16,133,2,25,0,131,1,125,22,124,19,124,20, - 23,0,124,21,23,0,125,8,124,22,124,9,107,4,144,3, - 114,156,116,3,100,28,124,0,155,2,157,2,124,0,100,3, - 141,2,130,1,124,22,124,10,55,0,125,22,122,14,124,1, - 160,7,124,19,161,1,125,23,87,0,110,40,4,0,116,2, - 107,10,144,3,114,218,1,0,1,0,1,0,116,3,100,5, - 124,0,155,2,157,2,124,0,100,3,141,2,130,1,89,0, - 110,2,88,0,116,8,124,23,131,1,124,19,107,3,144,3, - 114,252,116,3,100,5,124,0,155,2,157,2,124,0,100,3, - 141,2,130,1,122,50,116,8,124,1,160,7,124,8,124,19, - 24,0,161,1,131,1,124,8,124,19,24,0,107,3,144,4, - 114,44,116,3,100,5,124,0,155,2,157,2,124,0,100,3, - 141,2,130,1,87,0,110,40,4,0,116,2,107,10,144,4, - 114,86,1,0,1,0,1,0,116,3,100,5,124,0,155,2, - 157,2,124,0,100,3,141,2,130,1,89,0,110,2,88,0, - 124,13,100,29,64,0,144,4,114,108,124,23,160,16,161,0, - 125,23,110,54,122,14,124,23,160,16,100,30,161,1,125,23, - 87,0,110,38,4,0,116,17,107,10,144,4,114,160,1,0, - 1,0,1,0,124,23,160,16,100,31,161,1,160,18,116,19, - 161,1,125,23,89,0,110,2,88,0,124,23,160,20,100,32, - 116,21,161,2,125,23,116,22,160,23,124,0,124,23,161,2, - 125,24,124,24,124,14,124,18,124,4,124,22,124,15,124,16, - 124,17,102,8,125,25,124,25,124,11,124,23,60,0,124,12, - 100,33,55,0,125,12,144,2,113,120,87,0,53,0,81,0, - 82,0,88,0,116,24,160,25,100,34,124,12,124,0,161,3, - 1,0,124,11,83,0,41,35,78,218,2,114,98,122,21,99, - 97,110,39,116,32,111,112,101,110,32,90,105,112,32,102,105, - 108,101,58,32,114,12,0,0,0,114,86,0,0,0,250,21, - 99,97,110,39,116,32,114,101,97,100,32,90,105,112,32,102, - 105,108,101,58,32,233,4,0,0,0,114,0,0,0,0,122, - 16,110,111,116,32,97,32,90,105,112,32,102,105,108,101,58, - 32,122,18,99,111,114,114,117,112,116,32,90,105,112,32,102, - 105,108,101,58,32,233,12,0,0,0,233,16,0,0,0,233, - 20,0,0,0,122,28,98,97,100,32,99,101,110,116,114,97, - 108,32,100,105,114,101,99,116,111,114,121,32,115,105,122,101, - 58,32,122,30,98,97,100,32,99,101,110,116,114,97,108,32, - 100,105,114,101,99,116,111,114,121,32,111,102,102,115,101,116, - 58,32,122,38,98,97,100,32,99,101,110,116,114,97,108,32, - 100,105,114,101,99,116,111,114,121,32,115,105,122,101,32,111, - 114,32,111,102,102,115,101,116,58,32,233,46,0,0,0,250, - 27,69,79,70,32,114,101,97,100,32,119,104,101,114,101,32, - 110,111,116,32,101,120,112,101,99,116,101,100,115,4,0,0, - 0,80,75,1,2,233,8,0,0,0,233,10,0,0,0,233, - 14,0,0,0,233,24,0,0,0,233,28,0,0,0,233,30, - 0,0,0,233,32,0,0,0,233,34,0,0,0,233,42,0, - 0,0,122,25,98,97,100,32,108,111,99,97,108,32,104,101, - 97,100,101,114,32,111,102,102,115,101,116,58,32,105,0,8, - 0,0,218,5,97,115,99,105,105,90,6,108,97,116,105,110, - 49,250,1,47,114,5,0,0,0,122,33,122,105,112,105,109, - 112,111,114,116,58,32,102,111,117,110,100,32,123,125,32,110, - 97,109,101,115,32,105,110,32,123,33,114,125,41,26,218,3, - 95,105,111,218,4,111,112,101,110,114,22,0,0,0,114,3, - 0,0,0,218,4,115,101,101,107,218,20,69,78,68,95,67, - 69,78,84,82,65,76,95,68,73,82,95,83,73,90,69,90, - 4,116,101,108,108,218,4,114,101,97,100,114,51,0,0,0, - 218,18,83,84,82,73,78,71,95,69,78,68,95,65,82,67, - 72,73,86,69,218,3,109,97,120,218,15,77,65,88,95,67, - 79,77,77,69,78,84,95,76,69,78,218,5,114,102,105,110, - 100,114,2,0,0,0,218,8,69,79,70,69,114,114,111,114, - 114,1,0,0,0,114,62,0,0,0,218,18,85,110,105,99, - 111,100,101,68,101,99,111,100,101,69,114,114,111,114,218,9, - 116,114,97,110,115,108,97,116,101,218,11,99,112,52,51,55, - 95,116,97,98,108,101,114,19,0,0,0,114,20,0,0,0, - 114,21,0,0,0,114,30,0,0,0,114,76,0,0,0,114, - 77,0,0,0,41,26,114,29,0,0,0,218,2,102,112,90, - 15,104,101,97,100,101,114,95,112,111,115,105,116,105,111,110, - 218,6,98,117,102,102,101,114,218,9,102,105,108,101,95,115, - 105,122,101,90,17,109,97,120,95,99,111,109,109,101,110,116, - 95,115,116,97,114,116,218,4,100,97,116,97,90,3,112,111, - 115,218,11,104,101,97,100,101,114,95,115,105,122,101,90,13, - 104,101,97,100,101,114,95,111,102,102,115,101,116,90,10,97, - 114,99,95,111,102,102,115,101,116,114,33,0,0,0,218,5, - 99,111,117,110,116,218,5,102,108,97,103,115,218,8,99,111, - 109,112,114,101,115,115,218,4,116,105,109,101,218,4,100,97, - 116,101,218,3,99,114,99,218,9,100,97,116,97,95,115,105, - 122,101,218,9,110,97,109,101,95,115,105,122,101,218,10,101, - 120,116,114,97,95,115,105,122,101,90,12,99,111,109,109,101, - 110,116,95,115,105,122,101,218,11,102,105,108,101,95,111,102, - 102,115,101,116,114,59,0,0,0,114,13,0,0,0,218,1, - 116,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 114,27,0,0,0,96,1,0,0,115,212,0,0,0,0,1, - 2,1,16,1,14,1,24,2,8,1,2,1,14,1,8,1, - 14,1,14,1,24,1,12,1,18,1,18,3,2,1,12,1, - 12,1,14,1,10,1,2,255,12,2,8,1,2,255,2,1, - 2,255,4,2,2,1,10,1,12,1,16,1,10,1,2,255, - 12,2,10,1,10,1,10,1,2,255,6,2,16,1,14,1, - 10,1,2,255,6,2,16,2,16,1,16,1,10,1,18,1, - 10,1,18,1,8,1,8,1,10,1,18,2,4,2,4,1, - 2,1,14,1,16,1,24,2,10,1,14,1,8,2,18,1, - 4,1,14,1,8,1,16,1,16,1,16,1,16,1,16,1, - 16,1,16,1,16,1,16,1,16,1,16,1,12,1,10,1, - 18,1,8,2,2,1,14,1,16,1,24,1,14,1,18,4, - 2,1,28,1,22,1,16,1,24,2,10,2,10,3,2,1, - 14,1,16,1,22,2,12,1,12,1,20,1,8,1,22,1, - 14,1,114,27,0,0,0,117,190,1,0,0,0,1,2,3, - 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, - 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35, - 36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51, - 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67, - 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83, - 84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99, - 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, - 116,117,118,119,120,121,122,123,124,125,126,127,195,135,195,188, - 195,169,195,162,195,164,195,160,195,165,195,167,195,170,195,171, - 195,168,195,175,195,174,195,172,195,132,195,133,195,137,195,166, - 195,134,195,180,195,182,195,178,195,187,195,185,195,191,195,150, - 195,156,194,162,194,163,194,165,226,130,167,198,146,195,161,195, - 173,195,179,195,186,195,177,195,145,194,170,194,186,194,191,226, - 140,144,194,172,194,189,194,188,194,161,194,171,194,187,226,150, - 145,226,150,146,226,150,147,226,148,130,226,148,164,226,149,161, - 226,149,162,226,149,150,226,149,149,226,149,163,226,149,145,226, - 149,151,226,149,157,226,149,156,226,149,155,226,148,144,226,148, - 148,226,148,180,226,148,172,226,148,156,226,148,128,226,148,188, - 226,149,158,226,149,159,226,149,154,226,149,148,226,149,169,226, - 149,166,226,149,160,226,149,144,226,149,172,226,149,167,226,149, - 168,226,149,164,226,149,165,226,149,153,226,149,152,226,149,146, - 226,149,147,226,149,171,226,149,170,226,148,152,226,148,140,226, - 150,136,226,150,132,226,150,140,226,150,144,226,150,128,206,177, - 195,159,206,147,207,128,206,163,207,131,194,181,207,132,206,166, - 206,152,206,169,206,180,226,136,158,207,134,206,181,226,136,169, - 226,137,161,194,177,226,137,165,226,137,164,226,140,160,226,140, - 161,195,183,226,137,136,194,176,226,136,153,194,183,226,136,154, - 226,129,191,194,178,226,150,160,194,160,99,0,0,0,0,0, - 0,0,0,1,0,0,0,8,0,0,0,67,0,0,0,115, - 108,0,0,0,116,0,114,22,116,1,160,2,100,1,161,1, - 1,0,116,3,100,2,131,1,130,1,100,3,97,0,122,60, - 122,16,100,4,100,5,108,4,109,5,125,0,1,0,87,0, - 110,38,4,0,116,6,107,10,114,82,1,0,1,0,1,0, - 116,1,160,2,100,1,161,1,1,0,116,3,100,2,131,1, - 130,1,89,0,110,2,88,0,87,0,53,0,100,6,97,0, - 88,0,116,1,160,2,100,7,161,1,1,0,124,0,83,0, - 41,8,78,122,27,122,105,112,105,109,112,111,114,116,58,32, - 122,108,105,98,32,85,78,65,86,65,73,76,65,66,76,69, - 250,41,99,97,110,39,116,32,100,101,99,111,109,112,114,101, - 115,115,32,100,97,116,97,59,32,122,108,105,98,32,110,111, - 116,32,97,118,97,105,108,97,98,108,101,84,114,0,0,0, - 0,169,1,218,10,100,101,99,111,109,112,114,101,115,115,70, - 122,25,122,105,112,105,109,112,111,114,116,58,32,122,108,105, - 98,32,97,118,97,105,108,97,98,108,101,41,7,218,15,95, - 105,109,112,111,114,116,105,110,103,95,122,108,105,98,114,76, - 0,0,0,114,77,0,0,0,114,3,0,0,0,90,4,122, - 108,105,98,114,142,0,0,0,218,9,69,120,99,101,112,116, - 105,111,110,114,141,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,20,95,103,101,116,95,100,101, - 99,111,109,112,114,101,115,115,95,102,117,110,99,254,1,0, - 0,115,24,0,0,0,0,2,4,3,10,1,8,2,4,1, - 4,1,16,1,14,1,10,1,18,2,6,2,10,1,114,145, - 0,0,0,99,2,0,0,0,0,0,0,0,17,0,0,0, + 130,1,89,0,110,2,88,0,124,1,160,7,100,16,161,1, + 125,3,116,8,124,3,131,1,100,6,107,0,144,2,114,152, + 116,14,100,17,131,1,130,1,124,3,100,0,100,6,133,2, + 25,0,100,18,107,3,144,2,114,174,144,4,113,226,116,8, + 124,3,131,1,100,16,107,3,144,2,114,196,116,14,100,17, + 131,1,130,1,116,15,124,3,100,19,100,20,133,2,25,0, + 131,1,125,13,116,15,124,3,100,20,100,10,133,2,25,0, + 131,1,125,14,116,15,124,3,100,10,100,21,133,2,25,0, + 131,1,125,15,116,15,124,3,100,21,100,11,133,2,25,0, + 131,1,125,16,116,13,124,3,100,11,100,12,133,2,25,0, + 131,1,125,17,116,13,124,3,100,12,100,22,133,2,25,0, + 131,1,125,18,116,13,124,3,100,22,100,23,133,2,25,0, + 131,1,125,4,116,15,124,3,100,23,100,24,133,2,25,0, + 131,1,125,19,116,15,124,3,100,24,100,25,133,2,25,0, + 131,1,125,20,116,15,124,3,100,25,100,26,133,2,25,0, + 131,1,125,21,116,13,124,3,100,27,100,16,133,2,25,0, + 131,1,125,22,124,19,124,20,23,0,124,21,23,0,125,8, + 124,22,124,9,107,4,144,3,114,156,116,3,100,28,124,0, + 155,2,157,2,124,0,100,3,141,2,130,1,124,22,124,10, + 55,0,125,22,122,14,124,1,160,7,124,19,161,1,125,23, + 87,0,110,40,4,0,116,2,107,10,144,3,114,218,1,0, + 1,0,1,0,116,3,100,5,124,0,155,2,157,2,124,0, + 100,3,141,2,130,1,89,0,110,2,88,0,116,8,124,23, + 131,1,124,19,107,3,144,3,114,252,116,3,100,5,124,0, + 155,2,157,2,124,0,100,3,141,2,130,1,122,50,116,8, + 124,1,160,7,124,8,124,19,24,0,161,1,131,1,124,8, + 124,19,24,0,107,3,144,4,114,44,116,3,100,5,124,0, + 155,2,157,2,124,0,100,3,141,2,130,1,87,0,110,40, + 4,0,116,2,107,10,144,4,114,86,1,0,1,0,1,0, + 116,3,100,5,124,0,155,2,157,2,124,0,100,3,141,2, + 130,1,89,0,110,2,88,0,124,13,100,29,64,0,144,4, + 114,108,124,23,160,16,161,0,125,23,110,54,122,14,124,23, + 160,16,100,30,161,1,125,23,87,0,110,38,4,0,116,17, + 107,10,144,4,114,160,1,0,1,0,1,0,124,23,160,16, + 100,31,161,1,160,18,116,19,161,1,125,23,89,0,110,2, + 88,0,124,23,160,20,100,32,116,21,161,2,125,23,116,22, + 160,23,124,0,124,23,161,2,125,24,124,24,124,14,124,18, + 124,4,124,22,124,15,124,16,124,17,102,8,125,25,124,25, + 124,11,124,23,60,0,124,12,100,33,55,0,125,12,144,2, + 113,120,87,0,53,0,81,0,82,0,88,0,116,24,160,25, + 100,34,124,12,124,0,161,3,1,0,124,11,83,0,41,35, + 78,218,2,114,98,122,21,99,97,110,39,116,32,111,112,101, + 110,32,90,105,112,32,102,105,108,101,58,32,114,12,0,0, + 0,114,86,0,0,0,250,21,99,97,110,39,116,32,114,101, + 97,100,32,90,105,112,32,102,105,108,101,58,32,233,4,0, + 0,0,114,0,0,0,0,122,16,110,111,116,32,97,32,90, + 105,112,32,102,105,108,101,58,32,122,18,99,111,114,114,117, + 112,116,32,90,105,112,32,102,105,108,101,58,32,233,12,0, + 0,0,233,16,0,0,0,233,20,0,0,0,122,28,98,97, + 100,32,99,101,110,116,114,97,108,32,100,105,114,101,99,116, + 111,114,121,32,115,105,122,101,58,32,122,30,98,97,100,32, + 99,101,110,116,114,97,108,32,100,105,114,101,99,116,111,114, + 121,32,111,102,102,115,101,116,58,32,122,38,98,97,100,32, + 99,101,110,116,114,97,108,32,100,105,114,101,99,116,111,114, + 121,32,115,105,122,101,32,111,114,32,111,102,102,115,101,116, + 58,32,233,46,0,0,0,250,27,69,79,70,32,114,101,97, + 100,32,119,104,101,114,101,32,110,111,116,32,101,120,112,101, + 99,116,101,100,115,4,0,0,0,80,75,1,2,233,8,0, + 0,0,233,10,0,0,0,233,14,0,0,0,233,24,0,0, + 0,233,28,0,0,0,233,30,0,0,0,233,32,0,0,0, + 233,34,0,0,0,233,42,0,0,0,122,25,98,97,100,32, + 108,111,99,97,108,32,104,101,97,100,101,114,32,111,102,102, + 115,101,116,58,32,105,0,8,0,0,218,5,97,115,99,105, + 105,90,6,108,97,116,105,110,49,250,1,47,114,5,0,0, + 0,122,33,122,105,112,105,109,112,111,114,116,58,32,102,111, + 117,110,100,32,123,125,32,110,97,109,101,115,32,105,110,32, + 123,33,114,125,41,26,218,3,95,105,111,218,4,111,112,101, + 110,114,22,0,0,0,114,3,0,0,0,218,4,115,101,101, + 107,218,20,69,78,68,95,67,69,78,84,82,65,76,95,68, + 73,82,95,83,73,90,69,90,4,116,101,108,108,218,4,114, + 101,97,100,114,51,0,0,0,218,18,83,84,82,73,78,71, + 95,69,78,68,95,65,82,67,72,73,86,69,218,3,109,97, + 120,218,15,77,65,88,95,67,79,77,77,69,78,84,95,76, + 69,78,218,5,114,102,105,110,100,114,2,0,0,0,218,8, + 69,79,70,69,114,114,111,114,114,1,0,0,0,114,62,0, + 0,0,218,18,85,110,105,99,111,100,101,68,101,99,111,100, + 101,69,114,114,111,114,218,9,116,114,97,110,115,108,97,116, + 101,218,11,99,112,52,51,55,95,116,97,98,108,101,114,19, + 0,0,0,114,20,0,0,0,114,21,0,0,0,114,30,0, + 0,0,114,76,0,0,0,114,77,0,0,0,41,26,114,29, + 0,0,0,218,2,102,112,90,15,104,101,97,100,101,114,95, + 112,111,115,105,116,105,111,110,218,6,98,117,102,102,101,114, + 218,9,102,105,108,101,95,115,105,122,101,90,17,109,97,120, + 95,99,111,109,109,101,110,116,95,115,116,97,114,116,218,4, + 100,97,116,97,90,3,112,111,115,218,11,104,101,97,100,101, + 114,95,115,105,122,101,90,13,104,101,97,100,101,114,95,111, + 102,102,115,101,116,90,10,97,114,99,95,111,102,102,115,101, + 116,114,33,0,0,0,218,5,99,111,117,110,116,218,5,102, + 108,97,103,115,218,8,99,111,109,112,114,101,115,115,218,4, + 116,105,109,101,218,4,100,97,116,101,218,3,99,114,99,218, + 9,100,97,116,97,95,115,105,122,101,218,9,110,97,109,101, + 95,115,105,122,101,218,10,101,120,116,114,97,95,115,105,122, + 101,90,12,99,111,109,109,101,110,116,95,115,105,122,101,218, + 11,102,105,108,101,95,111,102,102,115,101,116,114,59,0,0, + 0,114,13,0,0,0,218,1,116,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,114,27,0,0,0,96,1,0, + 0,115,212,0,0,0,0,1,2,1,16,1,14,1,24,2, + 8,1,2,1,14,1,8,1,14,1,14,1,24,1,12,1, + 18,1,18,3,2,1,12,1,12,1,14,1,10,1,2,255, + 12,2,8,1,2,255,2,1,2,255,4,2,2,1,10,1, + 12,1,16,1,10,1,2,255,12,2,10,1,10,1,10,1, + 2,255,6,2,16,1,14,1,10,1,2,255,6,2,16,2, + 16,1,16,1,10,1,18,1,10,1,18,1,8,1,8,1, + 10,1,18,2,4,2,4,1,2,1,14,1,16,1,24,2, + 10,1,14,1,8,2,18,1,4,1,14,1,8,1,16,1, + 16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1, + 16,1,16,1,12,1,10,1,18,1,8,2,2,1,14,1, + 16,1,24,1,14,1,18,4,2,1,28,1,22,1,16,1, + 24,2,10,2,10,3,2,1,14,1,16,1,22,2,12,1, + 12,1,20,1,8,1,22,1,14,1,114,27,0,0,0,117, + 190,1,0,0,0,1,2,3,4,5,6,7,8,9,10,11, + 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43, + 44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59, + 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75, + 76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91, + 92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107, + 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123, + 124,125,126,127,195,135,195,188,195,169,195,162,195,164,195,160, + 195,165,195,167,195,170,195,171,195,168,195,175,195,174,195,172, + 195,132,195,133,195,137,195,166,195,134,195,180,195,182,195,178, + 195,187,195,185,195,191,195,150,195,156,194,162,194,163,194,165, + 226,130,167,198,146,195,161,195,173,195,179,195,186,195,177,195, + 145,194,170,194,186,194,191,226,140,144,194,172,194,189,194,188, + 194,161,194,171,194,187,226,150,145,226,150,146,226,150,147,226, + 148,130,226,148,164,226,149,161,226,149,162,226,149,150,226,149, + 149,226,149,163,226,149,145,226,149,151,226,149,157,226,149,156, + 226,149,155,226,148,144,226,148,148,226,148,180,226,148,172,226, + 148,156,226,148,128,226,148,188,226,149,158,226,149,159,226,149, + 154,226,149,148,226,149,169,226,149,166,226,149,160,226,149,144, + 226,149,172,226,149,167,226,149,168,226,149,164,226,149,165,226, + 149,153,226,149,152,226,149,146,226,149,147,226,149,171,226,149, + 170,226,148,152,226,148,140,226,150,136,226,150,132,226,150,140, + 226,150,144,226,150,128,206,177,195,159,206,147,207,128,206,163, + 207,131,194,181,207,132,206,166,206,152,206,169,206,180,226,136, + 158,207,134,206,181,226,136,169,226,137,161,194,177,226,137,165, + 226,137,164,226,140,160,226,140,161,195,183,226,137,136,194,176, + 226,136,153,194,183,226,136,154,226,129,191,194,178,226,150,160, + 194,160,99,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,8,0,0,0,67,0,0,0,115,108,0,0,0, + 116,0,114,22,116,1,160,2,100,1,161,1,1,0,116,3, + 100,2,131,1,130,1,100,3,97,0,122,60,122,16,100,4, + 100,5,108,4,109,5,125,0,1,0,87,0,110,38,4,0, + 116,6,107,10,114,82,1,0,1,0,1,0,116,1,160,2, + 100,1,161,1,1,0,116,3,100,2,131,1,130,1,89,0, + 110,2,88,0,87,0,53,0,100,6,97,0,88,0,116,1, + 160,2,100,7,161,1,1,0,124,0,83,0,41,8,78,122, + 27,122,105,112,105,109,112,111,114,116,58,32,122,108,105,98, + 32,85,78,65,86,65,73,76,65,66,76,69,250,41,99,97, + 110,39,116,32,100,101,99,111,109,112,114,101,115,115,32,100, + 97,116,97,59,32,122,108,105,98,32,110,111,116,32,97,118, + 97,105,108,97,98,108,101,84,114,0,0,0,0,169,1,218, + 10,100,101,99,111,109,112,114,101,115,115,70,122,25,122,105, + 112,105,109,112,111,114,116,58,32,122,108,105,98,32,97,118, + 97,105,108,97,98,108,101,41,7,218,15,95,105,109,112,111, + 114,116,105,110,103,95,122,108,105,98,114,76,0,0,0,114, + 77,0,0,0,114,3,0,0,0,90,4,122,108,105,98,114, + 142,0,0,0,218,9,69,120,99,101,112,116,105,111,110,114, + 141,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,20,95,103,101,116,95,100,101,99,111,109,112, + 114,101,115,115,95,102,117,110,99,254,1,0,0,115,24,0, + 0,0,0,2,4,3,10,1,8,2,4,1,4,1,16,1, + 14,1,10,1,18,2,6,2,10,1,114,145,0,0,0,99, + 2,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0, 9,0,0,0,67,0,0,0,115,130,1,0,0,124,1,92, 8,125,2,125,3,125,4,125,5,125,6,125,7,125,8,125, 9,124,4,100,1,107,0,114,36,116,0,100,2,131,1,130, @@ -770,84 +775,85 @@ const unsigned char _Py_M__zipimport[] = { 14,1,24,1,10,1,12,1,8,2,16,2,18,2,16,1, 16,1,12,1,8,1,2,1,14,1,16,1,24,1,10,1, 14,1,18,2,10,2,4,3,2,1,10,1,16,1,14,1, - 114,52,0,0,0,99,2,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,124,0,124,1,24,0,131,1,100,1,107,1,83,0,41, - 2,78,114,5,0,0,0,41,1,218,3,97,98,115,41,2, - 90,2,116,49,90,2,116,50,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,9,95,101,113,95,109,116,105, - 109,101,65,2,0,0,115,2,0,0,0,0,2,114,148,0, - 0,0,99,5,0,0,0,0,0,0,0,14,0,0,0,8, - 0,0,0,67,0,0,0,115,68,1,0,0,124,3,124,2, - 100,1,156,2,125,5,122,18,116,0,160,1,124,4,124,3, - 124,5,161,3,125,6,87,0,110,26,4,0,116,2,107,10, - 114,54,1,0,1,0,1,0,89,0,100,0,83,0,89,0, - 110,2,88,0,124,6,100,2,64,0,100,3,107,3,125,7, - 124,7,114,190,124,6,100,4,64,0,100,3,107,3,125,8, - 116,3,106,4,100,5,107,3,114,188,124,8,115,108,116,3, - 106,4,100,6,107,2,114,188,116,5,124,0,124,2,131,2, - 125,9,124,9,100,0,107,9,114,188,116,3,160,6,116,0, - 106,7,124,9,161,2,125,10,122,20,116,8,160,9,124,4, - 124,10,124,3,124,5,161,4,1,0,87,0,110,26,4,0, - 116,2,107,10,114,186,1,0,1,0,1,0,89,0,100,0, - 83,0,89,0,110,2,88,0,110,84,116,10,124,0,124,2, - 131,2,92,2,125,11,125,12,124,11,144,1,114,18,116,11, - 116,12,124,4,100,7,100,8,133,2,25,0,131,1,124,11, - 131,2,114,254,116,12,124,4,100,8,100,9,133,2,25,0, - 131,1,124,12,107,3,144,1,114,18,116,13,160,14,100,10, - 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,15, - 160,16,124,4,100,9,100,0,133,2,25,0,161,1,125,13, - 116,17,124,13,116,18,131,2,144,1,115,64,116,19,100,11, - 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0, - 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114, - 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5, - 110,101,118,101,114,90,6,97,108,119,97,121,115,114,100,0, - 0,0,114,95,0,0,0,114,96,0,0,0,122,22,98,121, - 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, - 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109, - 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,41,20,114, - 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21, - 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, - 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, - 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, - 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95, - 78,85,77,66,69,82,90,18,95,98,111,111,115,116,114,97, - 112,95,101,120,116,101,114,110,97,108,90,18,95,118,97,108, - 105,100,97,116,101,95,104,97,115,104,95,112,121,99,218,29, - 95,103,101,116,95,109,116,105,109,101,95,97,110,100,95,115, - 105,122,101,95,111,102,95,115,111,117,114,99,101,114,148,0, - 0,0,114,2,0,0,0,114,76,0,0,0,114,77,0,0, - 0,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, - 115,114,15,0,0,0,218,10,95,99,111,100,101,95,116,121, - 112,101,218,9,84,121,112,101,69,114,114,111,114,41,14,114, - 32,0,0,0,114,53,0,0,0,114,63,0,0,0,114,38, - 0,0,0,114,127,0,0,0,90,11,101,120,99,95,100,101, - 116,97,105,108,115,114,130,0,0,0,90,10,104,97,115,104, - 95,98,97,115,101,100,90,12,99,104,101,99,107,95,115,111, - 117,114,99,101,90,12,115,111,117,114,99,101,95,98,121,116, - 101,115,114,151,0,0,0,90,12,115,111,117,114,99,101,95, - 109,116,105,109,101,90,11,115,111,117,114,99,101,95,115,105, - 122,101,114,46,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,15,95,117,110,109,97,114,115,104, - 97,108,95,99,111,100,101,75,2,0,0,115,88,0,0,0, - 0,2,2,1,2,254,6,5,2,1,18,1,14,1,12,2, - 12,1,4,1,12,1,10,1,2,255,2,1,8,255,2,2, - 10,1,8,1,4,1,4,1,2,254,4,5,2,1,4,1, - 2,0,2,0,2,0,2,255,8,2,14,1,14,3,8,255, - 6,3,6,3,22,1,18,255,4,2,4,1,8,255,4,2, - 4,2,18,1,12,1,16,1,114,156,0,0,0,99,1,0, - 0,0,0,0,0,0,1,0,0,0,4,0,0,0,67,0, - 0,0,115,28,0,0,0,124,0,160,0,100,1,100,2,161, - 2,125,0,124,0,160,0,100,3,100,2,161,2,125,0,124, - 0,83,0,41,4,78,115,2,0,0,0,13,10,243,1,0, - 0,0,10,243,1,0,0,0,13,41,1,114,19,0,0,0, - 41,1,218,6,115,111,117,114,99,101,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,218,23,95,110,111,114,109, - 97,108,105,122,101,95,108,105,110,101,95,101,110,100,105,110, - 103,115,126,2,0,0,115,6,0,0,0,0,1,12,1,12, - 1,114,160,0,0,0,99,2,0,0,0,0,0,0,0,2, + 114,52,0,0,0,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,16, + 0,0,0,116,0,124,0,124,1,24,0,131,1,100,1,107, + 1,83,0,41,2,78,114,5,0,0,0,41,1,218,3,97, + 98,115,41,2,90,2,116,49,90,2,116,50,114,9,0,0, + 0,114,9,0,0,0,114,10,0,0,0,218,9,95,101,113, + 95,109,116,105,109,101,65,2,0,0,115,2,0,0,0,0, + 2,114,148,0,0,0,99,5,0,0,0,0,0,0,0,0, + 0,0,0,14,0,0,0,8,0,0,0,67,0,0,0,115, + 68,1,0,0,124,3,124,2,100,1,156,2,125,5,122,18, + 116,0,160,1,124,4,124,3,124,5,161,3,125,6,87,0, + 110,26,4,0,116,2,107,10,114,54,1,0,1,0,1,0, + 89,0,100,0,83,0,89,0,110,2,88,0,124,6,100,2, + 64,0,100,3,107,3,125,7,124,7,114,190,124,6,100,4, + 64,0,100,3,107,3,125,8,116,3,106,4,100,5,107,3, + 114,188,124,8,115,108,116,3,106,4,100,6,107,2,114,188, + 116,5,124,0,124,2,131,2,125,9,124,9,100,0,107,9, + 114,188,116,3,160,6,116,0,106,7,124,9,161,2,125,10, + 122,20,116,8,160,9,124,4,124,10,124,3,124,5,161,4, + 1,0,87,0,110,26,4,0,116,2,107,10,114,186,1,0, + 1,0,1,0,89,0,100,0,83,0,89,0,110,2,88,0, + 110,84,116,10,124,0,124,2,131,2,92,2,125,11,125,12, + 124,11,144,1,114,18,116,11,116,12,124,4,100,7,100,8, + 133,2,25,0,131,1,124,11,131,2,114,254,116,12,124,4, + 100,8,100,9,133,2,25,0,131,1,124,12,107,3,144,1, + 114,18,116,13,160,14,100,10,124,3,155,2,157,2,161,1, + 1,0,100,0,83,0,116,15,160,16,124,4,100,9,100,0, + 133,2,25,0,161,1,125,13,116,17,124,13,116,18,131,2, + 144,1,115,64,116,19,100,11,124,1,155,2,100,12,157,3, + 131,1,130,1,124,13,83,0,41,13,78,41,2,114,59,0, + 0,0,114,13,0,0,0,114,5,0,0,0,114,0,0,0, + 0,114,86,0,0,0,90,5,110,101,118,101,114,90,6,97, + 108,119,97,121,115,114,100,0,0,0,114,95,0,0,0,114, + 96,0,0,0,122,22,98,121,116,101,99,111,100,101,32,105, + 115,32,115,116,97,108,101,32,102,111,114,32,122,16,99,111, + 109,112,105,108,101,100,32,109,111,100,117,108,101,32,122,21, + 32,105,115,32,110,111,116,32,97,32,99,111,100,101,32,111, + 98,106,101,99,116,41,20,114,21,0,0,0,90,13,95,99, + 108,97,115,115,105,102,121,95,112,121,99,114,75,0,0,0, + 218,4,95,105,109,112,90,21,99,104,101,99,107,95,104,97, + 115,104,95,98,97,115,101,100,95,112,121,99,115,218,15,95, + 103,101,116,95,112,121,99,95,115,111,117,114,99,101,218,11, + 115,111,117,114,99,101,95,104,97,115,104,90,17,95,82,65, + 87,95,77,65,71,73,67,95,78,85,77,66,69,82,90,18, + 95,98,111,111,115,116,114,97,112,95,101,120,116,101,114,110, + 97,108,90,18,95,118,97,108,105,100,97,116,101,95,104,97, + 115,104,95,112,121,99,218,29,95,103,101,116,95,109,116,105, + 109,101,95,97,110,100,95,115,105,122,101,95,111,102,95,115, + 111,117,114,99,101,114,148,0,0,0,114,2,0,0,0,114, + 76,0,0,0,114,77,0,0,0,218,7,109,97,114,115,104, + 97,108,90,5,108,111,97,100,115,114,15,0,0,0,218,10, + 95,99,111,100,101,95,116,121,112,101,218,9,84,121,112,101, + 69,114,114,111,114,41,14,114,32,0,0,0,114,53,0,0, + 0,114,63,0,0,0,114,38,0,0,0,114,127,0,0,0, + 90,11,101,120,99,95,100,101,116,97,105,108,115,114,130,0, + 0,0,90,10,104,97,115,104,95,98,97,115,101,100,90,12, + 99,104,101,99,107,95,115,111,117,114,99,101,90,12,115,111, + 117,114,99,101,95,98,121,116,101,115,114,151,0,0,0,90, + 12,115,111,117,114,99,101,95,109,116,105,109,101,90,11,115, + 111,117,114,99,101,95,115,105,122,101,114,46,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,15, + 95,117,110,109,97,114,115,104,97,108,95,99,111,100,101,75, + 2,0,0,115,88,0,0,0,0,2,2,1,2,254,6,5, + 2,1,18,1,14,1,12,2,12,1,4,1,12,1,10,1, + 2,255,2,1,8,255,2,2,10,1,8,1,4,1,4,1, + 2,254,4,5,2,1,4,1,2,0,2,0,2,0,2,255, + 8,2,14,1,14,3,8,255,6,3,6,3,22,1,18,255, + 4,2,4,1,8,255,4,2,4,2,18,1,12,1,16,1, + 114,156,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,28, + 0,0,0,124,0,160,0,100,1,100,2,161,2,125,0,124, + 0,160,0,100,3,100,2,161,2,125,0,124,0,83,0,41, + 4,78,115,2,0,0,0,13,10,243,1,0,0,0,10,243, + 1,0,0,0,13,41,1,114,19,0,0,0,41,1,218,6, + 115,111,117,114,99,101,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,23,95,110,111,114,109,97,108,105,122, + 101,95,108,105,110,101,95,101,110,100,105,110,103,115,126,2, + 0,0,115,6,0,0,0,0,1,12,1,12,1,114,160,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, 0,0,0,6,0,0,0,67,0,0,0,115,24,0,0,0, 116,0,124,1,131,1,125,1,116,1,124,1,124,0,100,1, 100,2,100,3,141,4,83,0,41,4,78,114,74,0,0,0, @@ -857,56 +863,57 @@ const unsigned char _Py_M__zipimport[] = { 0,0,114,9,0,0,0,114,10,0,0,0,218,15,95,99, 111,109,112,105,108,101,95,115,111,117,114,99,101,133,2,0, 0,115,4,0,0,0,0,1,8,1,114,162,0,0,0,99, - 2,0,0,0,0,0,0,0,2,0,0,0,11,0,0,0, - 67,0,0,0,115,68,0,0,0,116,0,160,1,124,0,100, - 1,63,0,100,2,23,0,124,0,100,3,63,0,100,4,64, - 0,124,0,100,5,64,0,124,1,100,6,63,0,124,1,100, - 3,63,0,100,7,64,0,124,1,100,5,64,0,100,8,20, - 0,100,9,100,9,100,9,102,9,161,1,83,0,41,10,78, - 233,9,0,0,0,105,188,7,0,0,233,5,0,0,0,233, - 15,0,0,0,233,31,0,0,0,233,11,0,0,0,233,63, - 0,0,0,114,86,0,0,0,114,14,0,0,0,41,2,114, - 132,0,0,0,90,6,109,107,116,105,109,101,41,2,218,1, - 100,114,139,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,14,95,112,97,114,115,101,95,100,111, - 115,116,105,109,101,139,2,0,0,115,22,0,0,0,0,1, - 4,1,10,1,10,1,6,1,6,1,10,1,10,1,2,0, - 2,0,2,249,114,170,0,0,0,99,2,0,0,0,0,0, - 0,0,6,0,0,0,10,0,0,0,67,0,0,0,115,116, - 0,0,0,122,82,124,1,100,1,100,0,133,2,25,0,100, - 2,107,6,115,22,116,0,130,1,124,1,100,0,100,1,133, - 2,25,0,125,1,124,0,106,1,124,1,25,0,125,2,124, - 2,100,3,25,0,125,3,124,2,100,4,25,0,125,4,124, - 2,100,5,25,0,125,5,116,2,124,4,124,3,131,2,124, - 5,102,2,87,0,83,0,4,0,116,3,116,4,116,5,102, - 3,107,10,114,110,1,0,1,0,1,0,89,0,100,6,83, - 0,88,0,100,0,83,0,41,7,78,114,14,0,0,0,169, - 2,218,1,99,218,1,111,114,164,0,0,0,233,6,0,0, - 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0, - 0,0,41,6,218,14,65,115,115,101,114,116,105,111,110,69, - 114,114,111,114,114,28,0,0,0,114,170,0,0,0,114,26, - 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114, - 155,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,132,0,0,0,114,133,0,0,0,90, - 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105, - 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,152,0,0,0,152,2,0,0,115,20,0,0,0,0, - 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16, - 1,20,1,114,152,0,0,0,99,2,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,67,0,0,0,115,86,0, - 0,0,124,1,100,1,100,0,133,2,25,0,100,2,107,6, - 115,20,116,0,130,1,124,1,100,0,100,1,133,2,25,0, - 125,1,122,14,124,0,106,1,124,1,25,0,125,2,87,0, - 110,22,4,0,116,2,107,10,114,68,1,0,1,0,1,0, - 89,0,100,0,83,0,88,0,116,3,124,0,106,4,124,2, - 131,2,83,0,100,0,83,0,41,3,78,114,14,0,0,0, - 114,171,0,0,0,41,5,114,176,0,0,0,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0, - 41,3,114,32,0,0,0,114,13,0,0,0,114,54,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 114,150,0,0,0,171,2,0,0,115,14,0,0,0,0,2, - 20,1,12,2,2,1,14,1,14,1,8,2,114,150,0,0, - 0,99,2,0,0,0,0,0,0,0,11,0,0,0,9,0, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 11,0,0,0,67,0,0,0,115,68,0,0,0,116,0,160, + 1,124,0,100,1,63,0,100,2,23,0,124,0,100,3,63, + 0,100,4,64,0,124,0,100,5,64,0,124,1,100,6,63, + 0,124,1,100,3,63,0,100,7,64,0,124,1,100,5,64, + 0,100,8,20,0,100,9,100,9,100,9,102,9,161,1,83, + 0,41,10,78,233,9,0,0,0,105,188,7,0,0,233,5, + 0,0,0,233,15,0,0,0,233,31,0,0,0,233,11,0, + 0,0,233,63,0,0,0,114,86,0,0,0,114,14,0,0, + 0,41,2,114,132,0,0,0,90,6,109,107,116,105,109,101, + 41,2,218,1,100,114,139,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,14,95,112,97,114,115, + 101,95,100,111,115,116,105,109,101,139,2,0,0,115,22,0, + 0,0,0,1,4,1,10,1,10,1,6,1,6,1,10,1, + 10,1,2,0,2,0,2,249,114,170,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,6,0,0,0,10,0, + 0,0,67,0,0,0,115,116,0,0,0,122,82,124,1,100, + 1,100,0,133,2,25,0,100,2,107,6,115,22,116,0,130, + 1,124,1,100,0,100,1,133,2,25,0,125,1,124,0,106, + 1,124,1,25,0,125,2,124,2,100,3,25,0,125,3,124, + 2,100,4,25,0,125,4,124,2,100,5,25,0,125,5,116, + 2,124,4,124,3,131,2,124,5,102,2,87,0,83,0,4, + 0,116,3,116,4,116,5,102,3,107,10,114,110,1,0,1, + 0,1,0,89,0,100,6,83,0,88,0,100,0,83,0,41, + 7,78,114,14,0,0,0,169,2,218,1,99,218,1,111,114, + 164,0,0,0,233,6,0,0,0,233,3,0,0,0,41,2, + 114,0,0,0,0,114,0,0,0,0,41,6,218,14,65,115, + 115,101,114,116,105,111,110,69,114,114,111,114,114,28,0,0, + 0,114,170,0,0,0,114,26,0,0,0,218,10,73,110,100, + 101,120,69,114,114,111,114,114,155,0,0,0,41,6,114,32, + 0,0,0,114,13,0,0,0,114,54,0,0,0,114,132,0, + 0,0,114,133,0,0,0,90,17,117,110,99,111,109,112,114, + 101,115,115,101,100,95,115,105,122,101,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,152,0,0,0,152,2, + 0,0,115,20,0,0,0,0,1,2,2,20,1,12,1,10, + 3,8,1,8,1,8,1,16,1,20,1,114,152,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,86,0,0,0,124,1, + 100,1,100,0,133,2,25,0,100,2,107,6,115,20,116,0, + 130,1,124,1,100,0,100,1,133,2,25,0,125,1,122,14, + 124,0,106,1,124,1,25,0,125,2,87,0,110,22,4,0, + 116,2,107,10,114,68,1,0,1,0,1,0,89,0,100,0, + 83,0,88,0,116,3,124,0,106,4,124,2,131,2,83,0, + 100,0,83,0,41,3,78,114,14,0,0,0,114,171,0,0, + 0,41,5,114,176,0,0,0,114,28,0,0,0,114,26,0, + 0,0,114,52,0,0,0,114,29,0,0,0,41,3,114,32, + 0,0,0,114,13,0,0,0,114,54,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,150,0,0, + 0,171,2,0,0,115,14,0,0,0,0,2,20,1,12,2, + 2,1,14,1,14,1,8,2,114,150,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,11,0,0,0,9,0, 0,0,67,0,0,0,115,198,0,0,0,116,0,124,0,124, 1,131,2,125,2,116,1,68,0,93,160,92,3,125,3,125, 4,125,5,124,2,124,3,23,0,125,6,116,2,106,3,100, @@ -935,53 +942,54 @@ const unsigned char _Py_M__zipimport[] = { 2,0,0,115,36,0,0,0,0,1,10,1,14,1,8,1, 22,1,2,1,14,1,14,1,6,2,8,1,12,1,4,1, 18,2,10,1,8,3,2,1,8,1,16,2,114,44,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,64,0,0,0,115,60,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,90,4,100,3,100,4,132, - 0,90,5,100,5,100,6,132,0,90,6,100,7,100,8,132, - 0,90,7,100,9,100,10,132,0,90,8,100,11,100,12,132, - 0,90,9,100,13,83,0,41,14,114,80,0,0,0,122,165, - 80,114,105,118,97,116,101,32,99,108,97,115,115,32,117,115, - 101,100,32,116,111,32,115,117,112,112,111,114,116,32,90,105, - 112,73,109,112,111,114,116,46,103,101,116,95,114,101,115,111, - 117,114,99,101,95,114,101,97,100,101,114,40,41,46,10,10, - 32,32,32,32,84,104,105,115,32,99,108,97,115,115,32,105, - 115,32,97,108,108,111,119,101,100,32,116,111,32,114,101,102, - 101,114,101,110,99,101,32,97,108,108,32,116,104,101,32,105, - 110,110,97,114,100,115,32,97,110,100,32,112,114,105,118,97, - 116,101,32,112,97,114,116,115,32,111,102,10,32,32,32,32, - 116,104,101,32,122,105,112,105,109,112,111,114,116,101,114,46, - 10,32,32,32,32,70,99,3,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,124,2,124,0,95,1,100,0,83,0, - 114,88,0,0,0,41,2,114,4,0,0,0,114,38,0,0, - 0,41,3,114,32,0,0,0,114,4,0,0,0,114,38,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,34,0,0,0,220,2,0,0,115,4,0,0,0,0, - 1,6,1,122,33,95,90,105,112,73,109,112,111,114,116,82, - 101,115,111,117,114,99,101,82,101,97,100,101,114,46,95,95, - 105,110,105,116,95,95,99,2,0,0,0,0,0,0,0,5, - 0,0,0,8,0,0,0,67,0,0,0,115,92,0,0,0, - 124,0,106,0,160,1,100,1,100,2,161,2,125,2,124,2, - 155,0,100,2,124,1,155,0,157,3,125,3,100,3,100,4, - 108,2,109,3,125,4,1,0,122,18,124,4,124,0,106,4, - 160,5,124,3,161,1,131,1,87,0,83,0,4,0,116,6, - 107,10,114,86,1,0,1,0,1,0,116,7,124,3,131,1, - 130,1,89,0,110,2,88,0,100,0,83,0,41,5,78,114, - 85,0,0,0,114,110,0,0,0,114,0,0,0,0,41,1, - 218,7,66,121,116,101,115,73,79,41,8,114,38,0,0,0, - 114,19,0,0,0,90,2,105,111,114,178,0,0,0,114,4, - 0,0,0,114,55,0,0,0,114,22,0,0,0,218,17,70, - 105,108,101,78,111,116,70,111,117,110,100,69,114,114,111,114, - 41,5,114,32,0,0,0,218,8,114,101,115,111,117,114,99, - 101,218,16,102,117,108,108,110,97,109,101,95,97,115,95,112, - 97,116,104,114,13,0,0,0,114,178,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,13,111,112, - 101,110,95,114,101,115,111,117,114,99,101,224,2,0,0,115, - 14,0,0,0,0,1,14,1,14,1,12,1,2,1,18,1, - 14,1,122,38,95,90,105,112,73,109,112,111,114,116,82,101, - 115,111,117,114,99,101,82,101,97,100,101,114,46,111,112,101, - 110,95,114,101,115,111,117,114,99,101,99,2,0,0,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,64,0,0,0,115,60,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,100, + 3,100,4,132,0,90,5,100,5,100,6,132,0,90,6,100, + 7,100,8,132,0,90,7,100,9,100,10,132,0,90,8,100, + 11,100,12,132,0,90,9,100,13,83,0,41,14,114,80,0, + 0,0,122,165,80,114,105,118,97,116,101,32,99,108,97,115, + 115,32,117,115,101,100,32,116,111,32,115,117,112,112,111,114, + 116,32,90,105,112,73,109,112,111,114,116,46,103,101,116,95, + 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,40, + 41,46,10,10,32,32,32,32,84,104,105,115,32,99,108,97, + 115,115,32,105,115,32,97,108,108,111,119,101,100,32,116,111, + 32,114,101,102,101,114,101,110,99,101,32,97,108,108,32,116, + 104,101,32,105,110,110,97,114,100,115,32,97,110,100,32,112, + 114,105,118,97,116,101,32,112,97,114,116,115,32,111,102,10, + 32,32,32,32,116,104,101,32,122,105,112,105,109,112,111,114, + 116,101,114,46,10,32,32,32,32,70,99,3,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, + 0,0,0,115,16,0,0,0,124,1,124,0,95,0,124,2, + 124,0,95,1,100,0,83,0,114,88,0,0,0,41,2,114, + 4,0,0,0,114,38,0,0,0,41,3,114,32,0,0,0, + 114,4,0,0,0,114,38,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,34,0,0,0,220,2, + 0,0,115,4,0,0,0,0,1,6,1,122,33,95,90,105, + 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, + 101,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,8, + 0,0,0,67,0,0,0,115,92,0,0,0,124,0,106,0, + 160,1,100,1,100,2,161,2,125,2,124,2,155,0,100,2, + 124,1,155,0,157,3,125,3,100,3,100,4,108,2,109,3, + 125,4,1,0,122,18,124,4,124,0,106,4,160,5,124,3, + 161,1,131,1,87,0,83,0,4,0,116,6,107,10,114,86, + 1,0,1,0,1,0,116,7,124,3,131,1,130,1,89,0, + 110,2,88,0,100,0,83,0,41,5,78,114,85,0,0,0, + 114,110,0,0,0,114,0,0,0,0,41,1,218,7,66,121, + 116,101,115,73,79,41,8,114,38,0,0,0,114,19,0,0, + 0,90,2,105,111,114,178,0,0,0,114,4,0,0,0,114, + 55,0,0,0,114,22,0,0,0,218,17,70,105,108,101,78, + 111,116,70,111,117,110,100,69,114,114,111,114,41,5,114,32, + 0,0,0,218,8,114,101,115,111,117,114,99,101,218,16,102, + 117,108,108,110,97,109,101,95,97,115,95,112,97,116,104,114, + 13,0,0,0,114,178,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,13,111,112,101,110,95,114, + 101,115,111,117,114,99,101,224,2,0,0,115,14,0,0,0, + 0,1,14,1,14,1,12,1,2,1,18,1,14,1,122,38, + 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, + 99,101,82,101,97,100,101,114,46,111,112,101,110,95,114,101, + 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0, 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, 8,0,0,0,116,0,130,1,100,0,83,0,114,88,0,0, 0,41,1,114,179,0,0,0,41,2,114,32,0,0,0,114, @@ -990,86 +998,87 @@ const unsigned char _Py_M__zipimport[] = { 116,104,233,2,0,0,115,2,0,0,0,0,4,122,38,95, 90,105,112,73,109,112,111,114,116,82,101,115,111,117,114,99, 101,82,101,97,100,101,114,46,114,101,115,111,117,114,99,101, - 95,112,97,116,104,99,2,0,0,0,0,0,0,0,4,0, - 0,0,8,0,0,0,67,0,0,0,115,72,0,0,0,124, - 0,106,0,160,1,100,1,100,2,161,2,125,2,124,2,155, - 0,100,2,124,1,155,0,157,3,125,3,122,16,124,0,106, - 2,160,3,124,3,161,1,1,0,87,0,110,22,4,0,116, - 4,107,10,114,66,1,0,1,0,1,0,89,0,100,3,83, - 0,88,0,100,4,83,0,41,5,78,114,85,0,0,0,114, - 110,0,0,0,70,84,41,5,114,38,0,0,0,114,19,0, - 0,0,114,4,0,0,0,114,55,0,0,0,114,22,0,0, - 0,41,4,114,32,0,0,0,114,59,0,0,0,114,181,0, - 0,0,114,13,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,11,105,115,95,114,101,115,111,117, - 114,99,101,239,2,0,0,115,14,0,0,0,0,3,14,1, - 14,1,2,1,16,1,14,1,8,1,122,36,95,90,105,112, - 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, - 97,100,101,114,46,105,115,95,114,101,115,111,117,114,99,101, - 99,1,0,0,0,0,0,0,0,9,0,0,0,9,0,0, - 0,99,0,0,0,115,186,0,0,0,100,1,100,2,108,0, - 109,1,125,1,1,0,124,1,124,0,106,2,160,3,124,0, - 106,4,161,1,131,1,125,2,124,2,160,5,124,0,106,2, - 106,6,161,1,125,3,124,3,106,7,100,3,107,2,115,58, - 116,8,130,1,124,3,106,9,125,4,116,10,131,0,125,5, - 124,0,106,2,106,11,68,0,93,102,125,6,122,18,124,1, - 124,6,131,1,160,5,124,4,161,1,125,7,87,0,110,24, - 4,0,116,12,107,10,114,124,1,0,1,0,1,0,89,0, - 113,78,89,0,110,2,88,0,124,7,106,9,106,7,125,8, - 116,13,124,8,131,1,100,1,107,2,114,156,124,7,106,7, - 86,0,1,0,113,78,124,8,124,5,107,7,114,78,124,5, - 160,14,124,8,161,1,1,0,124,8,86,0,1,0,113,78, - 100,0,83,0,41,4,78,114,0,0,0,0,41,1,218,4, - 80,97,116,104,114,60,0,0,0,41,15,90,7,112,97,116, - 104,108,105,98,114,185,0,0,0,114,4,0,0,0,114,56, - 0,0,0,114,38,0,0,0,90,11,114,101,108,97,116,105, - 118,101,95,116,111,114,29,0,0,0,114,59,0,0,0,114, - 176,0,0,0,90,6,112,97,114,101,110,116,218,3,115,101, - 116,114,28,0,0,0,114,23,0,0,0,114,51,0,0,0, - 218,3,97,100,100,41,9,114,32,0,0,0,114,185,0,0, - 0,90,13,102,117,108,108,110,97,109,101,95,112,97,116,104, - 90,13,114,101,108,97,116,105,118,101,95,112,97,116,104,90, - 12,112,97,99,107,97,103,101,95,112,97,116,104,90,12,115, - 117,98,100,105,114,115,95,115,101,101,110,218,8,102,105,108, - 101,110,97,109,101,90,8,114,101,108,97,116,105,118,101,90, - 11,112,97,114,101,110,116,95,110,97,109,101,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,8,99,111,110, - 116,101,110,116,115,250,2,0,0,115,34,0,0,0,0,8, - 12,1,18,1,14,3,14,1,6,1,6,1,12,1,2,1, - 18,1,14,1,10,5,8,1,12,1,10,1,8,1,10,1, - 122,33,95,90,105,112,73,109,112,111,114,116,82,101,115,111, - 117,114,99,101,82,101,97,100,101,114,46,99,111,110,116,101, - 110,116,115,78,41,10,114,6,0,0,0,114,7,0,0,0, - 114,8,0,0,0,114,84,0,0,0,114,81,0,0,0,114, - 34,0,0,0,114,182,0,0,0,114,183,0,0,0,114,184, - 0,0,0,114,189,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,114,80,0,0, - 0,212,2,0,0,115,14,0,0,0,8,1,4,5,4,2, - 8,4,8,9,8,6,8,11,114,80,0,0,0,41,45,114, - 84,0,0,0,90,26,95,102,114,111,122,101,110,95,105,109, - 112,111,114,116,108,105,98,95,101,120,116,101,114,110,97,108, - 114,21,0,0,0,114,1,0,0,0,114,2,0,0,0,90, - 17,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, - 105,98,114,76,0,0,0,114,149,0,0,0,114,111,0,0, - 0,114,153,0,0,0,114,67,0,0,0,114,132,0,0,0, - 90,7,95,95,97,108,108,95,95,114,20,0,0,0,90,15, - 112,97,116,104,95,115,101,112,97,114,97,116,111,114,115,114, - 18,0,0,0,114,75,0,0,0,114,3,0,0,0,114,25, - 0,0,0,218,4,116,121,112,101,114,70,0,0,0,114,114, - 0,0,0,114,116,0,0,0,114,118,0,0,0,114,4,0, - 0,0,114,89,0,0,0,114,36,0,0,0,114,37,0,0, - 0,114,35,0,0,0,114,27,0,0,0,114,123,0,0,0, - 114,143,0,0,0,114,145,0,0,0,114,52,0,0,0,114, - 148,0,0,0,114,156,0,0,0,218,8,95,95,99,111,100, - 101,95,95,114,154,0,0,0,114,160,0,0,0,114,162,0, - 0,0,114,170,0,0,0,114,152,0,0,0,114,150,0,0, - 0,114,44,0,0,0,114,80,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, - 8,60,109,111,100,117,108,101,62,1,0,0,0,115,88,0, - 0,0,4,16,8,1,16,1,8,1,8,1,8,1,8,1, - 8,1,8,2,8,3,6,1,14,3,16,4,4,2,8,2, - 4,1,4,1,4,2,14,127,0,127,0,1,12,1,12,1, - 2,1,2,252,4,9,8,4,8,9,8,31,8,126,2,254, - 2,29,4,5,8,21,8,46,8,10,8,46,10,5,8,7, - 8,6,8,13,8,19,8,15,8,26, + 95,112,97,116,104,99,2,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,72, + 0,0,0,124,0,106,0,160,1,100,1,100,2,161,2,125, + 2,124,2,155,0,100,2,124,1,155,0,157,3,125,3,122, + 16,124,0,106,2,160,3,124,3,161,1,1,0,87,0,110, + 22,4,0,116,4,107,10,114,66,1,0,1,0,1,0,89, + 0,100,3,83,0,88,0,100,4,83,0,41,5,78,114,85, + 0,0,0,114,110,0,0,0,70,84,41,5,114,38,0,0, + 0,114,19,0,0,0,114,4,0,0,0,114,55,0,0,0, + 114,22,0,0,0,41,4,114,32,0,0,0,114,59,0,0, + 0,114,181,0,0,0,114,13,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,218,11,105,115,95,114, + 101,115,111,117,114,99,101,239,2,0,0,115,14,0,0,0, + 0,3,14,1,14,1,2,1,16,1,14,1,8,1,122,36, + 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, + 99,101,82,101,97,100,101,114,46,105,115,95,114,101,115,111, + 117,114,99,101,99,1,0,0,0,0,0,0,0,0,0,0, + 0,9,0,0,0,9,0,0,0,99,0,0,0,115,186,0, + 0,0,100,1,100,2,108,0,109,1,125,1,1,0,124,1, + 124,0,106,2,160,3,124,0,106,4,161,1,131,1,125,2, + 124,2,160,5,124,0,106,2,106,6,161,1,125,3,124,3, + 106,7,100,3,107,2,115,58,116,8,130,1,124,3,106,9, + 125,4,116,10,131,0,125,5,124,0,106,2,106,11,68,0, + 93,102,125,6,122,18,124,1,124,6,131,1,160,5,124,4, + 161,1,125,7,87,0,110,24,4,0,116,12,107,10,114,124, + 1,0,1,0,1,0,89,0,113,78,89,0,110,2,88,0, + 124,7,106,9,106,7,125,8,116,13,124,8,131,1,100,1, + 107,2,114,156,124,7,106,7,86,0,1,0,113,78,124,8, + 124,5,107,7,114,78,124,5,160,14,124,8,161,1,1,0, + 124,8,86,0,1,0,113,78,100,0,83,0,41,4,78,114, + 0,0,0,0,41,1,218,4,80,97,116,104,114,60,0,0, + 0,41,15,90,7,112,97,116,104,108,105,98,114,185,0,0, + 0,114,4,0,0,0,114,56,0,0,0,114,38,0,0,0, + 90,11,114,101,108,97,116,105,118,101,95,116,111,114,29,0, + 0,0,114,59,0,0,0,114,176,0,0,0,90,6,112,97, + 114,101,110,116,218,3,115,101,116,114,28,0,0,0,114,23, + 0,0,0,114,51,0,0,0,218,3,97,100,100,41,9,114, + 32,0,0,0,114,185,0,0,0,90,13,102,117,108,108,110, + 97,109,101,95,112,97,116,104,90,13,114,101,108,97,116,105, + 118,101,95,112,97,116,104,90,12,112,97,99,107,97,103,101, + 95,112,97,116,104,90,12,115,117,98,100,105,114,115,95,115, + 101,101,110,218,8,102,105,108,101,110,97,109,101,90,8,114, + 101,108,97,116,105,118,101,90,11,112,97,114,101,110,116,95, + 110,97,109,101,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,8,99,111,110,116,101,110,116,115,250,2,0, + 0,115,34,0,0,0,0,8,12,1,18,1,14,3,14,1, + 6,1,6,1,12,1,2,1,18,1,14,1,10,5,8,1, + 12,1,10,1,8,1,10,1,122,33,95,90,105,112,73,109, + 112,111,114,116,82,101,115,111,117,114,99,101,82,101,97,100, + 101,114,46,99,111,110,116,101,110,116,115,78,41,10,114,6, + 0,0,0,114,7,0,0,0,114,8,0,0,0,114,84,0, + 0,0,114,81,0,0,0,114,34,0,0,0,114,182,0,0, + 0,114,183,0,0,0,114,184,0,0,0,114,189,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,80,0,0,0,212,2,0,0,115,14,0, + 0,0,8,1,4,5,4,2,8,4,8,9,8,6,8,11, + 114,80,0,0,0,41,45,114,84,0,0,0,90,26,95,102, + 114,111,122,101,110,95,105,109,112,111,114,116,108,105,98,95, + 101,120,116,101,114,110,97,108,114,21,0,0,0,114,1,0, + 0,0,114,2,0,0,0,90,17,95,102,114,111,122,101,110, + 95,105,109,112,111,114,116,108,105,98,114,76,0,0,0,114, + 149,0,0,0,114,111,0,0,0,114,153,0,0,0,114,67, + 0,0,0,114,132,0,0,0,90,7,95,95,97,108,108,95, + 95,114,20,0,0,0,90,15,112,97,116,104,95,115,101,112, + 97,114,97,116,111,114,115,114,18,0,0,0,114,75,0,0, + 0,114,3,0,0,0,114,25,0,0,0,218,4,116,121,112, + 101,114,70,0,0,0,114,114,0,0,0,114,116,0,0,0, + 114,118,0,0,0,114,4,0,0,0,114,89,0,0,0,114, + 36,0,0,0,114,37,0,0,0,114,35,0,0,0,114,27, + 0,0,0,114,123,0,0,0,114,143,0,0,0,114,145,0, + 0,0,114,52,0,0,0,114,148,0,0,0,114,156,0,0, + 0,218,8,95,95,99,111,100,101,95,95,114,154,0,0,0, + 114,160,0,0,0,114,162,0,0,0,114,170,0,0,0,114, + 152,0,0,0,114,150,0,0,0,114,44,0,0,0,114,80, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,8,60,109,111,100,117,108,101, + 62,1,0,0,0,115,88,0,0,0,4,16,8,1,16,1, + 8,1,8,1,8,1,8,1,8,1,8,2,8,3,6,1, + 14,3,16,4,4,2,8,2,4,1,4,1,4,2,14,127, + 0,127,0,1,12,1,12,1,2,1,2,252,4,9,8,4, + 8,9,8,31,8,126,2,254,2,29,4,5,8,21,8,46, + 8,10,8,46,10,5,8,7,8,6,8,13,8,19,8,15, + 8,26, }; diff --git a/Python/marshal.c b/Python/marshal.c index 52932af225a..caaddfe9e44 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -530,6 +530,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) PyCodeObject *co = (PyCodeObject *)v; W_TYPE(TYPE_CODE, p); w_long(co->co_argcount, p); + w_long(co->co_posonlyargcount, p); w_long(co->co_kwonlyargcount, p); w_long(co->co_nlocals, p); w_long(co->co_stacksize, p); @@ -1322,6 +1323,7 @@ r_object(RFILE *p) case TYPE_CODE: { int argcount; + int posonlyargcount; int kwonlyargcount; int nlocals; int stacksize; @@ -1347,6 +1349,10 @@ r_object(RFILE *p) argcount = (int)r_long(p); if (PyErr_Occurred()) goto code_error; + posonlyargcount = (int)r_long(p); + if (PyErr_Occurred()) { + goto code_error; + } kwonlyargcount = (int)r_long(p); if (PyErr_Occurred()) goto code_error; @@ -1391,7 +1397,7 @@ r_object(RFILE *p) goto code_error; v = (PyObject *) PyCode_New( - argcount, kwonlyargcount, + argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, name, diff --git a/Python/pathconfig.c b/Python/pathconfig.c index 0ccb898e429..7fea7c36678 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -331,7 +331,7 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config) #endif if (path_config.isolated != -1) { - config->preconfig.isolated = path_config.isolated; + config->isolated = path_config.isolated; } if (path_config.site_import != -1) { config->site_import = path_config.site_import; @@ -394,7 +394,7 @@ pathconfig_global_init(void) _PyInitError err; _PyCoreConfig config = _PyCoreConfig_INIT; - err = _PyCoreConfig_Read(&config, NULL); + err = _PyCoreConfig_Read(&config); if (_Py_INIT_FAILED(err)) { goto error; } diff --git a/Python/preconfig.c b/Python/preconfig.c index 13e5e1e8579..48b9e8383aa 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -7,14 +7,17 @@ #define DECODE_LOCALE_ERR(NAME, LEN) \ (((LEN) == -2) \ - ? _Py_INIT_USER_ERR("cannot decode " NAME) \ + ? _Py_INIT_ERR("cannot decode " NAME) \ : _Py_INIT_NO_MEMORY()) /* --- File system encoding/errors -------------------------------- */ /* The filesystem encoding is chosen by config_init_fs_encoding(), - see also initfsencoding(). */ + see also initfsencoding(). + + Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors + are encoded to UTF-8. */ const char *Py_FileSystemDefaultEncoding = NULL; int Py_HasFileSystemDefaultEncoding = 0; const char *Py_FileSystemDefaultEncodeErrors = NULL; @@ -63,6 +66,7 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) /* --- _PyArgv ---------------------------------------------------- */ +/* Decode bytes_argv using Py_DecodeLocale() */ _PyInitError _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) { @@ -111,12 +115,149 @@ _PyPreCmdline_Clear(_PyPreCmdline *cmdline) _PyInitError -_PyPreCmdline_Init(_PyPreCmdline *cmdline, const _PyArgv *args) +_PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) { return _PyArgv_AsWstrList(args, &cmdline->argv); } +static void +_PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + if (config->ATTR != -1) { \ + cmdline->ATTR = config->ATTR; \ + } + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + +#undef COPY_ATTR +} + + +static void +_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + config->ATTR = cmdline->ATTR + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + +#undef COPY_ATTR +} + + +int +_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + config->ATTR = cmdline->ATTR + + if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) { + return -1; + } + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + return 0; + +#undef COPY_ATTR +} + + +/* Parse the command line arguments */ +static _PyInitError +precmdline_parse_cmdline(_PyPreCmdline *cmdline) +{ + _PyWstrList *argv = &cmdline->argv; + + _PyOS_ResetGetOpt(); + /* Don't log parsing errors into stderr here: _PyCoreConfig_Read() + is responsible for that */ + _PyOS_opterr = 0; + do { + int longindex = -1; + int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); + + if (c == EOF || c == 'c' || c == 'm') { + break; + } + + switch (c) { + case 'E': + cmdline->use_environment = 0; + break; + + case 'I': + cmdline->isolated = 1; + break; + + case 'X': + { + if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) { + return _Py_INIT_NO_MEMORY(); + } + break; + } + + default: + /* ignore other argument: + handled by _PyCoreConfig_Read() */ + break; + } + } while (1); + + return _Py_INIT_OK(); +} + + +_PyInitError +_PyPreCmdline_Read(_PyPreCmdline *cmdline, + const _PyPreConfig *preconfig) +{ + if (preconfig) { + _PyPreCmdline_GetPreConfig(cmdline, preconfig); + } + + _PyInitError err = precmdline_parse_cmdline(cmdline); + if (_Py_INIT_FAILED(err)) { + return err; + } + + /* isolated, use_environment */ + if (cmdline->isolated < 0) { + cmdline->isolated = 0; + } + if (cmdline->isolated > 0) { + cmdline->use_environment = 0; + } + if (cmdline->use_environment < 0) { + cmdline->use_environment = 0; + } + + /* dev_mode */ + if ((cmdline && _Py_get_xoption(&cmdline->xoptions, L"dev")) + || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE")) + { + cmdline->dev_mode = 1; + } + if (cmdline->dev_mode < 0) { + cmdline->dev_mode = 0; + } + + assert(cmdline->use_environment >= 0); + assert(cmdline->isolated >= 0); + assert(cmdline->dev_mode >= 0); + + return _Py_INIT_OK(); +} + + /* --- _PyPreConfig ----------------------------------------------- */ void @@ -145,13 +286,13 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) COPY_ATTR(isolated); COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); COPY_ATTR(coerce_c_locale); COPY_ATTR(coerce_c_locale_warn); #ifdef MS_WINDOWS COPY_ATTR(legacy_windows_fs_encoding); #endif COPY_ATTR(utf8_mode); - COPY_ATTR(dev_mode); COPY_STR_ATTR(allocator); #undef COPY_ATTR @@ -160,41 +301,114 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) } +PyObject* +_PyPreConfig_AsDict(const _PyPreConfig *config) +{ + PyObject *dict; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM(KEY, EXPR) \ + do { \ + PyObject *obj = (EXPR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) +#define SET_ITEM_INT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) +#define FROM_STRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromString(STR) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_STR(ATTR) \ + SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) + + SET_ITEM_INT(isolated); + SET_ITEM_INT(use_environment); + SET_ITEM_INT(coerce_c_locale); + SET_ITEM_INT(coerce_c_locale_warn); + SET_ITEM_INT(utf8_mode); +#ifdef MS_WINDOWS + SET_ITEM_INT(legacy_windows_fs_encoding); +#endif + SET_ITEM_INT(dev_mode); + SET_ITEM_STR(allocator); + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef FROM_STRING +#undef SET_ITEM +#undef SET_ITEM_INT +#undef SET_ITEM_STR +} + + void +_PyCoreConfig_GetCoreConfig(_PyPreConfig *config, + const _PyCoreConfig *core_config) +{ +#define COPY_ATTR(ATTR) \ + if (core_config->ATTR != -1) { \ + config->ATTR = core_config->ATTR; \ + } + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + +#undef COPY_ATTR +} + + +static void _PyPreConfig_GetGlobalConfig(_PyPreConfig *config) { #define COPY_FLAG(ATTR, VALUE) \ - if (config->ATTR == -1) { \ - config->ATTR = VALUE; \ - } + if (config->ATTR == -1) { \ + config->ATTR = VALUE; \ + } #define COPY_NOT_FLAG(ATTR, VALUE) \ - if (config->ATTR == -1) { \ - config->ATTR = !(VALUE); \ - } + if (config->ATTR == -1) { \ + config->ATTR = !(VALUE); \ + } COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif - COPY_FLAG(utf8_mode, Py_UTF8Mode); + if (Py_UTF8Mode > 0) { + config->utf8_mode = 1; + } #undef COPY_FLAG #undef COPY_NOT_FLAG } -void +static void _PyPreConfig_SetGlobalConfig(const _PyPreConfig *config) { #define COPY_FLAG(ATTR, VAR) \ - if (config->ATTR != -1) { \ - VAR = config->ATTR; \ - } + if (config->ATTR != -1) { \ + VAR = config->ATTR; \ + } #define COPY_NOT_FLAG(ATTR, VAR) \ - if (config->ATTR != -1) { \ - VAR = !config->ATTR; \ - } + if (config->ATTR != -1) { \ + VAR = !config->ATTR; \ + } COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); @@ -209,11 +423,11 @@ _PyPreConfig_SetGlobalConfig(const _PyPreConfig *config) const char* -_PyPreConfig_GetEnv(const _PyPreConfig *config, const char *name) +_Py_GetEnv(int use_environment, const char *name) { - assert(config->use_environment >= 0); + assert(use_environment >= 0); - if (!config->use_environment) { + if (!use_environment) { return NULL; } @@ -246,9 +460,9 @@ _Py_str_to_int(const char *str, int *result) void -_Py_get_env_flag(_PyPreConfig *config, int *flag, const char *name) +_Py_get_env_flag(int use_environment, int *flag, const char *name) { - const char *var = _PyPreConfig_GetEnv(config, name); + const char *var = _Py_GetEnv(use_environment, name); if (!var) { return; } @@ -287,6 +501,16 @@ _Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name) static _PyInitError preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) { +#ifdef MS_WINDOWS + if (config->legacy_windows_fs_encoding) { + config->utf8_mode = 0; + } +#endif + + if (config->utf8_mode >= 0) { + return _Py_INIT_OK(); + } + const wchar_t *xopt; if (cmdline) { xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); @@ -305,7 +529,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) config->utf8_mode = 0; } else { - return _Py_INIT_USER_ERR("invalid -X utf8 option value"); + return _Py_INIT_ERR("invalid -X utf8 option value"); } } else { @@ -314,7 +538,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) return _Py_INIT_OK(); } - const char *opt = _PyPreConfig_GetEnv(config, "PYTHONUTF8"); + const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8"); if (opt) { if (strcmp(opt, "1") == 0) { config->utf8_mode = 1; @@ -323,90 +547,12 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) config->utf8_mode = 0; } else { - return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment " - "variable value"); + return _Py_INIT_ERR("invalid PYTHONUTF8 environment " + "variable value"); } return _Py_INIT_OK(); } - return _Py_INIT_OK(); -} - - -static void -preconfig_init_locale(_PyPreConfig *config) -{ - /* Test also if coerce_c_locale equals 1: PYTHONCOERCECLOCALE=1 doesn't - imply that the C locale is always coerced. It is only coerced if - if the LC_CTYPE locale is "C". */ - if (config->coerce_c_locale != 0) { - /* The C locale enables the C locale coercion (PEP 538) */ - if (_Py_LegacyLocaleDetected()) { - config->coerce_c_locale = 1; - } - else { - config->coerce_c_locale = 0; - } - } -} - - -static _PyInitError -preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline) -{ - _PyPreConfig_GetGlobalConfig(config); - - /* isolated and use_environment */ - if (config->isolated > 0) { - config->use_environment = 0; - } - - /* Default values */ - if (config->use_environment < 0) { - config->use_environment = 0; - } - - /* legacy_windows_fs_encoding, utf8_mode, coerce_c_locale */ - if (config->use_environment) { -#ifdef MS_WINDOWS - _Py_get_env_flag(config, &config->legacy_windows_fs_encoding, - "PYTHONLEGACYWINDOWSFSENCODING"); -#endif - - const char *env = _PyPreConfig_GetEnv(config, "PYTHONCOERCECLOCALE"); - if (env) { - if (strcmp(env, "0") == 0) { - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 0; - } - } - else if (strcmp(env, "warn") == 0) { - config->coerce_c_locale_warn = 1; - } - else { - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 1; - } - } - } - } - -#ifdef MS_WINDOWS - if (config->legacy_windows_fs_encoding) { - config->utf8_mode = 0; - } -#endif - - if (config->utf8_mode < 0) { - _PyInitError err = preconfig_init_utf8_mode(config, cmdline); - if (_Py_INIT_FAILED(err)) { - return err; - } - } - - if (config->coerce_c_locale != 0) { - preconfig_init_locale(config); - } #ifndef MS_WINDOWS if (config->utf8_mode < 0) { @@ -421,33 +567,61 @@ preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline) } #endif - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 0; - } if (config->utf8_mode < 0) { config->utf8_mode = 0; } - if (config->coerce_c_locale < 0) { + return _Py_INIT_OK(); +} + + +static void +preconfig_init_coerce_c_locale(_PyPreConfig *config) +{ + const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE"); + if (env) { + if (strcmp(env, "0") == 0) { + if (config->coerce_c_locale < 0) { + config->coerce_c_locale = 0; + } + } + else if (strcmp(env, "warn") == 0) { + config->coerce_c_locale_warn = 1; + } + else { + if (config->coerce_c_locale < 0) { + config->coerce_c_locale = 1; + } + } + } + + /* Test if coerce_c_locale equals to -1 or equals to 1: + PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced. + It is only coerced if if the LC_CTYPE locale is "C". */ + if (config->coerce_c_locale == 0 || config->coerce_c_locale == 2) { + return; + } + + /* The C locale enables the C locale coercion (PEP 538) */ + if (_Py_LegacyLocaleDetected()) { + config->coerce_c_locale = 2; + } + else { config->coerce_c_locale = 0; } - /* dev_mode */ - if ((cmdline && _Py_get_xoption(&cmdline->xoptions, L"dev")) - || _PyPreConfig_GetEnv(config, "PYTHONDEVMODE")) - { - config->dev_mode = 1; - } - if (config->dev_mode < 0) { - config->dev_mode = 0; - } + assert(config->coerce_c_locale >= 0); +} - /* allocator */ + +static _PyInitError +preconfig_init_allocator(_PyPreConfig *config) +{ if (config->allocator == NULL) { /* bpo-34247. The PYTHONMALLOC environment variable has the priority over PYTHONDEV env var and "-X dev" command line option. For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory allocators to "malloc" (and not to "debug"). */ - const char *allocator = _PyPreConfig_GetEnv(config, "PYTHONMALLOC"); + const char *allocator = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); if (allocator) { config->allocator = _PyMem_RawStrdup(allocator); if (config->allocator == NULL) { @@ -462,8 +636,46 @@ preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline) return _Py_INIT_NO_MEMORY(); } } + return _Py_INIT_OK(); +} + + +static _PyInitError +preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline) +{ + _PyInitError err; + + err = _PyPreCmdline_Read(cmdline, config); + if (_Py_INIT_FAILED(err)) { + return err; + } + + _PyPreCmdline_SetPreConfig(cmdline, config); + + /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */ +#ifdef MS_WINDOWS + _Py_get_env_flag(config->use_environment, + &config->legacy_windows_fs_encoding, + "PYTHONLEGACYWINDOWSFSENCODING"); +#endif + + preconfig_init_coerce_c_locale(config); + + err = preconfig_init_utf8_mode(config, cmdline); + if (_Py_INIT_FAILED(err)) { + return err; + } + + /* allocator */ + err = preconfig_init_allocator(config); + if (_Py_INIT_FAILED(err)) { + return err; + } assert(config->coerce_c_locale >= 0); +#ifdef MS_WINDOWS + assert(config->legacy_windows_fs_encoding >= 0); +#endif assert(config->utf8_mode >= 0); assert(config->isolated >= 0); assert(config->use_environment >= 0); @@ -473,202 +685,14 @@ preconfig_read(_PyPreConfig *config, const _PyPreCmdline *cmdline) } -static _PyInitError -get_ctype_locale(char **locale_p) -{ - const char *loc = setlocale(LC_CTYPE, NULL); - if (loc == NULL) { - return _Py_INIT_ERR("failed to LC_CTYPE locale"); - } - - char *copy = _PyMem_RawStrdup(loc); - if (copy == NULL) { - return _Py_INIT_NO_MEMORY(); - } - - *locale_p = copy; - return _Py_INIT_OK(); -} - - -/* Read the configuration from: - - - environment variables - - Py_xxx global configuration variables - - the LC_CTYPE locale - - See _PyPreConfig_ReadFromArgv() to parse also command line arguments. */ -_PyInitError -_PyPreConfig_Read(_PyPreConfig *config) -{ - _PyInitError err; - char *old_loc; - - err = get_ctype_locale(&old_loc); - if (_Py_INIT_FAILED(err)) { - return err; - } - - /* Set LC_CTYPE to the user preferred locale */ - _Py_SetLocaleFromEnv(LC_CTYPE); - - err = preconfig_read(config, NULL); - - setlocale(LC_CTYPE, old_loc); - PyMem_RawFree(old_loc); - - return err; -} - - -void -_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config) -{ -#define COPY_ATTR(ATTR) \ - if (cmdline->ATTR != -1) { \ - config->ATTR = cmdline->ATTR; \ - } - - COPY_ATTR(use_environment); - COPY_ATTR(isolated); - -#undef COPY_ATTR -} - - -int -_PyPreConfig_AsDict(const _PyPreConfig *config, PyObject *dict) -{ -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define SET_ITEM_INT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_STR(ATTR) \ - SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) - - SET_ITEM_INT(isolated); - SET_ITEM_INT(use_environment); - SET_ITEM_INT(coerce_c_locale); - SET_ITEM_INT(coerce_c_locale_warn); - SET_ITEM_INT(utf8_mode); -#ifdef MS_WINDOWS - SET_ITEM_INT(legacy_windows_fs_encoding); -#endif - SET_ITEM_INT(dev_mode); - SET_ITEM_STR(allocator); - return 0; - -fail: - return -1; - -#undef FROM_STRING -#undef SET_ITEM -#undef SET_ITEM_INT -#undef SET_ITEM_STR -} - - -/* Parse the command line arguments */ -_PyInitError -_PyPreCmdline_Read(_PyPreCmdline *cmdline) -{ - _PyWstrList *argv = &cmdline->argv; - - _PyOS_ResetGetOpt(); - /* Don't log parsing errors into stderr here: _PyCoreConfig_ReadFromArgv() - is responsible for that */ - _PyOS_opterr = 0; - do { - int longindex = -1; - int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); - - if (c == EOF || c == 'c' || c == 'm') { - break; - } - - switch (c) { - case 'E': - cmdline->use_environment = 0; - break; - - case 'I': - cmdline->isolated = 1; - break; - - case 'X': - { - if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) { - return _Py_INIT_NO_MEMORY(); - } - break; - } - - default: - /* ignore other argument: - handled by _PyCoreConfig_ReadFromArgv() */ - break; - } - } while (1); - - return _Py_INIT_OK(); -} - - -static _PyInitError -preconfig_from_argv(_PyPreConfig *config, const _PyArgv *args) -{ - _PyInitError err; - - _PyPreCmdline cmdline = _PyPreCmdline_INIT; - - err = _PyPreCmdline_Init(&cmdline, args); - if (_Py_INIT_FAILED(err)) { - goto done; - } - - err = _PyPreCmdline_Read(&cmdline); - if (_Py_INIT_FAILED(err)) { - goto done; - } - - _PyPreCmdline_SetPreConfig(&cmdline, config); - - err = preconfig_read(config, &cmdline); - if (_Py_INIT_FAILED(err)) { - goto done; - } - err = _Py_INIT_OK(); - -done: - _PyPreCmdline_Clear(&cmdline); - return err; -} - - /* Read the configuration from: - command line arguments - environment variables - Py_xxx global configuration variables - - the LC_CTYPE locale - - See _PyPreConfig_ReadFromArgv() to parse also command line arguments. */ + - the LC_CTYPE locale */ _PyInitError -_PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args) +_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) { _PyInitError err; @@ -677,30 +701,43 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args) return err; } - char *init_ctype_locale = NULL; - int init_utf8_mode = Py_UTF8Mode; -#ifdef MS_WINDOWS - int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; -#endif - _PyPreConfig save_config = _PyPreConfig_INIT; - int locale_coerced = 0; - int loops = 0; - - err = get_ctype_locale(&init_ctype_locale); - if (_Py_INIT_FAILED(err)) { - goto done; - } - _PyPreConfig_GetGlobalConfig(config); + /* Copy LC_CTYPE locale, since it's modified later */ + const char *loc = setlocale(LC_CTYPE, NULL); + if (loc == NULL) { + return _Py_INIT_ERR("failed to LC_CTYPE locale"); + } + char *init_ctype_locale = _PyMem_RawStrdup(loc); + if (init_ctype_locale == NULL) { + return _Py_INIT_NO_MEMORY(); + } + + /* Save the config to be able to restore it if encodings change */ + _PyPreConfig save_config = _PyPreConfig_INIT; if (_PyPreConfig_Copy(&save_config, config) < 0) { - err = _Py_INIT_NO_MEMORY(); - goto done; + return _Py_INIT_NO_MEMORY(); } /* Set LC_CTYPE to the user preferred locale */ _Py_SetLocaleFromEnv(LC_CTYPE); + _PyPreCmdline cmdline = _PyPreCmdline_INIT; + int init_utf8_mode = Py_UTF8Mode; +#ifdef MS_WINDOWS + int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; +#endif + + if (args) { + err = _PyPreCmdline_SetArgv(&cmdline, args); + if (_Py_INIT_FAILED(err)) { + goto done; + } + } + + int locale_coerced = 0; + int loops = 0; + while (1) { int utf8_mode = config->utf8_mode; @@ -719,15 +756,11 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args) Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; #endif - err = preconfig_from_argv(config, args); + err = preconfig_read(config, &cmdline); if (_Py_INIT_FAILED(err)) { goto done; } - if (locale_coerced) { - config->coerce_c_locale = 1; - } - /* The legacy C locale assumes ASCII as the default text encoding, which * causes problems not only for the CPython runtime, but also other * components like GNU readline. @@ -787,6 +820,7 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args) #ifdef MS_WINDOWS Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; #endif + _PyPreCmdline_Clear(&cmdline); return err; } @@ -800,7 +834,7 @@ _PyPreConfig_SetAllocator(_PyPreConfig *config) PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (_PyMem_SetupAllocators(config->allocator) < 0) { - return _Py_INIT_USER_ERR("Unknown PYTHONMALLOC allocator"); + return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator"); } /* Copy the pre-configuration with the new allocator */ diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 994a94f1402..bd4d1d92662 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -59,13 +59,12 @@ extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward */ static _PyInitError add_main_module(PyInterpreterState *interp); -static _PyInitError initfsencoding(PyInterpreterState *interp); -static _PyInitError initsite(void); +static _PyInitError init_import_size(void); static _PyInitError init_sys_streams(PyInterpreterState *interp); -static _PyInitError initsigs(void); +static _PyInitError init_signals(void); static void call_py_exitfuncs(PyInterpreterState *); static void wait_for_thread_shutdown(void); -static void call_ll_exitfuncs(void); +static void call_ll_exitfuncs(_PyRuntimeState *runtime); int _Py_UnhandledKeyboardInterrupt = 0; _PyRuntimeState _PyRuntime = _PyRuntimeState_INIT; @@ -144,42 +143,8 @@ Py_IsInitialized(void) */ -static char* -get_codec_name(const char *encoding) -{ - const char *name_utf8; - char *name_str; - PyObject *codec, *name = NULL; - - codec = _PyCodec_Lookup(encoding); - if (!codec) - goto error; - - name = _PyObject_GetAttrId(codec, &PyId_name); - Py_CLEAR(codec); - if (!name) - goto error; - - name_utf8 = PyUnicode_AsUTF8(name); - if (name_utf8 == NULL) - goto error; - name_str = _PyMem_RawStrdup(name_utf8); - Py_DECREF(name); - if (name_str == NULL) { - PyErr_NoMemory(); - return NULL; - } - return name_str; - -error: - Py_XDECREF(codec); - Py_XDECREF(name); - return NULL; -} - - static _PyInitError -initimport(PyInterpreterState *interp, PyObject *sysmod) +init_importlib(PyInterpreterState *interp, PyObject *sysmod) { PyObject *importlib; PyObject *impmod; @@ -229,7 +194,7 @@ initimport(PyInterpreterState *interp, PyObject *sysmod) } static _PyInitError -initexternalimport(PyInterpreterState *interp) +init_importlib_external(PyInterpreterState *interp) { PyObject *value; value = PyObject_CallMethod(interp->importlib, @@ -286,9 +251,10 @@ static const char *_C_LOCALE_WARNING = "locales is recommended.\n"; static void -_emit_stderr_warning_for_legacy_locale(const _PyCoreConfig *core_config) +emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) { - if (core_config->preconfig.coerce_c_locale_warn && _Py_LegacyLocaleDetected()) { + const _PyPreConfig *preconfig = &runtime->preconfig; + if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected()) { PySys_FormatStderr("%s", _C_LOCALE_WARNING); } } @@ -365,8 +331,7 @@ _Py_CoerceLegacyLocale(int warn) const char *new_locale = setlocale(LC_CTYPE, target->locale_name); if (new_locale != NULL) { -#if !defined(__APPLE__) && !defined(__ANDROID__) && \ -defined(HAVE_LANGINFO_H) && defined(CODESET) +#if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET) /* Also ensure that nl_langinfo works in this locale */ char *codeset = nl_langinfo(CODESET); if (!codeset || *codeset == '\0') { @@ -457,7 +422,7 @@ _Py_SetLocaleFromEnv(int category) /* Global initializations. Can be undone by Py_Finalize(). Don't call this twice without an intervening Py_Finalize() call. - Every call to _Py_InitializeCore, Py_Initialize or Py_InitializeEx + Every call to _Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx must have a corresponding call to Py_Finalize. Locking: you must hold the interpreter lock while calling these APIs. @@ -467,9 +432,11 @@ _Py_SetLocaleFromEnv(int category) */ static _PyInitError -_Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p, +_Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, const _PyCoreConfig *core_config) { + _PyInitError err; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { return _Py_INIT_ERR("failed to read thread state"); @@ -481,15 +448,16 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p, } *interp_p = interp; - _PyCoreConfig_SetGlobalConfig(core_config); + _PyCoreConfig_Write(core_config, runtime); - if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + err = _PyCoreConfig_Copy(&interp->core_config, core_config); + if (_Py_INIT_FAILED(err)) { + return err; } core_config = &interp->core_config; if (core_config->_install_importlib) { - _PyInitError err = _PyCoreConfig_SetPathConfig(core_config); + err = _PyCoreConfig_SetPathConfig(core_config); if (_Py_INIT_FAILED(err)) { return err; } @@ -499,18 +467,14 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p, static _PyInitError -pycore_init_runtime(const _PyCoreConfig *core_config) +pycore_init_runtime(_PyRuntimeState *runtime, + const _PyCoreConfig *core_config) { - if (_PyRuntime.initialized) { + if (runtime->initialized) { return _Py_INIT_ERR("main interpreter already initialized"); } - _PyCoreConfig_SetGlobalConfig(core_config); - - _PyInitError err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; - } + _PyCoreConfig_Write(core_config, runtime); /* Py_Finalize leaves _Py_Finalizing set in order to help daemon * threads behave a little more gracefully at interpreter shutdown. @@ -521,14 +485,14 @@ pycore_init_runtime(const _PyCoreConfig *core_config) * threads still hanging around from a previous Py_Initialize/Finalize * pair :( */ - _PyRuntime.finalizing = NULL; + runtime->finalizing = NULL; - err = _Py_HashRandomization_Init(core_config); + _PyInitError err = _Py_HashRandomization_Init(core_config); if (_Py_INIT_FAILED(err)) { return err; } - err = _PyInterpreterState_Enable(&_PyRuntime); + err = _PyInterpreterState_Enable(runtime); if (_Py_INIT_FAILED(err)) { return err; } @@ -537,7 +501,8 @@ pycore_init_runtime(const _PyCoreConfig *core_config) static _PyInitError -pycore_create_interpreter(const _PyCoreConfig *core_config, +pycore_create_interpreter(_PyRuntimeState *runtime, + const _PyCoreConfig *core_config, PyInterpreterState **interp_p) { PyInterpreterState *interp = PyInterpreterState_New(); @@ -546,8 +511,9 @@ pycore_create_interpreter(const _PyCoreConfig *core_config, } *interp_p = interp; - if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + _PyInitError err = _PyCoreConfig_Copy(&interp->core_config, core_config); + if (_Py_INIT_FAILED(err)) { + return err; } core_config = &interp->core_config; @@ -564,7 +530,7 @@ pycore_create_interpreter(const _PyCoreConfig *core_config, _PyEval_FiniThreads(); /* Auto-thread-state API */ - _PyGILState_Init(interp, tstate); + _PyGILState_Init(runtime, interp, tstate); /* Create the GIL */ PyEval_InitThreads(); @@ -660,7 +626,7 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) /* This call sets up builtin and frozen import support */ if (interp->core_config._install_importlib) { - err = initimport(interp, sysmod); + err = init_importlib(interp, sysmod); if (_Py_INIT_FAILED(err)) { return err; } @@ -670,17 +636,20 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) static _PyInitError -_Py_InitializeCore_impl(PyInterpreterState **interp_p, +_Py_InitializeCore_impl(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, const _PyCoreConfig *core_config) { PyInterpreterState *interp; - _PyInitError err = pycore_init_runtime(core_config); + _PyCoreConfig_Write(core_config, runtime); + + _PyInitError err = pycore_init_runtime(runtime, core_config); if (_Py_INIT_FAILED(err)) { return err; } - err = pycore_create_interpreter(core_config, &interp); + err = pycore_create_interpreter(runtime, core_config, &interp); if (_Py_INIT_FAILED(err)) { return err; } @@ -693,7 +662,7 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, } PyObject *sysmod; - err = _PySys_Create(interp, &sysmod); + err = _PySys_Create(runtime, interp, &sysmod); if (_Py_INIT_FAILED(err)) { return err; } @@ -709,28 +678,13 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, } /* Only when we get here is the runtime core fully initialized */ - _PyRuntime.core_initialized = 1; + runtime->core_initialized = 1; return _Py_INIT_OK(); } _PyInitError -_Py_PreInitializeFromPreConfig(_PyPreConfig *config) -{ - if (config != NULL) { - _PyInitError err = _PyPreConfig_Write(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - } - - _PyRuntime.pre_initialized = 1; - return _Py_INIT_OK(); -} - - -static _PyInitError -pyinit_preconfig(_PyPreConfig *config, const _PyPreConfig *src_config) +_Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args) { _PyInitError err; @@ -738,54 +692,111 @@ pyinit_preconfig(_PyPreConfig *config, const _PyPreConfig *src_config) if (_Py_INIT_FAILED(err)) { return err; } + _PyRuntimeState *runtime = &_PyRuntime; - if (_PyPreConfig_Copy(config, src_config) < 0) { - return _Py_INIT_ERR("failed to copy pre config"); + if (runtime->pre_initialized) { + /* If it's already configured: ignored the new configuration */ + return _Py_INIT_OK(); } - err = _PyPreConfig_Read(config); + _PyPreConfig config = _PyPreConfig_INIT; + + if (src_config) { + if (_PyPreConfig_Copy(&config, src_config) < 0) { + err = _Py_INIT_NO_MEMORY(); + goto done; + } + } + + err = _PyPreConfig_Read(&config, args); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } - return _Py_PreInitializeFromPreConfig(config); + err = _PyPreConfig_Write(&config); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + runtime->pre_initialized = 1; + err = _Py_INIT_OK(); + +done: + _PyPreConfig_Clear(&config); + return err; } _PyInitError -_Py_PreInitialize(void) +_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv) { - _PyInitError err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; - } + _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; + return _Py_PreInitializeFromPyArgv(src_config, &args); +} - if (_PyRuntime.pre_initialized) { - return _Py_INIT_OK(); - } - return _Py_PreInitializeFromPreConfig(NULL); +_PyInitError +_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, int argc, wchar_t **argv) +{ + _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; + return _Py_PreInitializeFromPyArgv(src_config, &args); +} + + +_PyInitError +_Py_PreInitialize(const _PyPreConfig *src_config) +{ + return _Py_PreInitializeFromPyArgv(src_config, NULL); +} + + +_PyInitError +_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig, + const _PyArgv *args) +{ + _PyPreConfig config = _PyPreConfig_INIT; + if (coreconfig != NULL) { + _PyCoreConfig_GetCoreConfig(&config, coreconfig); + } + return _Py_PreInitializeFromPyArgv(&config, args); + /* No need to clear config: + _PyCoreConfig_GetCoreConfig() doesn't allocate memory */ } static _PyInitError -pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config, +pyinit_coreconfig(_PyRuntimeState *runtime, + _PyCoreConfig *config, + const _PyCoreConfig *src_config, + const _PyArgv *args, PyInterpreterState **interp_p) { - if (_PyCoreConfig_Copy(config, src_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + _PyInitError err; + + if (src_config) { + err = _PyCoreConfig_Copy(config, src_config); + if (_Py_INIT_FAILED(err)) { + return err; + } } - _PyInitError err = _PyCoreConfig_Read(config, NULL); + if (args) { + err = _PyCoreConfig_SetPyArgv(config, args); + if (_Py_INIT_FAILED(err)) { + return err; + } + } + + err = _PyCoreConfig_Read(config); if (_Py_INIT_FAILED(err)) { return err; } - if (!_PyRuntime.core_initialized) { - return _Py_InitializeCore_impl(interp_p, config); + if (!runtime->core_initialized) { + return _Py_InitializeCore_impl(runtime, interp_p, config); } else { - return _Py_Initialize_ReconfigureCore(interp_p, config); + return _Py_Initialize_ReconfigureCore(runtime, interp_p, config); } } @@ -807,40 +818,43 @@ pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config, * to the Python C API (unless the API is explicitly listed as being * safe to call without calling Py_Initialize first) */ -_PyInitError -_Py_InitializeCore(PyInterpreterState **interp_p, - const _PyCoreConfig *src_config) +static _PyInitError +_Py_InitializeCore(_PyRuntimeState *runtime, + const _PyCoreConfig *src_config, + const _PyArgv *args, + PyInterpreterState **interp_p) { _PyInitError err; - assert(src_config != NULL); - - _PyCoreConfig local_config = _PyCoreConfig_INIT; - - err = pyinit_preconfig(&local_config.preconfig, &src_config->preconfig); + err = _Py_PreInitializeFromCoreConfig(src_config, args); if (_Py_INIT_FAILED(err)) { - goto done; + return err; } - err = pyinit_coreconfig(&local_config, src_config, interp_p); - -done: + _PyCoreConfig local_config = _PyCoreConfig_INIT; + err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p); _PyCoreConfig_Clear(&local_config); return err; } + /* Py_Initialize() has already been called: update the main interpreter configuration. Example of bpo-34008: Py_Main() called after Py_Initialize(). */ static _PyInitError -_Py_ReconfigureMainInterpreter(PyInterpreterState *interp, - const _PyMainInterpreterConfig *config) +_Py_ReconfigureMainInterpreter(PyInterpreterState *interp) { - if (config->argv != NULL) { - int res = PyDict_SetItemString(interp->sysdict, "argv", config->argv); - if (res < 0) { - return _Py_INIT_ERR("fail to set sys.argv"); - } + _PyCoreConfig *core_config = &interp->core_config; + + PyObject *argv = _PyWstrList_AsList(&core_config->argv); + if (argv == NULL) { + return _Py_INIT_NO_MEMORY(); \ + } + + int res = PyDict_SetItemString(interp->sysdict, "argv", argv); + Py_DECREF(argv); + if (res < 0) { + return _Py_INIT_ERR("fail to set sys.argv"); } return _Py_INIT_OK(); } @@ -856,23 +870,19 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp, * Other errors should be reported as normal Python exceptions with a * non-zero return code. */ -_PyInitError -_Py_InitializeMainInterpreter(PyInterpreterState *interp, - const _PyMainInterpreterConfig *config) +static _PyInitError +_Py_InitializeMainInterpreter(_PyRuntimeState *runtime, + PyInterpreterState *interp) { - if (!_PyRuntime.core_initialized) { + if (!runtime->core_initialized) { return _Py_INIT_ERR("runtime core not initialized"); } /* Configure the main interpreter */ - if (_PyMainInterpreterConfig_Copy(&interp->config, config) < 0) { - return _Py_INIT_ERR("failed to copy main interpreter config"); - } - config = &interp->config; _PyCoreConfig *core_config = &interp->core_config; - if (_PyRuntime.initialized) { - return _Py_ReconfigureMainInterpreter(interp, config); + if (runtime->initialized) { + return _Py_ReconfigureMainInterpreter(interp); } if (!core_config->_install_importlib) { @@ -881,7 +891,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, * This means anything which needs support from extension modules * or pure Python code in the standard library won't work. */ - _PyRuntime.initialized = 1; + runtime->initialized = 1; return _Py_INIT_OK(); } @@ -889,11 +899,11 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, return _Py_INIT_ERR("can't initialize time"); } - if (_PySys_InitMain(interp) < 0) { + if (_PySys_InitMain(runtime, interp) < 0) { return _Py_INIT_ERR("can't finish initializing sys"); } - _PyInitError err = initexternalimport(interp); + _PyInitError err = init_importlib_external(interp); if (_Py_INIT_FAILED(err)) { return err; } @@ -904,13 +914,13 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, return err; } - err = initfsencoding(interp); + err = _PyUnicode_InitEncodings(interp); if (_Py_INIT_FAILED(err)) { return err; } - if (interp->config.install_signal_handlers) { - err = initsigs(); /* Signal handling stuff, including initintr() */ + if (core_config->install_signal_handlers) { + err = init_signals(); if (_Py_INIT_FAILED(err)) { return err; } @@ -942,17 +952,17 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, Py_XDECREF(warnings_module); } - _PyRuntime.initialized = 1; + runtime->initialized = 1; if (core_config->site_import) { - err = initsite(); /* Module site */ + err = init_import_size(); /* Module site */ if (_Py_INIT_FAILED(err)) { return err; } } #ifndef MS_WINDOWS - _emit_stderr_warning_for_legacy_locale(core_config); + emit_stderr_warning_for_legacy_locale(runtime); #endif return _Py_INIT_OK(); @@ -960,45 +970,78 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, #undef _INIT_DEBUG_PRINT -_PyInitError -_Py_InitializeFromConfig(const _PyCoreConfig *config) +static _PyInitError +init_python(const _PyCoreConfig *config, const _PyArgv *args) { - PyInterpreterState *interp = NULL; _PyInitError err; - err = _Py_InitializeCore(&interp, config); + + err = _PyRuntime_Initialize(); + if (_Py_INIT_FAILED(err)) { + return err; + } + _PyRuntimeState *runtime = &_PyRuntime; + + PyInterpreterState *interp = NULL; + err = _Py_InitializeCore(runtime, config, args, &interp); if (_Py_INIT_FAILED(err)) { return err; } config = &interp->core_config; - _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT; - err = _PyMainInterpreterConfig_Read(&main_config, config); - if (!_Py_INIT_FAILED(err)) { - err = _Py_InitializeMainInterpreter(interp, &main_config); - } - _PyMainInterpreterConfig_Clear(&main_config); - if (_Py_INIT_FAILED(err)) { - return err; + if (!config->_frozen) { + err = _Py_InitializeMainInterpreter(runtime, interp); + if (_Py_INIT_FAILED(err)) { + return err; + } } + return _Py_INIT_OK(); } +_PyInitError +_Py_InitializeFromArgs(const _PyCoreConfig *config, int argc, char **argv) +{ + _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; + return init_python(config, &args); +} + + +_PyInitError +_Py_InitializeFromWideArgs(const _PyCoreConfig *config, int argc, wchar_t **argv) +{ + _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; + return init_python(config, &args); +} + + +_PyInitError +_Py_InitializeFromConfig(const _PyCoreConfig *config) +{ + return init_python(config, NULL); +} + + void Py_InitializeEx(int install_sigs) { - if (_PyRuntime.initialized) { + _PyInitError err; + + err = _PyRuntime_Initialize(); + if (_Py_INIT_FAILED(err)) { + _Py_ExitInitError(err); + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (runtime->initialized) { /* bpo-33932: Calling Py_Initialize() twice does nothing. */ return; } - _PyInitError err; _PyCoreConfig config = _PyCoreConfig_INIT; config.install_signal_handlers = install_sigs; err = _Py_InitializeFromConfig(&config); - _PyCoreConfig_Clear(&config); - if (_Py_INIT_FAILED(err)) { _Py_ExitInitError(err); } @@ -1081,23 +1124,23 @@ flush_std_files(void) int Py_FinalizeEx(void) { - PyInterpreterState *interp; - PyThreadState *tstate; int status = 0; - if (!_PyRuntime.initialized) + _PyRuntimeState *runtime = &_PyRuntime; + if (!runtime->initialized) { return status; + } // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(); - /* Get current thread state and interpreter pointer */ - tstate = _PyThreadState_GET(); - interp = tstate->interp; - // Make any remaining pending calls. _Py_FinishPendingCalls(); + /* Get current thread state and interpreter pointer */ + PyThreadState *tstate = _PyThreadState_GET(); + PyInterpreterState *interp = tstate->interp; + /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread * or exit func is still waiting to do an import, the import machinery @@ -1124,9 +1167,9 @@ Py_FinalizeEx(void) /* Remaining threads (e.g. daemon threads) will automatically exit after taking the GIL (in PyEval_RestoreThread()). */ - _PyRuntime.finalizing = tstate; - _PyRuntime.initialized = 0; - _PyRuntime.core_initialized = 0; + runtime->finalizing = tstate; + runtime->initialized = 0; + runtime->core_initialized = 0; /* Flush sys.stdout and sys.stderr */ if (flush_std_files() < 0) { @@ -1244,7 +1287,8 @@ Py_FinalizeEx(void) PyFloat_Fini(); PyDict_Fini(); PySlice_Fini(); - _PyGC_Fini(); + _PyGC_Fini(runtime); + _PyWarnings_Fini(runtime); _Py_HashRandomization_Fini(); _PyArg_Fini(); PyAsyncGen_Fini(); @@ -1264,7 +1308,7 @@ Py_FinalizeEx(void) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); /* Cleanup auto-thread-state */ - _PyGILState_Fini(); + _PyGILState_Fini(runtime); /* Delete current thread. After this, many C API calls become crashy. */ PyThreadState_Swap(NULL); @@ -1286,7 +1330,7 @@ Py_FinalizeEx(void) } #endif - call_ll_exitfuncs(); + call_ll_exitfuncs(runtime); _PyRuntime_Finalize(); return status; @@ -1314,12 +1358,15 @@ Py_Finalize(void) static _PyInitError new_interpreter(PyThreadState **tstate_p) { - PyInterpreterState *interp; - PyThreadState *tstate, *save_tstate; - PyObject *bimod, *sysmod; _PyInitError err; - if (!_PyRuntime.initialized) { + err = _PyRuntime_Initialize(); + if (_Py_INIT_FAILED(err)) { + return err; + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (!runtime->initialized) { return _Py_INIT_ERR("Py_Initialize must be called first"); } @@ -1327,41 +1374,36 @@ new_interpreter(PyThreadState **tstate_p) interpreters: disable PyGILState_Check(). */ _PyGILState_check_enabled = 0; - interp = PyInterpreterState_New(); + PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { *tstate_p = NULL; return _Py_INIT_OK(); } - tstate = PyThreadState_New(interp); + PyThreadState *tstate = PyThreadState_New(interp); if (tstate == NULL) { PyInterpreterState_Delete(interp); *tstate_p = NULL; return _Py_INIT_OK(); } - save_tstate = PyThreadState_Swap(tstate); + PyThreadState *save_tstate = PyThreadState_Swap(tstate); /* Copy the current interpreter config into the new interpreter */ _PyCoreConfig *core_config; - _PyMainInterpreterConfig *config; if (save_tstate != NULL) { core_config = &save_tstate->interp->core_config; - config = &save_tstate->interp->config; } else { /* No current thread state, copy from the main interpreter */ PyInterpreterState *main_interp = PyInterpreterState_Main(); core_config = &main_interp->core_config; - config = &main_interp->config; } - if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + err = _PyCoreConfig_Copy(&interp->core_config, core_config); + if (_Py_INIT_FAILED(err)) { + return err; } core_config = &interp->core_config; - if (_PyMainInterpreterConfig_Copy(&interp->config, config) < 0) { - return _Py_INIT_ERR("failed to copy main interpreter config"); - } err = _PyExc_Init(); if (_Py_INIT_FAILED(err)) { @@ -1375,14 +1417,15 @@ new_interpreter(PyThreadState **tstate_p) } interp->modules = modules; - sysmod = _PyImport_FindBuiltin("sys", modules); + PyObject *sysmod = _PyImport_FindBuiltin("sys", modules); if (sysmod != NULL) { interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) + if (interp->sysdict == NULL) { goto handle_error; + } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(interp) < 0) { + if (_PySys_InitMain(runtime, interp) < 0) { return _Py_INIT_ERR("can't finish initializing sys"); } } @@ -1390,7 +1433,7 @@ new_interpreter(PyThreadState **tstate_p) goto handle_error; } - bimod = _PyImport_FindBuiltin("builtins", modules); + PyObject *bimod = _PyImport_FindBuiltin("builtins", modules); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) @@ -1417,17 +1460,17 @@ new_interpreter(PyThreadState **tstate_p) return err; } - err = initimport(interp, sysmod); + err = init_importlib(interp, sysmod); if (_Py_INIT_FAILED(err)) { return err; } - err = initexternalimport(interp); + err = init_importlib_external(interp); if (_Py_INIT_FAILED(err)) { return err; } - err = initfsencoding(interp); + err = _PyUnicode_InitEncodings(interp); if (_Py_INIT_FAILED(err)) { return err; } @@ -1443,7 +1486,7 @@ new_interpreter(PyThreadState **tstate_p) } if (core_config->site_import) { - err = initsite(); + err = init_import_size(); if (_Py_INIT_FAILED(err)) { return err; } @@ -1569,47 +1612,15 @@ add_main_module(PyInterpreterState *interp) return _Py_INIT_OK(); } -static _PyInitError -initfsencoding(PyInterpreterState *interp) -{ - _PyCoreConfig *config = &interp->core_config; - - char *encoding = get_codec_name(config->filesystem_encoding); - if (encoding == NULL) { - /* Such error can only occurs in critical situations: no more - memory, import a module of the standard library failed, etc. */ - return _Py_INIT_ERR("failed to get the Python codec " - "of the filesystem encoding"); - } - - /* Update the filesystem encoding to the normalized Python codec name. - For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii" - (Python codec name). */ - PyMem_RawFree(config->filesystem_encoding); - config->filesystem_encoding = encoding; - - /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors - global configuration variables. */ - if (_Py_SetFileSystemEncoding(config->filesystem_encoding, - config->filesystem_errors) < 0) { - return _Py_INIT_NO_MEMORY(); - } - - /* PyUnicode can now use the Python codec rather than C implementation - for the filesystem encoding */ - interp->fscodec_initialized = 1; - return _Py_INIT_OK(); -} - /* Import the site module (not into __main__ though) */ static _PyInitError -initsite(void) +init_import_size(void) { PyObject *m; m = PyImport_ImportModule("site"); if (m == NULL) { - return _Py_INIT_USER_ERR("Failed to import the site module"); + return _Py_INIT_ERR("Failed to import the site module"); } Py_DECREF(m); return _Py_INIT_OK(); @@ -1620,26 +1631,34 @@ initsite(void) static int is_valid_fd(int fd) { -#ifdef __APPLE__ - /* bpo-30225: On macOS Tiger, when stdout is redirected to a pipe - and the other side of the pipe is closed, dup(1) succeed, whereas - fstat(1, &st) fails with EBADF. Prefer fstat() over dup() to detect - such error. */ +/* dup() is faster than fstat(): fstat() can require input/output operations, + whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python + startup. Problem: dup() doesn't check if the file descriptor is valid on + some platforms. + + bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other + side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with + EBADF. FreeBSD has similar issue (bpo-32849). + + Only use dup() on platforms where dup() is enough to detect invalid FD in + corner cases: on Linux and Windows (bpo-32849). */ +#if defined(__linux__) || defined(MS_WINDOWS) + if (fd < 0) { + return 0; + } + int fd2; + + _Py_BEGIN_SUPPRESS_IPH + fd2 = dup(fd); + if (fd2 >= 0) { + close(fd2); + } + _Py_END_SUPPRESS_IPH + + return (fd2 >= 0); +#else struct stat st; return (fstat(fd, &st) == 0); -#else - int fd2; - if (fd < 0) - return 0; - _Py_BEGIN_SUPPRESS_IPH - /* Prefer dup() over fstat(). fstat() can require input/output whereas - dup() doesn't, there is a low risk of EMFILE/ENFILE at Python - startup. */ - fd2 = dup(fd); - if (fd2 >= 0) - close(fd2); - _Py_END_SUPPRESS_IPH - return fd2 >= 0; #endif } @@ -1647,7 +1666,7 @@ is_valid_fd(int fd) static PyObject* create_stdio(const _PyCoreConfig *config, PyObject* io, int fd, int write_mode, const char* name, - const char* encoding, const char* errors) + const wchar_t* encoding, const wchar_t* errors) { PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; const char* mode; @@ -1697,7 +1716,7 @@ create_stdio(const _PyCoreConfig *config, PyObject* io, #ifdef MS_WINDOWS /* Windows console IO is always UTF-8 encoded */ if (PyWindowsConsoleIO_Check(raw)) - encoding = "utf-8"; + encoding = L"utf-8"; #endif text = PyUnicode_FromString(name); @@ -1733,10 +1752,25 @@ create_stdio(const _PyCoreConfig *config, PyObject* io, newline = "\n"; #endif - stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssOO", - buf, encoding, errors, + PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1); + if (encoding_str == NULL) { + Py_CLEAR(buf); + goto error; + } + + PyObject *errors_str = PyUnicode_FromWideChar(errors, -1); + if (errors_str == NULL) { + Py_CLEAR(buf); + Py_CLEAR(encoding_str); + goto error; + } + + stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OOOsOO", + buf, encoding_str, errors_str, newline, line_buffering, write_through); Py_CLEAR(buf); + Py_CLEAR(encoding_str); + Py_CLEAR(errors_str); if (stream == NULL) goto error; @@ -1788,19 +1822,10 @@ init_sys_streams(PyInterpreterState *interp) struct _Py_stat_struct sb; if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode)) { - return _Py_INIT_USER_ERR(" is a directory, " - "cannot continue"); + return _Py_INIT_ERR(" is a directory, cannot continue"); } #endif - char *codec_name = get_codec_name(config->stdio_encoding); - if (codec_name == NULL) { - return _Py_INIT_ERR("failed to get the Python codec name " - "of the stdio encoding"); - } - PyMem_RawFree(config->stdio_encoding); - config->stdio_encoding = codec_name; - /* Hack to avoid a nasty recursion issue when Python is invoked in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { @@ -1862,7 +1887,7 @@ init_sys_streams(PyInterpreterState *interp) fd = fileno(stderr); std = create_stdio(config, iomod, fd, 1, "", config->stdio_encoding, - "backslashreplace"); + L"backslashreplace"); if (std == NULL) goto error; @@ -2097,14 +2122,17 @@ Py_FatalError(const char *msg) void _Py_NO_RETURN _Py_ExitInitError(_PyInitError err) { - if (err.exitcode >= 0) { + assert(_Py_INIT_FAILED(err)); + if (_Py_INIT_IS_EXIT(err)) { +#ifdef MS_WINDOWS + ExitProcess(err.exitcode); +#else exit(err.exitcode); +#endif } else { - /* On "user" error: exit with status 1. - For all other errors, call abort(). */ - int status = err.user_err ? 1 : -1; - fatal_error(err.prefix, err.msg, status); + assert(_Py_INIT_IS_ERROR(err)); + fatal_error(err._func, err.err_msg, 1); } } @@ -2145,8 +2173,10 @@ wait_for_thread_shutdown(void) PyObject *result; PyObject *threading = _PyImport_GetModuleId(&PyId_threading); if (threading == NULL) { - /* threading not imported */ - PyErr_Clear(); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(NULL); + } + /* else: threading not imported */ return; } result = _PyObject_CallMethodId(threading, &PyId__shutdown, NULL); @@ -2169,10 +2199,16 @@ int Py_AtExit(void (*func)(void)) } static void -call_ll_exitfuncs(void) +call_ll_exitfuncs(_PyRuntimeState *runtime) { - while (_PyRuntime.nexitfuncs > 0) - (*_PyRuntime.exitfuncs[--_PyRuntime.nexitfuncs])(); + while (runtime->nexitfuncs > 0) { + /* pop last function from the list */ + runtime->nexitfuncs--; + void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs]; + runtime->exitfuncs[runtime->nexitfuncs] = NULL; + + exitfunc(); + } fflush(stdout); fflush(stderr); @@ -2189,7 +2225,7 @@ Py_Exit(int sts) } static _PyInitError -initsigs(void) +init_signals(void) { #ifdef SIGPIPE PyOS_setsig(SIGPIPE, SIG_IGN); diff --git a/Python/pystate.c b/Python/pystate.c index 6fe3dd1ff3f..e9c4c7d8376 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -6,11 +6,6 @@ #include "pycore_pymem.h" #include "pycore_pystate.h" -#define _PyThreadState_SET(value) \ - _Py_atomic_store_relaxed(&_PyRuntime.gilstate.tstate_current, \ - (uintptr_t)(value)) - - /* -------------------------------------------------------------------------- CAUTION @@ -34,6 +29,18 @@ to avoid the expense of doing their own locking). extern "C" { #endif +#define _PyRuntimeGILState_GetThreadState(gilstate) \ + ((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current)) +#define _PyRuntimeGILState_SetThreadState(gilstate, value) \ + _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ + (uintptr_t)(value)) + +/* Forward declarations */ +static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); +static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); +static PyThreadState *_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts); + + static _PyInitError _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) { @@ -108,51 +115,63 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) */ void -_PyRuntimeState_ReInitThreads(void) +_PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) { // This was initially set in _PyRuntimeState_Init(). - _PyRuntime.main_thread = PyThread_get_thread_ident(); + runtime->main_thread = PyThread_get_thread_ident(); - _PyRuntime.interpreters.mutex = PyThread_allocate_lock(); - if (_PyRuntime.interpreters.mutex == NULL) { + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + runtime->interpreters.mutex = PyThread_allocate_lock(); + runtime->interpreters.main->id_mutex = PyThread_allocate_lock(); + runtime->xidregistry.mutex = PyThread_allocate_lock(); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (runtime->interpreters.mutex == NULL) { Py_FatalError("Can't initialize lock for runtime interpreters"); } - _PyRuntime.interpreters.main->id_mutex = PyThread_allocate_lock(); - if (_PyRuntime.interpreters.main->id_mutex == NULL) { + if (runtime->interpreters.main->id_mutex == NULL) { Py_FatalError("Can't initialize ID lock for main interpreter"); } - _PyRuntime.xidregistry.mutex = PyThread_allocate_lock(); - if (_PyRuntime.xidregistry.mutex == NULL) { + if (runtime->xidregistry.mutex == NULL) { Py_FatalError("Can't initialize lock for cross-interpreter data registry"); } } -#define HEAD_LOCK() PyThread_acquire_lock(_PyRuntime.interpreters.mutex, \ - WAIT_LOCK) -#define HEAD_UNLOCK() PyThread_release_lock(_PyRuntime.interpreters.mutex) +#define HEAD_LOCK(runtime) \ + PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) +#define HEAD_UNLOCK(runtime) \ + PyThread_release_lock((runtime)->interpreters.mutex) -static void _PyGILState_NoteThreadState(PyThreadState* tstate); +/* Forward declaration */ +static void _PyGILState_NoteThreadState( + struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); _PyInitError _PyInterpreterState_Enable(_PyRuntimeState *runtime) { - runtime->interpreters.next_id = 0; + struct pyinterpreters *interpreters = &runtime->interpreters; + interpreters->next_id = 0; /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. Create a new mutex if needed. */ - if (runtime->interpreters.mutex == NULL) { + if (interpreters->mutex == NULL) { /* Force default allocator, since _PyRuntimeState_Fini() must use the same allocator than this function. */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - runtime->interpreters.mutex = PyThread_allocate_lock(); + interpreters->mutex = PyThread_allocate_lock(); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (runtime->interpreters.mutex == NULL) { + if (interpreters->mutex == NULL) { return _Py_INIT_ERR("Can't initialize threads for interpreter"); } } @@ -163,9 +182,7 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) PyInterpreterState * PyInterpreterState_New(void) { - PyInterpreterState *interp = (PyInterpreterState *) - PyMem_RawMalloc(sizeof(PyInterpreterState)); - + PyInterpreterState *interp = PyMem_RawMalloc(sizeof(PyInterpreterState)); if (interp == NULL) { return NULL; } @@ -174,7 +191,6 @@ PyInterpreterState_New(void) interp->id_refcount = -1; interp->check_interval = 100; interp->core_config = _PyCoreConfig_INIT; - interp->config = _PyMainInterpreterConfig_INIT; interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW @@ -184,23 +200,27 @@ PyInterpreterState_New(void) #endif #endif - HEAD_LOCK(); - if (_PyRuntime.interpreters.next_id < 0) { + _PyRuntimeState *runtime = &_PyRuntime; + struct pyinterpreters *interpreters = &runtime->interpreters; + + HEAD_LOCK(runtime); + if (interpreters->next_id < 0) { /* overflow or Py_Initialize() not called! */ PyErr_SetString(PyExc_RuntimeError, "failed to get an interpreter ID"); PyMem_RawFree(interp); interp = NULL; - } else { - interp->id = _PyRuntime.interpreters.next_id; - _PyRuntime.interpreters.next_id += 1; - interp->next = _PyRuntime.interpreters.head; - if (_PyRuntime.interpreters.main == NULL) { - _PyRuntime.interpreters.main = interp; - } - _PyRuntime.interpreters.head = interp; } - HEAD_UNLOCK(); + else { + interp->id = interpreters->next_id; + interpreters->next_id += 1; + interp->next = interpreters->head; + if (interpreters->main == NULL) { + interpreters->main = interp; + } + interpreters->head = interp; + } + HEAD_UNLOCK(runtime); if (interp == NULL) { return NULL; @@ -212,16 +232,15 @@ PyInterpreterState_New(void) } -void -PyInterpreterState_Clear(PyInterpreterState *interp) +static void +_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) { - PyThreadState *p; - HEAD_LOCK(); - for (p = interp->tstate_head; p != NULL; p = p->next) + HEAD_LOCK(runtime); + for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { PyThreadState_Clear(p); - HEAD_UNLOCK(); + } + HEAD_UNLOCK(runtime); _PyCoreConfig_Clear(&interp->core_config); - _PyMainInterpreterConfig_Clear(&interp->config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); Py_CLEAR(interp->codec_error_registry); @@ -243,45 +262,63 @@ PyInterpreterState_Clear(PyInterpreterState *interp) // objects have been cleaned up at the point. } +void +PyInterpreterState_Clear(PyInterpreterState *interp) +{ + _PyInterpreterState_Clear(&_PyRuntime, interp); +} + static void -zapthreads(PyInterpreterState *interp) +zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) { PyThreadState *p; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ while ((p = interp->tstate_head) != NULL) { - PyThreadState_Delete(p); + _PyThreadState_Delete(runtime, p); } } +static void +_PyInterpreterState_Delete(_PyRuntimeState *runtime, + PyInterpreterState *interp) +{ + struct pyinterpreters *interpreters = &runtime->interpreters; + zapthreads(runtime, interp); + HEAD_LOCK(runtime); + PyInterpreterState **p; + for (p = &interpreters->head; ; p = &(*p)->next) { + if (*p == NULL) { + Py_FatalError("PyInterpreterState_Delete: invalid interp"); + } + if (*p == interp) { + break; + } + } + if (interp->tstate_head != NULL) { + Py_FatalError("PyInterpreterState_Delete: remaining threads"); + } + *p = interp->next; + if (interpreters->main == interp) { + interpreters->main = NULL; + if (interpreters->head != NULL) { + Py_FatalError("PyInterpreterState_Delete: remaining subinterpreters"); + } + } + HEAD_UNLOCK(runtime); + if (interp->id_mutex != NULL) { + PyThread_free_lock(interp->id_mutex); + } + PyMem_RawFree(interp); +} + + void PyInterpreterState_Delete(PyInterpreterState *interp) { - PyInterpreterState **p; - zapthreads(interp); - HEAD_LOCK(); - for (p = &_PyRuntime.interpreters.head; ; p = &(*p)->next) { - if (*p == NULL) - Py_FatalError( - "PyInterpreterState_Delete: invalid interp"); - if (*p == interp) - break; - } - if (interp->tstate_head != NULL) - Py_FatalError("PyInterpreterState_Delete: remaining threads"); - *p = interp->next; - if (_PyRuntime.interpreters.main == interp) { - _PyRuntime.interpreters.main = NULL; - if (_PyRuntime.interpreters.head != NULL) - Py_FatalError("PyInterpreterState_Delete: remaining subinterpreters"); - } - HEAD_UNLOCK(); - if (interp->id_mutex != NULL) { - PyThread_free_lock(interp->id_mutex); - } - PyMem_RawFree(interp); + _PyInterpreterState_Delete(&_PyRuntime, interp); } @@ -290,26 +327,29 @@ PyInterpreterState_Delete(PyInterpreterState *interp) * is a current interpreter state, it *must* be the main interpreter. */ void -_PyInterpreterState_DeleteExceptMain() +_PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) { - PyThreadState *tstate = PyThreadState_Swap(NULL); - if (tstate != NULL && tstate->interp != _PyRuntime.interpreters.main) { + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct pyinterpreters *interpreters = &runtime->interpreters; + + PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); + if (tstate != NULL && tstate->interp != interpreters->main) { Py_FatalError("PyInterpreterState_DeleteExceptMain: not main interpreter"); } - HEAD_LOCK(); - PyInterpreterState *interp = _PyRuntime.interpreters.head; - _PyRuntime.interpreters.head = NULL; + HEAD_LOCK(runtime); + PyInterpreterState *interp = interpreters->head; + interpreters->head = NULL; while (interp != NULL) { - if (interp == _PyRuntime.interpreters.main) { - _PyRuntime.interpreters.main->next = NULL; - _PyRuntime.interpreters.head = interp; + if (interp == interpreters->main) { + interpreters->main->next = NULL; + interpreters->head = interp; interp = interp->next; continue; } - PyInterpreterState_Clear(interp); // XXX must activate? - zapthreads(interp); + _PyInterpreterState_Clear(runtime, interp); // XXX must activate? + zapthreads(runtime, interp); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -317,12 +357,12 @@ _PyInterpreterState_DeleteExceptMain() interp = interp->next; PyMem_RawFree(prev_interp); } - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); - if (_PyRuntime.interpreters.head == NULL) { + if (interpreters->head == NULL) { Py_FatalError("PyInterpreterState_DeleteExceptMain: missing main"); } - PyThreadState_Swap(tstate); + _PyThreadState_Swap(gilstate, tstate); } @@ -353,9 +393,9 @@ PyInterpreterState_GetID(PyInterpreterState *interp) static PyInterpreterState * -interp_look_up_id(PY_INT64_T requested_id) +interp_look_up_id(_PyRuntimeState *runtime, PY_INT64_T requested_id) { - PyInterpreterState *interp = PyInterpreterState_Head(); + PyInterpreterState *interp = runtime->interpreters.head; while (interp != NULL) { PY_INT64_T id = PyInterpreterState_GetID(interp); if (id < 0) { @@ -374,9 +414,10 @@ _PyInterpreterState_LookUpID(PY_INT64_T requested_id) { PyInterpreterState *interp = NULL; if (requested_id >= 0) { - HEAD_LOCK(); - interp = interp_look_up_id(requested_id); - HEAD_UNLOCK(); + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + interp = interp_look_up_id(runtime, requested_id); + HEAD_UNLOCK(runtime); } if (interp == NULL && !PyErr_Occurred()) { PyErr_Format(PyExc_RuntimeError, @@ -421,6 +462,7 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) if (interp->id_mutex == NULL) { return; } + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); interp->id_refcount -= 1; @@ -431,9 +473,9 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) // XXX Using the "head" thread isn't strictly correct. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? - PyThreadState *save_tstate = PyThreadState_Swap(tstate); + PyThreadState *save_tstate = _PyThreadState_Swap(gilstate, tstate); Py_EndInterpreter(tstate); - PyThreadState_Swap(save_tstate); + _PyThreadState_Swap(gilstate, save_tstate); } } @@ -455,12 +497,6 @@ _PyInterpreterState_GetCoreConfig(PyInterpreterState *interp) return &interp->core_config; } -_PyMainInterpreterConfig * -_PyInterpreterState_GetMainConfig(PyInterpreterState *interp) -{ - return &interp->config; -} - PyObject * _PyInterpreterState_GetMainModule(PyInterpreterState *interp) { @@ -494,72 +530,76 @@ threadstate_getframe(PyThreadState *self) static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { + _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); - - if (_PyThreadState_GetFrame == NULL) - _PyThreadState_GetFrame = threadstate_getframe; - - if (tstate != NULL) { - tstate->interp = interp; - - tstate->frame = NULL; - tstate->recursion_depth = 0; - tstate->overflowed = 0; - tstate->recursion_critical = 0; - tstate->stackcheck_counter = 0; - tstate->tracing = 0; - tstate->use_tracing = 0; - tstate->gilstate_counter = 0; - tstate->async_exc = NULL; - tstate->thread_id = PyThread_get_thread_ident(); - - tstate->dict = NULL; - - tstate->curexc_type = NULL; - tstate->curexc_value = NULL; - tstate->curexc_traceback = NULL; - - tstate->exc_state.exc_type = NULL; - tstate->exc_state.exc_value = NULL; - tstate->exc_state.exc_traceback = NULL; - tstate->exc_state.previous_item = NULL; - tstate->exc_info = &tstate->exc_state; - - tstate->c_profilefunc = NULL; - tstate->c_tracefunc = NULL; - tstate->c_profileobj = NULL; - tstate->c_traceobj = NULL; - - tstate->trash_delete_nesting = 0; - tstate->trash_delete_later = NULL; - tstate->on_delete = NULL; - tstate->on_delete_data = NULL; - - tstate->coroutine_origin_tracking_depth = 0; - - tstate->coroutine_wrapper = NULL; - tstate->in_coroutine_wrapper = 0; - - tstate->async_gen_firstiter = NULL; - tstate->async_gen_finalizer = NULL; - - tstate->context = NULL; - tstate->context_ver = 1; - - tstate->id = ++interp->tstate_next_unique_id; - - if (init) - _PyThreadState_Init(tstate); - - HEAD_LOCK(); - tstate->prev = NULL; - tstate->next = interp->tstate_head; - if (tstate->next) - tstate->next->prev = tstate; - interp->tstate_head = tstate; - HEAD_UNLOCK(); + if (tstate == NULL) { + return NULL; } + if (_PyThreadState_GetFrame == NULL) { + _PyThreadState_GetFrame = threadstate_getframe; + } + + tstate->interp = interp; + + tstate->frame = NULL; + tstate->recursion_depth = 0; + tstate->overflowed = 0; + tstate->recursion_critical = 0; + tstate->stackcheck_counter = 0; + tstate->tracing = 0; + tstate->use_tracing = 0; + tstate->gilstate_counter = 0; + tstate->async_exc = NULL; + tstate->thread_id = PyThread_get_thread_ident(); + + tstate->dict = NULL; + + tstate->curexc_type = NULL; + tstate->curexc_value = NULL; + tstate->curexc_traceback = NULL; + + tstate->exc_state.exc_type = NULL; + tstate->exc_state.exc_value = NULL; + tstate->exc_state.exc_traceback = NULL; + tstate->exc_state.previous_item = NULL; + tstate->exc_info = &tstate->exc_state; + + tstate->c_profilefunc = NULL; + tstate->c_tracefunc = NULL; + tstate->c_profileobj = NULL; + tstate->c_traceobj = NULL; + + tstate->trash_delete_nesting = 0; + tstate->trash_delete_later = NULL; + tstate->on_delete = NULL; + tstate->on_delete_data = NULL; + + tstate->coroutine_origin_tracking_depth = 0; + + tstate->coroutine_wrapper = NULL; + tstate->in_coroutine_wrapper = 0; + + tstate->async_gen_firstiter = NULL; + tstate->async_gen_finalizer = NULL; + + tstate->context = NULL; + tstate->context_ver = 1; + + tstate->id = ++interp->tstate_next_unique_id; + + if (init) { + _PyThreadState_Init(runtime, tstate); + } + + HEAD_LOCK(runtime); + tstate->prev = NULL; + tstate->next = interp->tstate_head; + if (tstate->next) + tstate->next->prev = tstate; + interp->tstate_head = tstate; + HEAD_UNLOCK(runtime); + return tstate; } @@ -576,9 +616,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) } void -_PyThreadState_Init(PyThreadState *tstate) +_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyGILState_NoteThreadState(tstate); + _PyGILState_NoteThreadState(&runtime->gilstate, tstate); } PyObject* @@ -743,22 +783,23 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(PyThreadState *tstate) +tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) { - PyInterpreterState *interp; - if (tstate == NULL) + if (tstate == NULL) { Py_FatalError("PyThreadState_Delete: NULL tstate"); - interp = tstate->interp; - if (interp == NULL) + } + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { Py_FatalError("PyThreadState_Delete: NULL interp"); - HEAD_LOCK(); + } + HEAD_LOCK(runtime); if (tstate->prev) tstate->prev->next = tstate->next; else interp->tstate_head = tstate->next; if (tstate->next) tstate->next->prev = tstate->prev; - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); if (tstate->on_delete != NULL) { tstate->on_delete(tstate->on_delete_data); } @@ -766,37 +807,53 @@ tstate_delete_common(PyThreadState *tstate) } -void -PyThreadState_Delete(PyThreadState *tstate) +static void +_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) { - if (tstate == _PyThreadState_GET()) + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { Py_FatalError("PyThreadState_Delete: tstate is still current"); - if (_PyRuntime.gilstate.autoInterpreterState && - PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate) - { - PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL); } - tstate_delete_common(tstate); + if (gilstate->autoInterpreterState && + PyThread_tss_get(&gilstate->autoTSSkey) == tstate) + { + PyThread_tss_set(&gilstate->autoTSSkey, NULL); + } + tstate_delete_common(runtime, tstate); } void -PyThreadState_DeleteCurrent() +PyThreadState_Delete(PyThreadState *tstate) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyThreadState_Delete(&_PyRuntime, tstate); +} + + +static void +_PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - tstate_delete_common(tstate); - if (_PyRuntime.gilstate.autoInterpreterState && - PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate) + tstate_delete_common(runtime, tstate); + if (gilstate->autoInterpreterState && + PyThread_tss_get(&gilstate->autoTSSkey) == tstate) { - PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL); + PyThread_tss_set(&gilstate->autoTSSkey, NULL); } - _PyThreadState_SET(NULL); + _PyRuntimeGILState_SetThreadState(gilstate, NULL); PyEval_ReleaseLock(); } +void +PyThreadState_DeleteCurrent() +{ + _PyThreadState_DeleteCurrent(&_PyRuntime); +} + /* * Delete all thread states except the one passed as argument. @@ -808,9 +865,10 @@ PyThreadState_DeleteCurrent() void _PyThreadState_DeleteExcept(PyThreadState *tstate) { + _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = tstate->interp; PyThreadState *p, *next, *garbage; - HEAD_LOCK(); + HEAD_LOCK(runtime); /* Remove all thread states, except tstate, from the linked list of thread states. This will allow calling PyThreadState_Clear() without holding the lock. */ @@ -823,7 +881,7 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) tstate->next->prev = tstate->prev; tstate->prev = tstate->next = NULL; interp->tstate_head = tstate; - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); /* Clear and deallocate all stale thread states. Even if this executes Python code, we should be safe since it executes in the current thread, not one of the stale threads. */ @@ -853,12 +911,12 @@ PyThreadState_Get(void) } -PyThreadState * -PyThreadState_Swap(PyThreadState *newts) +static PyThreadState * +_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) { - PyThreadState *oldts = _PyThreadState_GET(); + PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); - _PyThreadState_SET(newts); + _PyRuntimeGILState_SetThreadState(gilstate, newts); /* It should not be possible for more than one thread state to be used for a thread. Check this the best we can in debug builds. @@ -869,7 +927,7 @@ PyThreadState_Swap(PyThreadState *newts) to it, we need to ensure errno doesn't change. */ int err = errno; - PyThreadState *check = PyGILState_GetThisThreadState(); + PyThreadState *check = _PyGILState_GetThisThreadState(gilstate); if (check && check->interp == newts->interp && check != newts) Py_FatalError("Invalid thread state for this thread"); errno = err; @@ -878,6 +936,12 @@ PyThreadState_Swap(PyThreadState *newts) return oldts; } +PyThreadState * +PyThreadState_Swap(PyThreadState *newts) +{ + return _PyThreadState_Swap(&_PyRuntime.gilstate, newts); +} + /* An extension mechanism to store arbitrary additional per-thread state. PyThreadState_GetDict() returns a dictionary that can be used to hold such state; the caller should pick a unique key and store its state there. If @@ -921,7 +985,8 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) * list of thread states we're traversing, so to prevent that we lock * head_mutex for the duration. */ - HEAD_LOCK(); + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); for (p = interp->tstate_head; p != NULL; p = p->next) { if (p->thread_id == id) { /* Tricky: we need to decref the current value @@ -934,13 +999,13 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) PyObject *old_exc = p->async_exc; Py_XINCREF(exc); p->async_exc = exc; - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); Py_XDECREF(old_exc); _PyEval_SignalAsyncExc(); return 1; } } - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); return 0; } @@ -996,8 +1061,9 @@ _PyThread_CurrentFrames(void) * Because these lists can mutate even when the GIL is held, we * need to grab head_mutex for the duration. */ - HEAD_LOCK(); - for (i = _PyRuntime.interpreters.head; i != NULL; i = i->next) { + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + for (i = runtime->interpreters.head; i != NULL; i = i->next) { PyThreadState *t; for (t = i->tstate_head; t != NULL; t = t->next) { PyObject *id; @@ -1014,11 +1080,11 @@ _PyThread_CurrentFrames(void) goto Fail; } } - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); return result; Fail: - HEAD_UNLOCK(); + HEAD_UNLOCK(runtime); Py_DECREF(result); return NULL; } @@ -1037,25 +1103,32 @@ static int PyThreadState_IsCurrent(PyThreadState *tstate) { /* Must be the tstate for this thread */ - assert(PyGILState_GetThisThreadState()==tstate); - return tstate == _PyThreadState_GET(); + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + assert(_PyGILState_GetThisThreadState(gilstate) == tstate); + return tstate == _PyRuntimeGILState_GetThreadState(gilstate); } /* Internal initialization/finalization functions called by Py_Initialize/Py_FinalizeEx */ void -_PyGILState_Init(PyInterpreterState *i, PyThreadState *t) +_PyGILState_Init(_PyRuntimeState *runtime, + PyInterpreterState *interp, PyThreadState *tstate) { - assert(i && t); /* must init with valid states */ - if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) { + /* must init with valid states */ + assert(interp != NULL); + assert(tstate != NULL); + + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + + if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { Py_FatalError("Could not allocate TSS entry"); } - _PyRuntime.gilstate.autoInterpreterState = i; - assert(PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL); - assert(t->gilstate_counter == 0); + gilstate->autoInterpreterState = interp; + assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); + assert(tstate->gilstate_counter == 0); - _PyGILState_NoteThreadState(t); + _PyGILState_NoteThreadState(gilstate, tstate); } PyInterpreterState * @@ -1065,10 +1138,11 @@ _PyGILState_GetInterpreterStateUnsafe(void) } void -_PyGILState_Fini(void) +_PyGILState_Fini(_PyRuntimeState *runtime) { - PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey); - _PyRuntime.gilstate.autoInterpreterState = NULL; + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + PyThread_tss_delete(&gilstate->autoTSSkey); + gilstate->autoInterpreterState = NULL; } /* Reset the TSS key - called by PyOS_AfterFork_Child(). @@ -1076,31 +1150,20 @@ _PyGILState_Fini(void) * don't reset TSS upon fork(), see issue #10517. */ void -_PyGILState_Reinit(void) +_PyGILState_Reinit(_PyRuntimeState *runtime) { - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + PyThreadState *tstate = _PyGILState_GetThisThreadState(gilstate); - _PyRuntime.interpreters.mutex = PyThread_allocate_lock(); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (_PyRuntime.interpreters.mutex == NULL) { - Py_FatalError("Can't initialize threads for interpreter"); - } - - PyThreadState *tstate = PyGILState_GetThisThreadState(); - PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey); - if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) { + PyThread_tss_delete(&gilstate->autoTSSkey); + if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { Py_FatalError("Could not allocate TSS entry"); } /* If the thread had an associated auto thread state, reassociate it with * the new key. */ if (tstate && - PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) != 0) + PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) { Py_FatalError("Couldn't create autoTSSkey mapping"); } @@ -1112,13 +1175,14 @@ _PyGILState_Reinit(void) a better fix for SF bug #1010677 than the first one attempted). */ static void -_PyGILState_NoteThreadState(PyThreadState* tstate) +_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate) { /* If autoTSSkey isn't initialized, this must be the very first threadstate created in Py_Initialize(). Don't do anything for now (we'll be back here when _PyGILState_Init is called). */ - if (!_PyRuntime.gilstate.autoInterpreterState) + if (!gilstate->autoInterpreterState) { return; + } /* Stick the thread state for this thread in thread specific storage. @@ -1132,10 +1196,8 @@ _PyGILState_NoteThreadState(PyThreadState* tstate) The first thread state created for that given OS level thread will "win", which seems reasonable behaviour. */ - if (PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL) { - if ((PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) - ) != 0) - { + if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) { + if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) { Py_FatalError("Couldn't create autoTSSkey mapping"); } } @@ -1145,36 +1207,45 @@ _PyGILState_NoteThreadState(PyThreadState* tstate) } /* The public functions */ +static PyThreadState * +_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate) +{ + if (gilstate->autoInterpreterState == NULL) + return NULL; + return (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); +} + PyThreadState * PyGILState_GetThisThreadState(void) { - if (_PyRuntime.gilstate.autoInterpreterState == NULL) - return NULL; - return (PyThreadState *)PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey); + return _PyGILState_GetThisThreadState(&_PyRuntime.gilstate); } int PyGILState_Check(void) { - PyThreadState *tstate; - if (!_PyGILState_check_enabled) - return 1; - - if (!PyThread_tss_is_created(&_PyRuntime.gilstate.autoTSSkey)) { + if (!_PyGILState_check_enabled) { return 1; } - tstate = _PyThreadState_GET(); - if (tstate == NULL) - return 0; + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { + return 1; + } - return (tstate == PyGILState_GetThisThreadState()); + PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + if (tstate == NULL) { + return 0; + } + + return (tstate == _PyGILState_GetThisThreadState(gilstate)); } PyGILState_STATE PyGILState_Ensure(void) { + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; int current; PyThreadState *tcur; int need_init_threads = 0; @@ -1185,14 +1256,14 @@ PyGILState_Ensure(void) called Py_Initialize() and usually PyEval_InitThreads(). */ /* Py_Initialize() hasn't been called! */ - assert(_PyRuntime.gilstate.autoInterpreterState); + assert(gilstate->autoInterpreterState); - tcur = (PyThreadState *)PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey); + tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); if (tcur == NULL) { need_init_threads = 1; /* Create a new thread state for this thread */ - tcur = PyThreadState_New(_PyRuntime.gilstate.autoInterpreterState); + tcur = PyThreadState_New(gilstate->autoInterpreterState); if (tcur == NULL) Py_FatalError("Couldn't create thread-state for new thread"); /* This is our thread state! We'll need to delete it in the @@ -1228,18 +1299,21 @@ PyGILState_Ensure(void) void PyGILState_Release(PyGILState_STATE oldstate) { - PyThreadState *tcur = (PyThreadState *)PyThread_tss_get( - &_PyRuntime.gilstate.autoTSSkey); - if (tcur == NULL) + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tcur = PyThread_tss_get(&runtime->gilstate.autoTSSkey); + if (tcur == NULL) { Py_FatalError("auto-releasing thread-state, " "but no thread-state for this thread"); + } + /* We must hold the GIL and have our thread state current */ /* XXX - remove the check - the assert should be fine, but while this is very new (April 2003), the extra check by release-only users can't hurt. */ - if (! PyThreadState_IsCurrent(tcur)) + if (!PyThreadState_IsCurrent(tcur)) { Py_FatalError("This thread state must be current when releasing"); + } assert(PyThreadState_IsCurrent(tcur)); --tcur->gilstate_counter; assert(tcur->gilstate_counter >= 0); /* illegal counter value */ @@ -1256,7 +1330,7 @@ PyGILState_Release(PyGILState_STATE oldstate) * races; see bugs 225673 and 1061968 (that nasty bug has a * habit of coming back). */ - PyThreadState_DeleteCurrent(); + _PyThreadState_DeleteCurrent(runtime); } /* Release the lock if necessary */ else if (oldstate == PyGILState_UNLOCKED) @@ -1361,7 +1435,8 @@ _release_xidata(void *arg) } static void -_call_in_interpreter(PyInterpreterState *interp, +_call_in_interpreter(struct _gilstate_runtime_state *gilstate, + PyInterpreterState *interp, void (*func)(void *), void *arg) { /* We would use Py_AddPendingCall() if it weren't specific to the @@ -1369,18 +1444,18 @@ _call_in_interpreter(PyInterpreterState *interp, * naive approach. */ PyThreadState *save_tstate = NULL; - if (interp != _PyInterpreterState_Get()) { + if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { // XXX Using the "head" thread isn't strictly correct. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? - save_tstate = PyThreadState_Swap(tstate); + save_tstate = _PyThreadState_Swap(gilstate, tstate); } func(arg); // Switch back. if (save_tstate != NULL) { - PyThreadState_Swap(save_tstate); + _PyThreadState_Swap(gilstate, save_tstate); } } @@ -1403,7 +1478,8 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) } // "Release" the data and/or the object. - _call_in_interpreter(interp, _release_xidata, data); + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + _call_in_interpreter(gilstate, interp, _release_xidata, data); } PyObject * @@ -1419,7 +1495,8 @@ _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) crossinterpdatafunc. It would be simpler and more efficient. */ static int -_register_xidata(PyTypeObject *cls, crossinterpdatafunc getdata) +_register_xidata(struct _xidregistry *xidregistry, PyTypeObject *cls, + crossinterpdatafunc getdata) { // Note that we effectively replace already registered classes // rather than failing. @@ -1428,12 +1505,12 @@ _register_xidata(PyTypeObject *cls, crossinterpdatafunc getdata) return -1; newhead->cls = cls; newhead->getdata = getdata; - newhead->next = _PyRuntime.xidregistry.head; - _PyRuntime.xidregistry.head = newhead; + newhead->next = xidregistry->head; + xidregistry->head = newhead; return 0; } -static void _register_builtins_for_crossinterpreter_data(void); +static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); int _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, @@ -1451,12 +1528,13 @@ _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, // Make sure the class isn't ever deallocated. Py_INCREF((PyObject *)cls); - PyThread_acquire_lock(_PyRuntime.xidregistry.mutex, WAIT_LOCK); - if (_PyRuntime.xidregistry.head == NULL) { - _register_builtins_for_crossinterpreter_data(); + struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + if (xidregistry->head == NULL) { + _register_builtins_for_crossinterpreter_data(xidregistry); } - int res = _register_xidata(cls, getdata); - PyThread_release_lock(_PyRuntime.xidregistry.mutex); + int res = _register_xidata(xidregistry, cls, getdata); + PyThread_release_lock(xidregistry->mutex); return res; } @@ -1467,13 +1545,14 @@ _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *obj) { + struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; PyObject *cls = PyObject_Type(obj); crossinterpdatafunc getdata = NULL; - PyThread_acquire_lock(_PyRuntime.xidregistry.mutex, WAIT_LOCK); - struct _xidregitem *cur = _PyRuntime.xidregistry.head; + PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + struct _xidregitem *cur = xidregistry->head; if (cur == NULL) { - _register_builtins_for_crossinterpreter_data(); - cur = _PyRuntime.xidregistry.head; + _register_builtins_for_crossinterpreter_data(xidregistry); + cur = xidregistry->head; } for(; cur != NULL; cur = cur->next) { if (cur->cls == (PyTypeObject *)cls) { @@ -1482,7 +1561,7 @@ _PyCrossInterpreterData_Lookup(PyObject *obj) } } Py_DECREF(cls); - PyThread_release_lock(_PyRuntime.xidregistry.mutex); + PyThread_release_lock(xidregistry->mutex); return getdata; } @@ -1589,25 +1668,25 @@ _none_shared(PyObject *obj, _PyCrossInterpreterData *data) } static void -_register_builtins_for_crossinterpreter_data(void) +_register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) { // None - if (_register_xidata((PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { + if (_register_xidata(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { Py_FatalError("could not register None for cross-interpreter sharing"); } // int - if (_register_xidata(&PyLong_Type, _long_shared) != 0) { + if (_register_xidata(xidregistry, &PyLong_Type, _long_shared) != 0) { Py_FatalError("could not register int for cross-interpreter sharing"); } // bytes - if (_register_xidata(&PyBytes_Type, _bytes_shared) != 0) { + if (_register_xidata(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { Py_FatalError("could not register bytes for cross-interpreter sharing"); } // str - if (_register_xidata(&PyUnicode_Type, _str_shared) != 0) { + if (_register_xidata(xidregistry, &PyUnicode_Type, _str_shared) != 0) { Py_FatalError("could not register str for cross-interpreter sharing"); } } diff --git a/Python/pytime.c b/Python/pytime.c index 68c49a86da2..9ff300699f0 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -1062,26 +1062,23 @@ _PyTime_localtime(time_t t, struct tm *tm) } return 0; #else /* !MS_WINDOWS */ + #ifdef _AIX - /* AIX does not return NULL on an error - so test ranges - asif! - (1902-01-01, -2145916800.0) - (2038-01-01, 2145916800.0) */ - if (abs(t) > (time_t) 2145916800) { -#ifdef EINVAL + /* bpo-34373: AIX does not return NULL if t is too small or too large */ + if (t < -2145916800 /* 1902-01-01 */ + || t > 2145916800 /* 2038-01-01 */) { errno = EINVAL; -#endif PyErr_SetString(PyExc_OverflowError, - "ctime argument out of range"); + "localtime argument out of range"); return -1; } #endif + + errno = 0; if (localtime_r(&t, tm) == NULL) { -#ifdef EINVAL if (errno == 0) { errno = EINVAL; } -#endif PyErr_SetFromErrno(PyExc_OSError); return -1; } diff --git a/Python/strdup.c b/Python/strdup.c index 99dc77417bd..6ce171b21fe 100644 --- a/Python/strdup.c +++ b/Python/strdup.c @@ -1,7 +1,5 @@ /* strdup() replacement (from stdwin, if you must know) */ -#include "pgenheaders.h" - char * strdup(const char *str) { diff --git a/Python/symtable.c b/Python/symtable.c index 1d68a7d939f..fe6bc9aca4d 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1653,6 +1653,8 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a) /* skip default arguments inside function block XXX should ast be different? */ + if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs)) + return 0; if (a->args && !symtable_visit_params(st, a->args)) return 0; if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 4351a7fb370..1290164edbf 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -17,6 +17,7 @@ Data members: #include "Python.h" #include "code.h" #include "frameobject.h" +#include "pycore_coreconfig.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pathconfig.h" @@ -283,7 +284,9 @@ sys_displayhook(PyObject *module, PyObject *o) builtins = _PyImport_GetModuleId(&PyId_builtins); if (builtins == NULL) { - PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); + } return NULL; } Py_DECREF(builtins); @@ -421,7 +424,7 @@ sys_getfilesystemencoding_impl(PyObject *module) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); const _PyCoreConfig *config = &interp->core_config; - return PyUnicode_FromString(config->filesystem_encoding); + return PyUnicode_FromWideChar(config->filesystem_encoding, -1); } /*[clinic input] @@ -436,7 +439,7 @@ sys_getfilesystemencodeerrors_impl(PyObject *module) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); const _PyCoreConfig *config = &interp->core_config; - return PyUnicode_FromString(config->filesystem_errors); + return PyUnicode_FromWideChar(config->filesystem_errors, -1); } /*[clinic input] @@ -1208,30 +1211,9 @@ static PyObject * sys__enablelegacywindowsfsencoding_impl(PyObject *module) /*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/ { - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - _PyCoreConfig *config = &interp->core_config; - - /* Set the filesystem encoding to mbcs/replace (PEP 529) */ - char *encoding = _PyMem_RawStrdup("mbcs"); - char *errors = _PyMem_RawStrdup("replace"); - if (encoding == NULL || errors == NULL) { - PyMem_Free(encoding); - PyMem_Free(errors); - PyErr_NoMemory(); + if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) { return NULL; } - - PyMem_RawFree(config->filesystem_encoding); - config->filesystem_encoding = encoding; - PyMem_RawFree(config->filesystem_errors); - config->filesystem_errors = errors; - - if (_Py_SetFileSystemEncoding(config->filesystem_encoding, - config->filesystem_errors) < 0) { - PyErr_NoMemory(); - return NULL; - } - Py_RETURN_NONE; } @@ -1768,7 +1750,7 @@ _alloc_preinit_entry(const wchar_t *value) PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return node; -}; +} static int _append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value) @@ -1790,7 +1772,7 @@ _append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value) last_entry->next = new_entry; } return 0; -}; +} static void _clear_preinit_entries(_Py_PreInitEntry *optionlist) @@ -1807,7 +1789,7 @@ _clear_preinit_entries(_Py_PreInitEntry *optionlist) current = next; } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -}; +} static void _clear_all_preinit_options(void) @@ -1838,7 +1820,7 @@ _PySys_ReadPreInitOptions(void) _clear_all_preinit_options(); return 0; -}; +} static PyObject * get_warnoptions(void) @@ -2152,11 +2134,12 @@ static PyStructSequence_Desc flags_desc = { }; static PyObject* -make_flags(void) +make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) { int pos = 0; PyObject *seq; - const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + const _PyPreConfig *preconfig = &runtime->preconfig; + const _PyCoreConfig *config = &interp->core_config; seq = PyStructSequence_New(&FlagsType); if (seq == NULL) @@ -2172,16 +2155,16 @@ make_flags(void) SetFlag(!config->write_bytecode); SetFlag(!config->user_site_directory); SetFlag(!config->site_import); - SetFlag(!config->preconfig.use_environment); + SetFlag(!config->use_environment); SetFlag(config->verbose); /* SetFlag(saw_unbuffered_flag); */ /* SetFlag(skipfirstline); */ SetFlag(config->bytes_warning); SetFlag(config->quiet); SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0); - SetFlag(config->preconfig.isolated); - PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->preconfig.dev_mode)); - SetFlag(config->preconfig.utf8_mode); + SetFlag(config->isolated); + PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode)); + SetFlag(preconfig->utf8_mode); #undef SetFlag if (PyErr_Occurred()) { @@ -2371,7 +2354,8 @@ static struct PyModuleDef sysmodule = { } while (0) static _PyInitError -_PySys_InitCore(PyObject *sysdict) +_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject *sysdict) { PyObject *version_info; int res; @@ -2461,8 +2445,8 @@ _PySys_InitCore(PyObject *sysdict) goto type_init_failed; } } - /* Set flags to their default values */ - SET_SYS_FROM_STRING("flags", make_flags()); + /* Set flags to their default values (updated by _PySys_InitMain()) */ + SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2527,26 +2511,71 @@ _PySys_InitCore(PyObject *sysdict) } \ } while (0) + +static int +sys_add_xoption(PyObject *opts, const wchar_t *s) +{ + PyObject *name, *value; + + const wchar_t *name_end = wcschr(s, L'='); + if (!name_end) { + name = PyUnicode_FromWideChar(s, -1); + value = Py_True; + Py_INCREF(value); + } + else { + name = PyUnicode_FromWideChar(s, name_end - s); + value = PyUnicode_FromWideChar(name_end + 1, -1); + } + if (name == NULL || value == NULL) { + goto error; + } + if (PyDict_SetItem(opts, name, value) < 0) { + goto error; + } + Py_DECREF(name); + Py_DECREF(value); + return 0; + +error: + Py_XDECREF(name); + Py_XDECREF(value); + return -1; +} + + +static PyObject* +sys_create_xoptions_dict(const _PyCoreConfig *config) +{ + Py_ssize_t nxoption = config->xoptions.length; + wchar_t * const * xoptions = config->xoptions.items; + PyObject *dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + + for (Py_ssize_t i=0; i < nxoption; i++) { + const wchar_t *option = xoptions[i]; + if (sys_add_xoption(dict, option) < 0) { + Py_DECREF(dict); + return NULL; + } + } + + return dict; +} + + int -_PySys_InitMain(PyInterpreterState *interp) +_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) { PyObject *sysdict = interp->sysdict; - const _PyCoreConfig *core_config = &interp->core_config; - const _PyMainInterpreterConfig *config = &interp->config; + const _PyCoreConfig *config = &interp->core_config; int res; - /* _PyMainInterpreterConfig_Read() must set all these variables */ - assert(config->module_search_path != NULL); - assert(config->executable != NULL); - assert(config->prefix != NULL); - assert(config->base_prefix != NULL); - assert(config->exec_prefix != NULL); - assert(config->base_exec_prefix != NULL); - -#define COPY_LIST(KEY, ATTR) \ +#define COPY_LIST(KEY, VALUE) \ do { \ - assert(PyList_Check(ATTR)); \ - PyObject *list = PyList_GetSlice(ATTR, 0, PyList_GET_SIZE(ATTR)); \ + PyObject *list = _PyWstrList_AsList(&(VALUE)); \ if (list == NULL) { \ return -1; \ } \ @@ -2554,39 +2583,45 @@ _PySys_InitMain(PyInterpreterState *interp) Py_DECREF(list); \ } while (0) - COPY_LIST("path", config->module_search_path); +#define SET_SYS_FROM_WSTR(KEY, VALUE) \ + do { \ + PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \ + if (str == NULL) { \ + return -1; \ + } \ + SET_SYS_FROM_STRING_BORROW(KEY, str); \ + Py_DECREF(str); \ + } while (0) - SET_SYS_FROM_STRING_BORROW("executable", config->executable); - SET_SYS_FROM_STRING_BORROW("prefix", config->prefix); - SET_SYS_FROM_STRING_BORROW("base_prefix", config->base_prefix); - SET_SYS_FROM_STRING_BORROW("exec_prefix", config->exec_prefix); - SET_SYS_FROM_STRING_BORROW("base_exec_prefix", config->base_exec_prefix); + COPY_LIST("path", config->module_search_paths); + + SET_SYS_FROM_WSTR("executable", config->executable); + SET_SYS_FROM_WSTR("prefix", config->prefix); + SET_SYS_FROM_WSTR("base_prefix", config->base_prefix); + SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix); + SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix); if (config->pycache_prefix != NULL) { - SET_SYS_FROM_STRING_BORROW("pycache_prefix", config->pycache_prefix); + SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); } else { PyDict_SetItemString(sysdict, "pycache_prefix", Py_None); } - if (config->argv != NULL) { - SET_SYS_FROM_STRING_BORROW("argv", config->argv); - } - if (config->warnoptions != NULL) { - COPY_LIST("warnoptions", config->warnoptions); - } - if (config->xoptions != NULL) { - PyObject *dict = PyDict_Copy(config->xoptions); - if (dict == NULL) { - return -1; - } - SET_SYS_FROM_STRING_BORROW("_xoptions", dict); - Py_DECREF(dict); + COPY_LIST("argv", config->argv); + COPY_LIST("warnoptions", config->warnoptions); + + PyObject *xoptions = sys_create_xoptions_dict(config); + if (xoptions == NULL) { + return -1; } + SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions); + Py_DECREF(xoptions); #undef COPY_LIST +#undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags()); + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; @@ -2599,7 +2634,7 @@ _PySys_InitMain(PyInterpreterState *interp) } SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode", - PyBool_FromLong(!core_config->write_bytecode)); + PyBool_FromLong(!config->write_bytecode)); if (get_warnoptions() == NULL) return -1; @@ -2653,7 +2688,8 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ _PyInitError -_PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) +_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject **sysmod_p) { PyObject *modules = PyDict_New(); if (modules == NULL) { @@ -2682,7 +2718,7 @@ _PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) return err; } - err = _PySys_InitCore(sysdict); + err = _PySys_InitCore(runtime, interp, sysdict); if (_Py_INIT_FAILED(err)) { return err; } diff --git a/Python/thread_nt.h b/Python/thread_nt.h index fdb192b7d77..5e00c351146 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -227,7 +227,7 @@ PyThread_get_thread_ident(void) return GetCurrentThreadId(); } -void +void _Py_NO_RETURN PyThread_exit_thread(void) { dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident())); diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 25f58d9446d..4c106d9959c 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -302,7 +302,7 @@ PyThread_get_thread_ident(void) return (unsigned long) threadid; } -void +void _Py_NO_RETURN PyThread_exit_thread(void) { dprintf(("PyThread_exit_thread called\n")); @@ -339,7 +339,7 @@ PyThread_allocate_lock(void) } } - dprintf(("PyThread_allocate_lock() -> %p\n", lock)); + dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); return (PyThread_type_lock)lock; } @@ -521,7 +521,7 @@ PyThread_allocate_lock(void) } } - dprintf(("PyThread_allocate_lock() -> %p\n", lock)); + dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); return (PyThread_type_lock) lock; } diff --git a/README.rst b/README.rst index 11f5d0b5d3c..388543b8dcf 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.8.0 alpha 2 +This is Python version 3.8.0 alpha 4 ==================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master @@ -70,7 +70,7 @@ to find out more. On macOS and Cygwin, the executable is called ``python.exe``; elsewhere it's just ``python``. If you are running on macOS with the latest updates installed, make sure to install -openSSL or some other SSL software along with Homebrew or another package manager. +OpenSSL or some other SSL software along with Homebrew or another package manager. If issues persist, see https://devguide.python.org/setup/#macos-and-os-x for more information. @@ -92,7 +92,7 @@ For example:: make test (This will fail if you *also* built at the top-level directory. You should do -a ``make clean`` at the toplevel first.) +a ``make clean`` at the top-level first.) To get an optimized build of Python, ``configure --enable-optimizations`` before you run ``make``. This sets the default make targets up to enable @@ -146,7 +146,7 @@ detailed change log, read `Misc/NEWS accounting of changes can only be gleaned from the `commit history `_. -If you want to install multiple versions of Python see the section below +If you want to install multiple versions of Python, see the section below entitled "Installing multiple versions". diff --git a/Tools/demo/markov.py b/Tools/demo/markov.py index 7a0720fa7c3..9729f3820fa 100755 --- a/Tools/demo/markov.py +++ b/Tools/demo/markov.py @@ -78,9 +78,9 @@ def test(): continue else: f = open(filename, 'r') - if debug: print('processing', filename, '...') - text = f.read() - f.close() + with f: + if debug: print('processing', filename, '...') + text = f.read() paralist = text.split('\n\n') for para in paralist: if debug > 1: print('feeding ...') diff --git a/Tools/demo/rpython.py b/Tools/demo/rpython.py index 5e7bc0a27d1..11f72cb3dd2 100755 --- a/Tools/demo/rpython.py +++ b/Tools/demo/rpython.py @@ -19,20 +19,19 @@ def main(): port = PORT i = host.find(':') if i >= 0: - port = int(port[i+1:]) + port = int(host[i+1:]) host = host[:i] command = ' '.join(sys.argv[2:]) - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, port)) - s.send(command.encode()) - s.shutdown(SHUT_WR) - reply = b'' - while True: - data = s.recv(BUFSIZE) - if not data: - break - reply += data - print(reply.decode(), end=' ') - s.close() + with socket(AF_INET, SOCK_STREAM) as s: + s.connect((host, port)) + s.send(command.encode()) + s.shutdown(SHUT_WR) + reply = b'' + while True: + data = s.recv(BUFSIZE) + if not data: + break + reply += data + print(reply.decode(), end=' ') main() diff --git a/Tools/demo/rpythond.py b/Tools/demo/rpythond.py index 9ffe13ab4fe..a885b3e946a 100755 --- a/Tools/demo/rpythond.py +++ b/Tools/demo/rpythond.py @@ -26,16 +26,16 @@ def main(): s.listen(1) while True: conn, (remotehost, remoteport) = s.accept() - print('connection from', remotehost, remoteport) - request = b'' - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - request += data - reply = execute(request.decode()) - conn.send(reply.encode()) - conn.close() + with conn: + print('connection from', remotehost, remoteport) + request = b'' + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + request += data + reply = execute(request.decode()) + conn.send(reply.encode()) def execute(request): stdout = sys.stdout diff --git a/Tools/freeze/checkextensions_win32.py b/Tools/freeze/checkextensions_win32.py index c9cb576ae52..64350df2b84 100644 --- a/Tools/freeze/checkextensions_win32.py +++ b/Tools/freeze/checkextensions_win32.py @@ -130,7 +130,8 @@ def parse_dsp(dsp): ret = [] dsp_path, dsp_name = os.path.split(dsp) try: - lines = open(dsp, "r").readlines() + with open(dsp, "r") as fp: + lines = fp.readlines() except IOError as msg: sys.stderr.write("%s: %s\n" % (dsp, msg)) return None diff --git a/Tools/freeze/freeze.py b/Tools/freeze/freeze.py index 3ab56fd0fe1..83aa508a46a 100755 --- a/Tools/freeze/freeze.py +++ b/Tools/freeze/freeze.py @@ -142,7 +142,8 @@ def main(): # last option can not be "-i", so this ensures "pos+1" is in range! if sys.argv[pos] == '-i': try: - options = open(sys.argv[pos+1]).read().split() + with open(sys.argv[pos+1]) as infp: + options = infp.read().split() except IOError as why: usage("File name '%s' specified with the -i option " "can not be read - %s" % (sys.argv[pos+1], why) ) diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index b46dd339736..b1d281d793b 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -561,9 +561,8 @@ class Options: # initialize list of strings to exclude if options.excludefilename: try: - fp = open(options.excludefilename) - options.toexclude = fp.readlines() - fp.close() + with open(options.excludefilename) as fp: + options.toexclude = fp.readlines() except IOError: print(_( "Can't read --exclude-file: %s") % options.excludefilename, file=sys.stderr) diff --git a/Tools/importbench/importbench.py b/Tools/importbench/importbench.py index e2ef75836ed..6c4a537ad86 100644 --- a/Tools/importbench/importbench.py +++ b/Tools/importbench/importbench.py @@ -183,8 +183,8 @@ def main(import_, options): benchmarks = [b] break else: - print('Unknown benchmark: {!r}'.format(options.benchmark, - file=sys.stderr)) + print('Unknown benchmark: {!r}'.format(options.benchmark), + file=sys.stderr) sys.exit(1) seconds = 1 seconds_plural = 's' if seconds > 1 else '' diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 8fa612e9ddc..532cebc5b51 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -6,7 +6,7 @@ set PCBUILD=%D%..\..\PCbuild\ set BUILDX86= set BUILDX64= set BUILDDOC= -set BUILDTEST=--test-marker +set BUILDTEST= set BUILDPACK= set REBUILD= @@ -16,6 +16,7 @@ if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts +if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts @@ -69,11 +70,12 @@ if defined BUILDX64 ( exit /B 0 :Help -echo build.bat [-x86] [-x64] [--doc] [-h] [--no-test-marker] [--pack] [-r] +echo build.bat [-x86] [-x64] [--doc] [-h] [--test-marker] [--pack] [-r] echo. echo -x86 Build x86 installers echo -x64 Build x64 installers echo --doc Build CHM documentation -echo --no-test-marker Build without test markers +echo --test-marker Build with test markers +echo --no-test-marker Build without test markers (default) echo --pack Embed core MSIs into installer echo -r Rebuild rather than incremental build diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index 2e468b7e57b..7cd8fb8e058 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -2989,9 +2989,20 @@ private: LOC_STRING *pLocString = nullptr; if (IsWindowsServer()) { - if (IsWindowsVersionOrGreater(6, 1, 1)) { - BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows Server 2008 R2 or later"); + if (IsWindowsVersionOrGreater(6, 2, 0)) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows Server 2012 or later"); return; + } else if (IsWindowsVersionOrGreater(6, 1, 1)) { + HMODULE hKernel32 = GetModuleHandleW(L"kernel32"); + if (hKernel32 && !GetProcAddress(hKernel32, "AddDllDirectory")) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Server 2008 R2 without KB2533625"); + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "KB2533625 update is required to continue."); + /* The "MissingSP1" error also specifies updates are required */ + LocGetString(_wixLoc, L"#(loc.FailureWS2K8R2MissingSP1)", &pLocString); + } else { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows Server 2008 R2 or later"); + return; + } } else if (IsWindowsVersionOrGreater(6, 1, 0)) { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Server 2008 R2"); BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Service Pack 1 is required to continue installation"); @@ -3009,9 +3020,20 @@ private: LocGetString(_wixLoc, L"#(loc.FailureWS2K3OrEarlier)", &pLocString); } } else { - if (IsWindows7SP1OrGreater()) { - BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows 7 SP1 or later"); + if (IsWindows8OrGreater()) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows 8 or later"); return; + } else if (IsWindows7SP1OrGreater()) { + HMODULE hKernel32 = GetModuleHandleW(L"kernel32"); + if (hKernel32 && !GetProcAddress(hKernel32, "AddDllDirectory")) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows 7 SP1 without KB2533625"); + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "KB2533625 update is required to continue."); + /* The "MissingSP1" error also specifies updates are required */ + LocGetString(_wixLoc, L"#(loc.FailureWin7MissingSP1)", &pLocString); + } else { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Target OS is Windows 7 SP1 or later"); + return; + } } else if (IsWindows7OrGreater()) { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows 7 RTM"); BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Service Pack 1 is required to continue installation"); diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs index a9952bdac4d..b462372512f 100644 --- a/Tools/msi/lib/lib_files.wxs +++ b/Tools/msi/lib/lib_files.wxs @@ -22,6 +22,9 @@ + + + @@ -69,6 +72,15 @@ + + + + + + + + + @@ -87,6 +99,12 @@ + + + + + + diff --git a/Tools/msi/make_cat.ps1 b/Tools/msi/make_cat.ps1 index 70741439869..cc3cd4a2b50 100644 --- a/Tools/msi/make_cat.ps1 +++ b/Tools/msi/make_cat.ps1 @@ -16,6 +16,7 @@ #> param( [Parameter(Mandatory=$true)][string]$catalog, + [switch]$sign, [string]$description, [string]$certname, [string]$certsha1, @@ -31,4 +32,6 @@ MakeCat $catalog if (-not $?) { throw "Catalog compilation failed" } -Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files @($catalog -replace 'cdf$', 'cat') +if ($sign) { + Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files @($catalog -replace 'cdf$', 'cat') +} diff --git a/Tools/msi/sdktools.psm1 b/Tools/msi/sdktools.psm1 index 61edb341176..8081b104d85 100644 --- a/Tools/msi/sdktools.psm1 +++ b/Tools/msi/sdktools.psm1 @@ -31,6 +31,10 @@ function Sign-File { $certfile = $env:SigningCertificateFile; } + if (-not ($certsha1 -or $certname -or $certfile)) { + throw "No signing certificate specified" + } + foreach ($a in $files) { if ($certsha1) { SignTool sign /sha1 $certsha1 /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a @@ -38,8 +42,6 @@ function Sign-File { SignTool sign /a /n $certname /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a } elseif ($certfile) { SignTool sign /f $certfile /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a - } else { - SignTool sign /a /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d $description $a } } } diff --git a/Tools/nuget/build.bat b/Tools/nuget/build.bat index f75cb3f7ba4..b532bd74216 100644 --- a/Tools/nuget/build.bat +++ b/Tools/nuget/build.bat @@ -6,20 +6,24 @@ if "%Py_OutDir%"=="" set Py_OutDir=%PCBUILD% set BUILDX86= set BUILDX64= +set BUILDARM32= set REBUILD= set OUTPUT= set PACKAGES= +set PYTHON_EXE= :CheckOpts if "%~1" EQU "-h" goto Help if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%~1" EQU "-arm32" (set BUILDARM32=1) && shift && goto CheckOpts if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts if "%~1" EQU "-o" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts if "%~1" EQU "--out" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts if "%~1" EQU "-p" (set PACKAGES=%PACKAGES% %~2) && shift && shift && goto CheckOpts +if "%~1" EQU "--python-exe" (set PYTHON_EXE="/p:PythonExe=%~2") && shift && shift && goto CheckOpts -if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) +if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM32 (set BUILDX86=1) && (set BUILDX64=1) && (set BUILDARM32=1) call "%D%..\msi\get_externals.bat" call "%PCBUILD%find_msbuild.bat" %MSBUILD% @@ -32,7 +36,7 @@ if defined BUILDX86 ( ) else if not exist "%Py_OutDir%win32\python.exe" call "%PCBUILD%build.bat" -e if errorlevel 1 goto :eof - %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% %PYTHON_EXE% if errorlevel 1 goto :eof ) @@ -41,7 +45,16 @@ if defined BUILDX64 ( ) else if not exist "%Py_OutDir%amd64\python.exe" call "%PCBUILD%build.bat" -p x64 -e if errorlevel 1 goto :eof - %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% %PYTHON_EXE% + if errorlevel 1 goto :eof +) + +if defined BUILDARM32 ( + if defined REBUILD ( call "%PCBUILD%build.bat" -p ARM -e -r --no-tkinter + ) else if not exist "%Py_OutDir%arm32\python.exe" call "%PCBUILD%build.bat" -p ARM -e --no-tkinter + if errorlevel 1 goto :eof + + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=ARM %OUTPUT% %PACKAGES% %PYTHON_EXE% if errorlevel 1 goto :eof ) diff --git a/Tools/nuget/make_pkg.proj b/Tools/nuget/make_pkg.proj index e093a6d0bd7..b387b8eef54 100644 --- a/Tools/nuget/make_pkg.proj +++ b/Tools/nuget/make_pkg.proj @@ -4,6 +4,7 @@ {10487945-15D1-4092-A214-338395C4116B} python $(OutputName)x86 + $(OutputName)arm32 $(OutputName)daily false @@ -28,7 +29,7 @@ $(PythonArguments) -b "$(BuildPath.TrimEnd(`\`))" -s "$(PySourcePath.TrimEnd(`\`))" $(PythonArguments) -t "$(IntermediateOutputPath)obj" $(PythonArguments) --copy "$(IntermediateOutputPath)pkg" - $(PythonArguments) --include-dev --include-tools --include-pip --include-stable --include-launcher --include-props + $(PythonArguments) --preset-nuget "$(IntermediateOutputPath)pkg\pip.exe" -B -m pip install -U $(Packages) diff --git a/Tools/nuget/pythonarm32.nuspec b/Tools/nuget/pythonarm32.nuspec new file mode 100644 index 00000000000..273d79a0312 --- /dev/null +++ b/Tools/nuget/pythonarm32.nuspec @@ -0,0 +1,19 @@ + + + + pythonarm32 + Python (ARM32) + Python Software Foundation + 0.0.0.0 + https://docs.python.org/3/license.html + https://www.python.org/ + false + Installs Python ARM32 for use in build scenarios. + https://www.python.org/static/favicon.ico + python + + + + + + diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py index 70b47a17405..385902ef4bc 100644 --- a/Tools/parser/unparse.py +++ b/Tools/parser/unparse.py @@ -592,14 +592,18 @@ def _arg(self, t): def _arguments(self, t): first = True # normal arguments - defaults = [None] * (len(t.args) - len(t.defaults)) + t.defaults - for a, d in zip(t.args, defaults): + all_args = t.posonlyargs + t.args + defaults = [None] * (len(all_args) - len(t.defaults)) + t.defaults + for index, elements in enumerate(zip(all_args, defaults), 1): + a, d = elements if first:first = False else: self.write(", ") self.dispatch(a) if d: self.write("=") self.dispatch(d) + if index == len(t.posonlyargs): + self.write(", /") # varargs, or bare '*' if no varargs but keyword-only arguments present if t.vararg or t.kwonlyargs: diff --git a/Tools/scripts/cleanfuture.py b/Tools/scripts/cleanfuture.py index b48ab60dd65..94f69126321 100755 --- a/Tools/scripts/cleanfuture.py +++ b/Tools/scripts/cleanfuture.py @@ -96,11 +96,11 @@ def check(file): errprint("%r: I/O Error: %s" % (file, str(msg))) return - ff = FutureFinder(f, file) - changed = ff.run() - if changed: - ff.gettherest() - f.close() + with f: + ff = FutureFinder(f, file) + changed = ff.run() + if changed: + ff.gettherest() if changed: if verbose: print("changed.") @@ -122,9 +122,8 @@ def check(file): os.rename(file, bak) if verbose: print("renamed", file, "to", bak) - g = open(file, "w") - ff.write(g) - g.close() + with open(file, "w") as g: + ff.write(g) if verbose: print("wrote new", file) else: diff --git a/Tools/scripts/combinerefs.py b/Tools/scripts/combinerefs.py index 7ca95267c93..49ccca73909 100755 --- a/Tools/scripts/combinerefs.py +++ b/Tools/scripts/combinerefs.py @@ -85,9 +85,7 @@ def read(fileiter, pat, whilematch): else: break -def combine(fname): - f = open(fname) - +def combinefile(f): fi = iter(f) for line in read(fi, re.compile(r'^Remaining objects:$'), False): @@ -121,8 +119,11 @@ def combine(fname): print('[%s->%s]' % (addr2rc[addr], rc), end=' ') print(guts, addr2guts[addr]) - f.close() print("%d objects before, %d after" % (before, after)) +def combine(fname): + with open(fname) as f: + combinefile(f) + if __name__ == '__main__': combine(sys.argv[1]) diff --git a/Tools/scripts/dutree.py b/Tools/scripts/dutree.py index 6b4361ac613..d25cf72b707 100755 --- a/Tools/scripts/dutree.py +++ b/Tools/scripts/dutree.py @@ -4,18 +4,18 @@ import os, sys, errno def main(): - p = os.popen('du ' + ' '.join(sys.argv[1:]), 'r') total, d = None, {} - for line in p.readlines(): - i = 0 - while line[i] in '0123456789': i = i+1 - size = eval(line[:i]) - while line[i] in ' \t': i = i+1 - filename = line[i:-1] - comps = filename.split('/') - if comps[0] == '': comps[0] = '/' - if comps[len(comps)-1] == '': del comps[len(comps)-1] - total, d = store(size, comps, total, d) + with os.popen('du ' + ' '.join(sys.argv[1:])) as p: + for line in p: + i = 0 + while line[i] in '0123456789': i = i+1 + size = eval(line[:i]) + while line[i] in ' \t': i = i+1 + filename = line[i:-1] + comps = filename.split('/') + if comps[0] == '': comps[0] = '/' + if comps[len(comps)-1] == '': del comps[len(comps)-1] + total, d = store(size, comps, total, d) try: display(total, d) except IOError as e: diff --git a/Tools/scripts/eptags.py b/Tools/scripts/eptags.py index 401ac7e29cd..7f8059ba71a 100755 --- a/Tools/scripts/eptags.py +++ b/Tools/scripts/eptags.py @@ -28,29 +28,30 @@ def treat_file(filename, outfp): except OSError: sys.stderr.write('Cannot open %s\n'%filename) return - charno = 0 - lineno = 0 - tags = [] - size = 0 - while 1: - line = fp.readline() - if not line: - break - lineno = lineno + 1 - m = matcher.search(line) - if m: - tag = m.group(0) + '\177%d,%d\n' % (lineno, charno) - tags.append(tag) - size = size + len(tag) - charno = charno + len(line) + with fp: + charno = 0 + lineno = 0 + tags = [] + size = 0 + while 1: + line = fp.readline() + if not line: + break + lineno = lineno + 1 + m = matcher.search(line) + if m: + tag = m.group(0) + '\177%d,%d\n' % (lineno, charno) + tags.append(tag) + size = size + len(tag) + charno = charno + len(line) outfp.write('\f\n%s,%d\n' % (filename,size)) for tag in tags: outfp.write(tag) def main(): - outfp = open('TAGS', 'w') - for filename in sys.argv[1:]: - treat_file(filename, outfp) + with open('TAGS', 'w') as outfp: + for filename in sys.argv[1:]: + treat_file(filename, outfp) if __name__=="__main__": main() diff --git a/Tools/scripts/finddiv.py b/Tools/scripts/finddiv.py index a705f562036..d21253cf1c8 100755 --- a/Tools/scripts/finddiv.py +++ b/Tools/scripts/finddiv.py @@ -55,17 +55,17 @@ def process(filename, listnames): except IOError as msg: sys.stderr.write("Can't open: %s\n" % msg) return 1 - g = tokenize.generate_tokens(fp.readline) - lastrow = None - for type, token, (row, col), end, line in g: - if token in ("/", "/="): - if listnames: - print(filename) - break - if row != lastrow: - lastrow = row - print("%s:%d:%s" % (filename, row, line), end=' ') - fp.close() + with fp: + g = tokenize.generate_tokens(fp.readline) + lastrow = None + for type, token, (row, col), end, line in g: + if token in ("/", "/="): + if listnames: + print(filename) + break + if row != lastrow: + lastrow = row + print("%s:%d:%s" % (filename, row, line), end=' ') def processdir(dir, listnames): try: diff --git a/Tools/scripts/fixcid.py b/Tools/scripts/fixcid.py index c66a0ac093a..8f35eaeeb4f 100755 --- a/Tools/scripts/fixcid.py +++ b/Tools/scripts/fixcid.py @@ -281,36 +281,36 @@ def addsubst(substfile): except IOError as msg: err(substfile + ': cannot read substfile: ' + str(msg) + '\n') sys.exit(1) - lineno = 0 - while 1: - line = fp.readline() - if not line: break - lineno = lineno + 1 - try: - i = line.index('#') - except ValueError: - i = -1 # Happens to delete trailing \n - words = line[:i].split() - if not words: continue - if len(words) == 3 and words[0] == 'struct': - words[:2] = [words[0] + ' ' + words[1]] - elif len(words) != 2: - err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line)) - continue - if Reverse: - [value, key] = words - else: - [key, value] = words - if value[0] == '*': - value = value[1:] - if key[0] == '*': - key = key[1:] - NotInComment[key] = value - if key in Dict: - err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value)) - err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key])) - Dict[key] = value - fp.close() + with fp: + lineno = 0 + while 1: + line = fp.readline() + if not line: break + lineno = lineno + 1 + try: + i = line.index('#') + except ValueError: + i = -1 # Happens to delete trailing \n + words = line[:i].split() + if not words: continue + if len(words) == 3 and words[0] == 'struct': + words[:2] = [words[0] + ' ' + words[1]] + elif len(words) != 2: + err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line)) + continue + if Reverse: + [value, key] = words + else: + [key, value] = words + if value[0] == '*': + value = value[1:] + if key[0] == '*': + key = key[1:] + NotInComment[key] = value + if key in Dict: + err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value)) + err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key])) + Dict[key] = value if __name__ == '__main__': main() diff --git a/Tools/scripts/fixdiv.py b/Tools/scripts/fixdiv.py index 1213a4e3976..df7c481aa22 100755 --- a/Tools/scripts/fixdiv.py +++ b/Tools/scripts/fixdiv.py @@ -179,27 +179,27 @@ def usage(msg): def readwarnings(warningsfile): prog = re.compile(PATTERN) + warnings = {} try: f = open(warningsfile) except IOError as msg: sys.stderr.write("can't open: %s\n" % msg) return - warnings = {} - while 1: - line = f.readline() - if not line: - break - m = prog.match(line) - if not m: - if line.find("division") >= 0: - sys.stderr.write("Warning: ignored input " + line) - continue - filename, lineno, what = m.groups() - list = warnings.get(filename) - if list is None: - warnings[filename] = list = [] - list.append((int(lineno), sys.intern(what))) - f.close() + with f: + while 1: + line = f.readline() + if not line: + break + m = prog.match(line) + if not m: + if line.find("division") >= 0: + sys.stderr.write("Warning: ignored input " + line) + continue + filename, lineno, what = m.groups() + list = warnings.get(filename) + if list is None: + warnings[filename] = list = [] + list.append((int(lineno), sys.intern(what))) return warnings def process(filename, list): @@ -210,84 +210,84 @@ def process(filename, list): except IOError as msg: sys.stderr.write("can't open: %s\n" % msg) return 1 - print("Index:", filename) - f = FileContext(fp) - list.sort() - index = 0 # list[:index] has been processed, list[index:] is still to do - g = tokenize.generate_tokens(f.readline) - while 1: - startlineno, endlineno, slashes = lineinfo = scanline(g) - if startlineno is None: - break - assert startlineno <= endlineno is not None - orphans = [] - while index < len(list) and list[index][0] < startlineno: - orphans.append(list[index]) - index += 1 - if orphans: - reportphantomwarnings(orphans, f) - warnings = [] - while index < len(list) and list[index][0] <= endlineno: - warnings.append(list[index]) - index += 1 - if not slashes and not warnings: - pass - elif slashes and not warnings: - report(slashes, "No conclusive evidence") - elif warnings and not slashes: - reportphantomwarnings(warnings, f) - else: - if len(slashes) > 1: - if not multi_ok: - rows = [] - lastrow = None - for (row, col), line in slashes: - if row == lastrow: - continue - rows.append(row) - lastrow = row - assert rows - if len(rows) == 1: - print("*** More than one / operator in line", rows[0]) + with fp: + print("Index:", filename) + f = FileContext(fp) + list.sort() + index = 0 # list[:index] has been processed, list[index:] is still to do + g = tokenize.generate_tokens(f.readline) + while 1: + startlineno, endlineno, slashes = lineinfo = scanline(g) + if startlineno is None: + break + assert startlineno <= endlineno is not None + orphans = [] + while index < len(list) and list[index][0] < startlineno: + orphans.append(list[index]) + index += 1 + if orphans: + reportphantomwarnings(orphans, f) + warnings = [] + while index < len(list) and list[index][0] <= endlineno: + warnings.append(list[index]) + index += 1 + if not slashes and not warnings: + pass + elif slashes and not warnings: + report(slashes, "No conclusive evidence") + elif warnings and not slashes: + reportphantomwarnings(warnings, f) + else: + if len(slashes) > 1: + if not multi_ok: + rows = [] + lastrow = None + for (row, col), line in slashes: + if row == lastrow: + continue + rows.append(row) + lastrow = row + assert rows + if len(rows) == 1: + print("*** More than one / operator in line", rows[0]) + else: + print("*** More than one / operator per statement", end=' ') + print("in lines %d-%d" % (rows[0], rows[-1])) + intlong = [] + floatcomplex = [] + bad = [] + for lineno, what in warnings: + if what in ("int", "long"): + intlong.append(what) + elif what in ("float", "complex"): + floatcomplex.append(what) else: - print("*** More than one / operator per statement", end=' ') - print("in lines %d-%d" % (rows[0], rows[-1])) - intlong = [] - floatcomplex = [] - bad = [] - for lineno, what in warnings: - if what in ("int", "long"): - intlong.append(what) - elif what in ("float", "complex"): - floatcomplex.append(what) - else: - bad.append(what) - lastrow = None - for (row, col), line in slashes: - if row == lastrow: - continue - lastrow = row - line = chop(line) - if line[col:col+1] != "/": - print("*** Can't find the / operator in line %d:" % row) - print("*", line) - continue - if bad: - print("*** Bad warning for line %d:" % row, bad) - print("*", line) - elif intlong and not floatcomplex: - print("%dc%d" % (row, row)) - print("<", line) - print("---") - print(">", line[:col] + "/" + line[col:]) - elif floatcomplex and not intlong: - print("True division / operator at line %d:" % row) - print("=", line) - elif intlong and floatcomplex: - print("*** Ambiguous / operator (%s, %s) at line %d:" % ( - "|".join(intlong), "|".join(floatcomplex), row)) - print("?", line) - fp.close() + bad.append(what) + lastrow = None + for (row, col), line in slashes: + if row == lastrow: + continue + lastrow = row + line = chop(line) + if line[col:col+1] != "/": + print("*** Can't find the / operator in line %d:" % row) + print("*", line) + continue + if bad: + print("*** Bad warning for line %d:" % row, bad) + print("*", line) + elif intlong and not floatcomplex: + print("%dc%d" % (row, row)) + print("<", line) + print("---") + print(">", line[:col] + "/" + line[col:]) + elif floatcomplex and not intlong: + print("True division / operator at line %d:" % row) + print("=", line) + elif intlong and floatcomplex: + print("*** Ambiguous / operator (%s, %s) at line %d:" % + ("|".join(intlong), "|".join(floatcomplex), row)) + print("?", line) def reportphantomwarnings(warnings, f): blocks = [] diff --git a/Tools/scripts/fixheader.py b/Tools/scripts/fixheader.py index ec840575b20..c834eec1e20 100755 --- a/Tools/scripts/fixheader.py +++ b/Tools/scripts/fixheader.py @@ -15,8 +15,8 @@ def process(filename): except IOError as msg: sys.stderr.write('%s: can\'t open: %s\n' % (filename, str(msg))) return - data = f.read() - f.close() + with f: + data = f.read() if data[:2] != '/*': sys.stderr.write('%s does not begin with C comment\n' % filename) return @@ -25,25 +25,25 @@ def process(filename): except IOError as msg: sys.stderr.write('%s: can\'t write: %s\n' % (filename, str(msg))) return - sys.stderr.write('Processing %s ...\n' % filename) - magic = 'Py_' - for c in filename: - if ord(c)<=0x80 and c.isalnum(): - magic = magic + c.upper() - else: magic = magic + '_' - sys.stdout = f - print('#ifndef', magic) - print('#define', magic) - print('#ifdef __cplusplus') - print('extern "C" {') - print('#endif') - print() - f.write(data) - print() - print('#ifdef __cplusplus') - print('}') - print('#endif') - print('#endif /*', '!'+magic, '*/') + with f: + sys.stderr.write('Processing %s ...\n' % filename) + magic = 'Py_' + for c in filename: + if ord(c)<=0x80 and c.isalnum(): + magic = magic + c.upper() + else: magic = magic + '_' + print('#ifndef', magic, file=f) + print('#define', magic, file=f) + print('#ifdef __cplusplus', file=f) + print('extern "C" {', file=f) + print('#endif', file=f) + print(file=f) + f.write(data) + print(file=f) + print('#ifdef __cplusplus', file=f) + print('}', file=f) + print('#endif', file=f) + print('#endif /*', '!'+magic, '*/', file=f) if __name__ == '__main__': main() diff --git a/Tools/scripts/fixnotice.py b/Tools/scripts/fixnotice.py index ad967f94781..317051dd82f 100755 --- a/Tools/scripts/fixnotice.py +++ b/Tools/scripts/fixnotice.py @@ -73,22 +73,19 @@ def main(): elif opt == '--dry-run': DRYRUN = 1 elif opt == '--oldnotice': - fp = open(arg) - OLD_NOTICE = fp.read() - fp.close() + with open(arg) as fp: + OLD_NOTICE = fp.read() elif opt == '--newnotice': - fp = open(arg) - NEW_NOTICE = fp.read() - fp.close() + with open(arg) as fp: + NEW_NOTICE = fp.read() for arg in args: process(arg) def process(file): - f = open(file) - data = f.read() - f.close() + with open(file) as f: + data = f.read() i = data.find(OLD_NOTICE) if i < 0: if VERBOSE: @@ -102,9 +99,8 @@ def process(file): data = data[:i] + NEW_NOTICE + data[i+len(OLD_NOTICE):] new = file + ".new" backup = file + ".bak" - f = open(new, "w") - f.write(data) - f.close() + with open(new, "w") as f: + f.write(data) os.rename(file, backup) os.rename(new, file) diff --git a/Tools/scripts/fixps.py b/Tools/scripts/fixps.py index b0022612068..725300e56a2 100755 --- a/Tools/scripts/fixps.py +++ b/Tools/scripts/fixps.py @@ -14,20 +14,18 @@ def main(): except IOError as msg: print(filename, ': can\'t open :', msg) continue - line = f.readline() - if not re.match('^#! */usr/local/bin/python', line): - print(filename, ': not a /usr/local/bin/python script') - f.close() - continue - rest = f.read() - f.close() + with f: + line = f.readline() + if not re.match('^#! */usr/local/bin/python', line): + print(filename, ': not a /usr/local/bin/python script') + continue + rest = f.read() line = re.sub('/usr/local/bin/python', '/usr/bin/env python', line) print(filename, ':', repr(line)) - f = open(filename, "w") - f.write(line) - f.write(rest) - f.close() + with open(filename, "w") as f: + f.write(line) + f.write(rest) if __name__ == '__main__': main() diff --git a/Tools/scripts/get-remote-certificate.py b/Tools/scripts/get-remote-certificate.py index 5811f202eda..38901286e19 100755 --- a/Tools/scripts/get-remote-certificate.py +++ b/Tools/scripts/get-remote-certificate.py @@ -29,9 +29,8 @@ def strip_to_x509_cert(certfile_contents, outfile=None): return None else: tn = tempfile.mktemp() - fp = open(tn, "wb") - fp.write(m.group(1) + b"\n") - fp.close() + with open(tn, "wb") as fp: + fp.write(m.group(1) + b"\n") try: tn2 = (outfile or tempfile.mktemp()) status, output = subproc(r'openssl x509 -in "%s" -out "%s"' % @@ -39,9 +38,8 @@ def strip_to_x509_cert(certfile_contents, outfile=None): if status != 0: raise RuntimeError('OpenSSL x509 failed with status %s and ' 'output: %r' % (status, output)) - fp = open(tn2, 'rb') - data = fp.read() - fp.close() + with open(tn2, 'rb') as fp: + data = fp.read() os.unlink(tn2) return data finally: @@ -49,9 +47,8 @@ def strip_to_x509_cert(certfile_contents, outfile=None): if sys.platform.startswith("win"): tfile = tempfile.mktemp() - fp = open(tfile, "w") - fp.write("quit\n") - fp.close() + with open(tfile, "w") as fp: + fp.write("quit\n") try: status, output = subproc( 'openssl s_client -connect "%s:%s" -showcerts < "%s"' % diff --git a/Tools/scripts/gprof2html.py b/Tools/scripts/gprof2html.py index 4ca705c3c61..b14def4ef84 100755 --- a/Tools/scripts/gprof2html.py +++ b/Tools/scripts/gprof2html.py @@ -28,14 +28,7 @@ def add_escapes(filename): for line in fp: yield html.escape(line) - -def main(): - filename = "gprof.out" - if sys.argv[1:]: - filename = sys.argv[1] - outputfilename = filename + ".html" - input = add_escapes(filename) - output = open(outputfilename, "w") +def gprof2html(input, output, filename): output.write(header % filename) for line in input: output.write(line) @@ -78,7 +71,16 @@ def main(): part = '%s' % (part, part) output.write(part) output.write(trailer) - output.close() + + +def main(): + filename = "gprof.out" + if sys.argv[1:]: + filename = sys.argv[1] + outputfilename = filename + ".html" + input = add_escapes(filename) + with open(outputfilename, "w") as output: + gprof2html(input, output, filename) webbrowser.open("file:" + os.path.abspath(outputfilename)) if __name__ == '__main__': diff --git a/Tools/scripts/h2py.py b/Tools/scripts/h2py.py index 4363c0cf735..ea37c04d4c5 100755 --- a/Tools/scripts/h2py.py +++ b/Tools/scripts/h2py.py @@ -69,23 +69,21 @@ def main(): sys.stdout.write('# Generated by h2py from stdin\n') process(sys.stdin, sys.stdout) else: - fp = open(filename, 'r') - outfile = os.path.basename(filename) - i = outfile.rfind('.') - if i > 0: outfile = outfile[:i] - modname = outfile.upper() - outfile = modname + '.py' - outfp = open(outfile, 'w') - outfp.write('# Generated by h2py from %s\n' % filename) - filedict = {} - for dir in searchdirs: - if filename[:len(dir)] == dir: - filedict[filename[len(dir)+1:]] = None # no '/' trailing - importable[filename[len(dir)+1:]] = modname - break - process(fp, outfp) - outfp.close() - fp.close() + with open(filename) as fp: + outfile = os.path.basename(filename) + i = outfile.rfind('.') + if i > 0: outfile = outfile[:i] + modname = outfile.upper() + outfile = modname + '.py' + with open(outfile, 'w') as outfp: + outfp.write('# Generated by h2py from %s\n' % filename) + filedict = {} + for dir in searchdirs: + if filename[:len(dir)] == dir: + filedict[filename[len(dir)+1:]] = None # no '/' trailing + importable[filename[len(dir)+1:]] = modname + break + process(fp, outfp) def pytify(body): # replace ignored patterns by spaces @@ -161,9 +159,10 @@ def process(fp, outfp, env = {}): except IOError: pass if inclfp: - outfp.write( - '\n# Included from %s\n' % filename) - process(inclfp, outfp, env) + with inclfp: + outfp.write( + '\n# Included from %s\n' % filename) + process(inclfp, outfp, env) else: sys.stderr.write('Warning - could not find file %s\n' % filename) diff --git a/Tools/scripts/ifdef.py b/Tools/scripts/ifdef.py index b1711ce5c16..22249b2d0af 100755 --- a/Tools/scripts/ifdef.py +++ b/Tools/scripts/ifdef.py @@ -45,9 +45,8 @@ def main(): if filename == '-': process(sys.stdin, sys.stdout) else: - f = open(filename, 'r') - process(f, sys.stdout) - f.close() + with open(filename) as f: + process(f, sys.stdout) def process(fpi, fpo): keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif') diff --git a/Tools/scripts/lll.py b/Tools/scripts/lll.py index aa4e55091e5..1b48eac8aad 100755 --- a/Tools/scripts/lll.py +++ b/Tools/scripts/lll.py @@ -13,8 +13,7 @@ def lll(dirname): full = os.path.join(dirname, name) if os.path.islink(full): print(name, '->', os.readlink(full)) -def main(): - args = sys.argv[1:] +def main(args): if not args: args = [os.curdir] first = 1 for arg in args: @@ -22,7 +21,7 @@ def main(): if not first: print() first = 0 print(arg + ':') - lll(arg) + lll(arg) if __name__ == '__main__': - main() + main(sys.argv[1:]) diff --git a/Tools/scripts/md5sum.py b/Tools/scripts/md5sum.py index 9cf4bdc9c69..f910576377a 100755 --- a/Tools/scripts/md5sum.py +++ b/Tools/scripts/md5sum.py @@ -47,10 +47,10 @@ def printsum(filename, out=sys.stdout): except IOError as msg: sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg)) return 1 - if fnfilter: - filename = fnfilter(filename) - sts = printsumfp(fp, filename, out) - fp.close() + with fp: + if fnfilter: + filename = fnfilter(filename) + sts = printsumfp(fp, filename, out) return sts def printsumfp(fp, filename, out=sys.stdout): diff --git a/Tools/scripts/mkreal.py b/Tools/scripts/mkreal.py index b21909e691d..f169da43fe1 100755 --- a/Tools/scripts/mkreal.py +++ b/Tools/scripts/mkreal.py @@ -18,14 +18,13 @@ def mkrealfile(name): st = os.stat(name) # Get the mode mode = S_IMODE(st[ST_MODE]) linkto = os.readlink(name) # Make sure again it's a symlink - f_in = open(name, 'r') # This ensures it's a file - os.unlink(name) - f_out = open(name, 'w') - while 1: - buf = f_in.read(BUFSIZE) - if not buf: break - f_out.write(buf) - del f_out # Flush data to disk before changing mode + with open(name, 'rb') as f_in: # This ensures it's a file + os.unlink(name) + with open(name, 'wb') as f_out: + while 1: + buf = f_in.read(BUFSIZE) + if not buf: break + f_out.write(buf) os.chmod(name, mode) def mkrealdir(name): diff --git a/Tools/scripts/nm2def.py b/Tools/scripts/nm2def.py index 83bbcd749f4..a885ebd6fec 100755 --- a/Tools/scripts/nm2def.py +++ b/Tools/scripts/nm2def.py @@ -42,7 +42,8 @@ def symbols(lib=PYTHONLIB,types=('T','C','D')): - lines = os.popen(NM % lib).readlines() + with os.popen(NM % lib) as pipe: + lines = pipe.readlines() lines = [s.strip() for s in lines] symbols = {} for line in lines: @@ -97,7 +98,7 @@ def main(): exports = export_list(s) f = sys.stdout # open('PC/python_nt.def','w') f.write(DEF_TEMPLATE % (exports)) - f.close() + # f.close() if __name__ == '__main__': main() diff --git a/Tools/scripts/objgraph.py b/Tools/scripts/objgraph.py index 3bb1712a9dc..add41e692c0 100755 --- a/Tools/scripts/objgraph.py +++ b/Tools/scripts/objgraph.py @@ -180,7 +180,8 @@ def main(): if filename == '-': readinput(sys.stdin) else: - readinput(open(filename, 'r')) + with open(filename) as f: + readinput(f) # warndups() # diff --git a/Tools/scripts/parseentities.py b/Tools/scripts/parseentities.py index c686b0241a7..0229d3af86b 100755 --- a/Tools/scripts/parseentities.py +++ b/Tools/scripts/parseentities.py @@ -50,13 +50,15 @@ def writefile(f,defs): if __name__ == '__main__': if len(sys.argv) > 1: - infile = open(sys.argv[1]) + with open(sys.argv[1]) as infile: + text = infile.read() else: - infile = sys.stdin - if len(sys.argv) > 2: - outfile = open(sys.argv[2],'w') - else: - outfile = sys.stdout - text = infile.read() + text = sys.stdin.read() + defs = parse(text) - writefile(outfile,defs) + + if len(sys.argv) > 2: + with open(sys.argv[2],'w') as outfile: + writefile(outfile, defs) + else: + writefile(sys.stdout, defs) diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py index c5bf984306a..1a0cf1c9e69 100755 --- a/Tools/scripts/pathfix.py +++ b/Tools/scripts/pathfix.py @@ -103,29 +103,27 @@ def fix(filename): except IOError as msg: err('%s: cannot open: %r\n' % (filename, msg)) return 1 - line = f.readline() - fixed = fixline(line) - if line == fixed: - rep(filename+': no change\n') - f.close() - return - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - try: - g = open(tempname, 'wb') - except IOError as msg: - f.close() - err('%s: cannot create: %r\n' % (tempname, msg)) - return 1 - rep(filename + ': updating\n') - g.write(fixed) - BUFSIZE = 8*1024 - while 1: - buf = f.read(BUFSIZE) - if not buf: break - g.write(buf) - g.close() - f.close() + with f: + line = f.readline() + fixed = fixline(line) + if line == fixed: + rep(filename+': no change\n') + return + head, tail = os.path.split(filename) + tempname = os.path.join(head, '@' + tail) + try: + g = open(tempname, 'wb') + except IOError as msg: + err('%s: cannot create: %r\n' % (tempname, msg)) + return 1 + with g: + rep(filename + ': updating\n') + g.write(fixed) + BUFSIZE = 8*1024 + while 1: + buf = f.read(BUFSIZE) + if not buf: break + g.write(buf) # Finishing touch -- move files diff --git a/Tools/scripts/pdeps.py b/Tools/scripts/pdeps.py index f8218ac5243..4e8e930948f 100755 --- a/Tools/scripts/pdeps.py +++ b/Tools/scripts/pdeps.py @@ -64,29 +64,28 @@ def main(): # Collect data from one file # def process(filename, table): - fp = open(filename, 'r') - mod = os.path.basename(filename) - if mod[-3:] == '.py': - mod = mod[:-3] - table[mod] = list = [] - while 1: - line = fp.readline() - if not line: break - while line[-1:] == '\\': - nextline = fp.readline() - if not nextline: break - line = line[:-1] + nextline - m_found = m_import.match(line) or m_from.match(line) - if m_found: - (a, b), (a1, b1) = m_found.regs[:2] - else: continue - words = line[a1:b1].split(',') - # print '#', line, words - for word in words: - word = word.strip() - if word not in list: - list.append(word) - fp.close() + with open(filename) as fp: + mod = os.path.basename(filename) + if mod[-3:] == '.py': + mod = mod[:-3] + table[mod] = list = [] + while 1: + line = fp.readline() + if not line: break + while line[-1:] == '\\': + nextline = fp.readline() + if not nextline: break + line = line[:-1] + nextline + m_found = m_import.match(line) or m_from.match(line) + if m_found: + (a, b), (a1, b1) = m_found.regs[:2] + else: continue + words = line[a1:b1].split(',') + # print '#', line, words + for word in words: + word = word.strip() + if word not in list: + list.append(word) # Compute closure (this is in fact totally general) diff --git a/Tools/scripts/ptags.py b/Tools/scripts/ptags.py index 396cbd07ea4..eedd411702c 100755 --- a/Tools/scripts/ptags.py +++ b/Tools/scripts/ptags.py @@ -19,9 +19,9 @@ def main(): for filename in args: treat_file(filename) if tags: - fp = open('tags', 'w') - tags.sort() - for s in tags: fp.write(s) + with open('tags', 'w') as fp: + tags.sort() + for s in tags: fp.write(s) expr = r'^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*[:\(]' @@ -33,21 +33,22 @@ def treat_file(filename): except: sys.stderr.write('Cannot open %s\n' % filename) return - base = os.path.basename(filename) - if base[-3:] == '.py': - base = base[:-3] - s = base + '\t' + filename + '\t' + '1\n' - tags.append(s) - while 1: - line = fp.readline() - if not line: - break - m = matcher.match(line) - if m: - content = m.group(0) - name = m.group(2) - s = name + '\t' + filename + '\t/^' + content + '/\n' - tags.append(s) + with fp: + base = os.path.basename(filename) + if base[-3:] == '.py': + base = base[:-3] + s = base + '\t' + filename + '\t' + '1\n' + tags.append(s) + while 1: + line = fp.readline() + if not line: + break + m = matcher.match(line) + if m: + content = m.group(0) + name = m.group(2) + s = name + '\t' + filename + '\t/^' + content + '/\n' + tags.append(s) if __name__ == '__main__': main() diff --git a/Tools/scripts/rgrep.py b/Tools/scripts/rgrep.py index 1917e05e494..c39bf93aad3 100755 --- a/Tools/scripts/rgrep.py +++ b/Tools/scripts/rgrep.py @@ -30,29 +30,30 @@ def main(): f = open(filename) except IOError as msg: usage("can't open %r: %s" % (filename, msg), 1) - f.seek(0, 2) - pos = f.tell() - leftover = None - while pos > 0: - size = min(pos, bufsize) - pos = pos - size - f.seek(pos) - buffer = f.read(size) - lines = buffer.split("\n") - del buffer - if leftover is None: - if not lines[-1]: - del lines[-1] - else: - lines[-1] = lines[-1] + leftover - if pos > 0: - leftover = lines[0] - del lines[0] - else: - leftover = None - for line in reversed(lines): - if prog.search(line): - print(line) + with f: + f.seek(0, 2) + pos = f.tell() + leftover = None + while pos > 0: + size = min(pos, bufsize) + pos = pos - size + f.seek(pos) + buffer = f.read(size) + lines = buffer.split("\n") + del buffer + if leftover is None: + if not lines[-1]: + del lines[-1] + else: + lines[-1] = lines[-1] + leftover + if pos > 0: + leftover = lines[0] + del lines[0] + else: + leftover = None + for line in reversed(lines): + if prog.search(line): + print(line) def usage(msg, code=2): diff --git a/Tools/scripts/serve.py b/Tools/scripts/serve.py index dae21f2260f..7ac9c105078 100755 --- a/Tools/scripts/serve.py +++ b/Tools/scripts/serve.py @@ -25,11 +25,12 @@ def app(environ, respond): return [b'not found'] if __name__ == '__main__': - path = sys.argv[1] + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 httpd = simple_server.make_server('', port, app) print("Serving {} on port {}, control-C to stop".format(path, port)) try: httpd.serve_forever() except KeyboardInterrupt: - print("\b\bShutting down.") + print("Shutting down.") + httpd.server_close() diff --git a/Tools/scripts/texi2html.py b/Tools/scripts/texi2html.py index 5565c210dab..c06d812ab3f 100755 --- a/Tools/scripts/texi2html.py +++ b/Tools/scripts/texi2html.py @@ -118,11 +118,10 @@ def write(self, *lines): self.lines.append(line) def flush(self): - fp = open(self.dirname + '/' + makefile(self.name), 'w') - fp.write(self.prologue) - fp.write(self.text) - fp.write(self.epilogue) - fp.close() + with open(self.dirname + '/' + makefile(self.name), 'w') as fp: + fp.write(self.prologue) + fp.write(self.text) + fp.write(self.epilogue) def link(self, label, nodename, rel=None, rev=None): if nodename: @@ -558,14 +557,14 @@ def do_include(self, args): except IOError as msg: print('*** Can\'t open include file', repr(file)) return - print('!'*self.debugging, '--> file', repr(file)) - save_done = self.done - save_skip = self.skip - save_stack = self.stack - self.includedepth = self.includedepth + 1 - self.parserest(fp, 0) - self.includedepth = self.includedepth - 1 - fp.close() + with fp: + print('!'*self.debugging, '--> file', repr(file)) + save_done = self.done + save_skip = self.skip + save_stack = self.stack + self.includedepth = self.includedepth + 1 + self.parserest(fp, 0) + self.includedepth = self.includedepth - 1 self.done = save_done self.skip = save_skip self.stack = save_stack @@ -1770,78 +1769,75 @@ def finalize(self): # PROJECT FILE try: - fp = open(projectfile,'w') - print('[OPTIONS]', file=fp) - print('Auto Index=Yes', file=fp) - print('Binary TOC=No', file=fp) - print('Binary Index=Yes', file=fp) - print('Compatibility=1.1', file=fp) - print('Compiled file=' + resultfile + '', file=fp) - print('Contents file=' + contentfile + '', file=fp) - print('Default topic=' + defaulttopic + '', file=fp) - print('Error log file=ErrorLog.log', file=fp) - print('Index file=' + indexfile + '', file=fp) - print('Title=' + title + '', file=fp) - print('Display compile progress=Yes', file=fp) - print('Full-text search=Yes', file=fp) - print('Default window=main', file=fp) - print('', file=fp) - print('[WINDOWS]', file=fp) - print('main=,"' + contentfile + '","' + indexfile - + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],' - '0xB0000,,,,,,0', file=fp) - print('', file=fp) - print('[FILES]', file=fp) - print('', file=fp) - self.dumpfiles(fp) - fp.close() + with open(projectfile, 'w') as fp: + print('[OPTIONS]', file=fp) + print('Auto Index=Yes', file=fp) + print('Binary TOC=No', file=fp) + print('Binary Index=Yes', file=fp) + print('Compatibility=1.1', file=fp) + print('Compiled file=' + resultfile + '', file=fp) + print('Contents file=' + contentfile + '', file=fp) + print('Default topic=' + defaulttopic + '', file=fp) + print('Error log file=ErrorLog.log', file=fp) + print('Index file=' + indexfile + '', file=fp) + print('Title=' + title + '', file=fp) + print('Display compile progress=Yes', file=fp) + print('Full-text search=Yes', file=fp) + print('Default window=main', file=fp) + print('', file=fp) + print('[WINDOWS]', file=fp) + print('main=,"' + contentfile + '","' + indexfile + + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],' + '0xB0000,,,,,,0', file=fp) + print('', file=fp) + print('[FILES]', file=fp) + print('', file=fp) + self.dumpfiles(fp) except IOError as msg: print(projectfile, ':', msg) sys.exit(1) # CONTENT FILE try: - fp = open(contentfile,'w') - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - self.dumpnodes(fp) - print('', file=fp) - print('', file=fp) - fp.close() + with open(contentfile, 'w') as fp: + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print(' ', file=fp) + print(' ', file=fp) + print(' ', file=fp) + print(' ', file=fp) + print(' ', file=fp) + self.dumpnodes(fp) + print('', file=fp) + print('', file=fp) except IOError as msg: print(contentfile, ':', msg) sys.exit(1) # INDEX FILE try: - fp = open(indexfile ,'w') - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - self.dumpindex(fp) - print('', file=fp) - print('', file=fp) - fp.close() + with open(indexfile, 'w') as fp: + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + print('', file=fp) + self.dumpindex(fp) + print('', file=fp) + print('', file=fp) except IOError as msg: print(indexfile , ':', msg) sys.exit(1) @@ -2064,8 +2060,8 @@ def test(): print(file, ':', msg) sys.exit(1) - parser.parse(fp) - fp.close() + with fp: + parser.parse(fp) parser.report() htmlhelp.finalize() diff --git a/Tools/unicode/gencjkcodecs.py b/Tools/unicode/gencjkcodecs.py index ebccfc7f96b..45866bf2f61 100644 --- a/Tools/unicode/gencjkcodecs.py +++ b/Tools/unicode/gencjkcodecs.py @@ -61,7 +61,8 @@ def gencodecs(prefix): encoding=enc.lower(), owner=loc) codecpath = os.path.join(prefix, enc + '.py') - open(codecpath, 'w').write(code) + with open(codecpath, 'w') as f: + f.write(code) if __name__ == '__main__': import sys diff --git a/Tools/unicode/gencodec.py b/Tools/unicode/gencodec.py index 31f0112150d..1e5aced63aa 100644 --- a/Tools/unicode/gencodec.py +++ b/Tools/unicode/gencodec.py @@ -72,9 +72,8 @@ def parsecodes(codes, len=len, range=range): def readmap(filename): - f = open(filename,'r') - lines = f.readlines() - f.close() + with open(filename) as f: + lines = f.readlines() enc2uni = {} identity = [] unmapped = list(range(256)) @@ -359,18 +358,16 @@ def getregentry(): def pymap(name,map,pyfile,encodingname,comments=1): code = codegen(name,map,encodingname,comments) - f = open(pyfile,'w') - f.write(code) - f.close() + with open(pyfile,'w') as f: + f.write(code) def marshalmap(name,map,marshalfile): d = {} for e,(u,c) in map.items(): d[e] = (u,c) - f = open(marshalfile,'wb') - marshal.dump(d,f) - f.close() + with open(marshalfile,'wb') as f: + marshal.dump(d,f) def convertdir(dir, dirprefix='', nameprefix='', comments=1): @@ -411,8 +408,8 @@ def rewritepythondir(dir, dirprefix='', comments=1): print('converting %s to %s' % (mapname, dirprefix + codefile)) try: - map = marshal.load(open(os.path.join(dir,mapname), - 'rb')) + with open(os.path.join(dir, mapname), 'rb') as f: + map = marshal.load(f) if not map: print('* map is empty; skipping') else: diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 9327693a173..2550b8f940c 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -1249,7 +1249,7 @@ def dump(self, file, trace=0): size = getsize(self.data) if trace: print(self.name+":", size*len(self.data), "bytes", file=sys.stderr) - file.write("static ") + file.write("static const ") if size == 1: file.write("unsigned char") elif size == 2: diff --git a/configure b/configure index d0ef8a601b2..e6e40073515 100755 --- a/configure +++ b/configure @@ -631,7 +631,9 @@ SRCDIRS THREADHEADERS LIBPL PY_ENABLE_SHARED +LIBPYTHON EXT_SUFFIX +ALT_SOABI SOABI LIBC LIBM @@ -783,7 +785,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -815,6 +816,7 @@ with_suffix enable_shared enable_profiling with_pydebug +with_trace_refs with_assertions enable_optimizations with_lto @@ -895,7 +897,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1148,15 +1149,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1294,7 +1286,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1447,7 +1439,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1512,6 +1503,7 @@ Optional Packages: compiler --with-suffix=.exe set executable suffix --with-pydebug build with Py_DEBUG defined + --with-trace-refs enable tracing references for debugging purpose --with-assertions build with C assertions enabled --with-lto Enable Link Time Optimization in any build. Disabled by default. @@ -3293,6 +3285,7 @@ then MACHDEP="$ac_md_system$ac_md_release" case $MACHDEP in + aix*) MACHDEP="aix";; linux*) MACHDEP="linux";; cygwin*) MACHDEP="cygwin";; darwin*) MACHDEP="darwin";; @@ -6344,8 +6337,30 @@ $as_echo "no" >&6; } fi -# Check for --with-assertions. Py_DEBUG implies assertions, but also changes -# the ABI. This allows enabling assertions without changing the ABI. +# Check for --with-trace-refs +# --with-trace-refs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-trace-refs" >&5 +$as_echo_n "checking for --with-trace-refs... " >&6; } + +# Check whether --with-trace-refs was given. +if test "${with_trace_refs+set}" = set; then : + withval=$with_trace_refs; +else + with_trace_refs=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_trace_refs" >&5 +$as_echo "$with_trace_refs" >&6; } + +if test "$with_trace_refs" = "yes" +then + +$as_echo "#define Py_TRACE_REFS 1" >>confdefs.h + +fi + +# Check for --with-assertions. +# This allows enabling assertions without Py_DEBUG. assertions='false' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-assertions" >&5 $as_echo_n "checking for --with-assertions... " >&6; } @@ -6824,6 +6839,19 @@ esac # compiler and platform. BASECFLAGS tweaks need to be made even if the # user set OPT. +case $CC in + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi +esac + # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line @@ -6837,19 +6865,6 @@ then WRAP="-fwrapv" fi - case $CC in - *clang*) - cc_is_clang=1 - ;; - *) - if $CC --version 2>&1 | grep -q clang - then - cc_is_clang=1 - else - cc_is_clang= - fi - esac - if test -n "${cc_is_clang}" then # Clang also needs -fwrapv @@ -6890,6 +6905,26 @@ then esac fi +if test -n "${cc_is_clang}" +then + # bpo-36618: Add -fmax-type-align=8 to CFLAGS when clang compiler is + # detected. The pymalloc memory allocator aligns memory on 8 bytes. On + # x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS + # instruction which can lead to segmentation fault. Instruct clang that + # Python is limited to alignemnt on 8 bytes to use MOVUPS instruction + # instead: slower but don't trigger a SIGSEGV if the memory is not aligned + # on 16 bytes. + # + # Sadly, the flag must be added to CFLAGS and not just CFLAGS_NODIST, + # since third party C extensions can have the same issue. + # + # Check if -fmax-type-align flag is supported (it's not supported by old + # clang versions): + if "$CC" -v --help 2>/dev/null |grep -- -fmax-type-align > /dev/null; then + CFLAGS="$CFLAGS -fmax-type-align=8" + fi +fi + @@ -9507,12 +9542,6 @@ then # -u libsys_s pulls in all symbols in libsys Darwin/*) LINKFORSHARED="$extra_undefs -framework CoreFoundation" - - # Issue #18075: the default maximum stack size (8MBytes) is too - # small for the default recursion limit. Increase the stack size - # to ensure that tests don't crash - LINKFORSHARED="-Wl,-stack_size,1000000 $LINKFORSHARED" - if test "$enable_framework" then LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' @@ -11229,7 +11258,6 @@ then $as_echo "#define WITH_PYMALLOC 1" >>confdefs.h - ABIFLAGS="${ABIFLAGS}m" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_pymalloc" >&5 $as_echo "$with_pymalloc" >&6; } @@ -15077,12 +15105,13 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h # * The Python implementation (always 'cpython-' for us) # * The major and minor version numbers # * --with-pydebug (adds a 'd') -# * --with-pymalloc (adds a 'm') -# * --with-wide-unicode (adds a 'u') # # Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, # would get a shared library ABI version tag of 'cpython-32dmu' and shared # libraries would be named 'foo.cpython-32dmu.so'. +# +# In Python 3.2 and older, --with-wide-unicode added a 'u' flag. +# In Python 3.7 and older, --with-pymalloc added a 'm' flag. { $as_echo "$as_me:${as_lineno-$LINENO}: checking ABIFLAGS" >&5 $as_echo_n "checking ABIFLAGS... " >&6; } @@ -15094,6 +15123,18 @@ SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFO { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5 $as_echo "$SOABI" >&6; } +# Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI +if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then + # Similar to SOABI but remove "d" flag from ABIFLAGS + + ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} + +cat >>confdefs.h <<_ACEOF +#define ALT_SOABI "${ALT_SOABI}" +_ACEOF + +fi + case $ac_sys_system in Linux*|GNU*|Darwin|VxWorks) @@ -15108,6 +15149,14 @@ LDVERSION='$(VERSION)$(ABIFLAGS)' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5 $as_echo "$LDVERSION" >&6; } +# On Android the shared libraries must be linked with libpython. + +if test -z "$ANDROID_API_LEVEL"; then + LIBPYTHON='' +else + LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +fi + if test x$PLATFORM_TRIPLET = x; then LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}" @@ -16544,7 +16593,7 @@ do done -SRCDIRS="Parser Objects Python Modules Programs" +SRCDIRS="Parser Objects Python Modules Modules/_io Programs" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5 $as_echo_n "checking for build directories... " >&6; } for dir in $SRCDIRS; do diff --git a/configure.ac b/configure.ac index 73ee71c6d24..a02597da2db 100644 --- a/configure.ac +++ b/configure.ac @@ -404,6 +404,7 @@ then MACHDEP="$ac_md_system$ac_md_release" case $MACHDEP in + aix*) MACHDEP="aix";; linux*) MACHDEP="linux";; cygwin*) MACHDEP="cygwin";; darwin*) MACHDEP="darwin";; @@ -1227,8 +1228,21 @@ else AC_MSG_RESULT(no); Py_DEBUG='false' fi], [AC_MSG_RESULT(no)]) -# Check for --with-assertions. Py_DEBUG implies assertions, but also changes -# the ABI. This allows enabling assertions without changing the ABI. +# Check for --with-trace-refs +# --with-trace-refs +AC_MSG_CHECKING(for --with-trace-refs) +AC_ARG_WITH(trace-refs, + AS_HELP_STRING([--with-trace-refs],[enable tracing references for debugging purpose]),, + with_trace_refs=no) +AC_MSG_RESULT($with_trace_refs) + +if test "$with_trace_refs" = "yes" +then + AC_DEFINE(Py_TRACE_REFS, 1, [Define if you want to enable tracing references for debugging purpose]) +fi + +# Check for --with-assertions. +# This allows enabling assertions without Py_DEBUG. assertions='false' AC_MSG_CHECKING(for --with-assertions) AC_ARG_WITH(assertions, @@ -1463,6 +1477,19 @@ esac # compiler and platform. BASECFLAGS tweaks need to be made even if the # user set OPT. +case $CC in + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi +esac + # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line AC_SUBST(OPT) @@ -1476,19 +1503,6 @@ then WRAP="-fwrapv" fi - case $CC in - *clang*) - cc_is_clang=1 - ;; - *) - if $CC --version 2>&1 | grep -q clang - then - cc_is_clang=1 - else - cc_is_clang= - fi - esac - if test -n "${cc_is_clang}" then # Clang also needs -fwrapv @@ -1529,6 +1543,26 @@ then esac fi +if test -n "${cc_is_clang}" +then + # bpo-36618: Add -fmax-type-align=8 to CFLAGS when clang compiler is + # detected. The pymalloc memory allocator aligns memory on 8 bytes. On + # x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS + # instruction which can lead to segmentation fault. Instruct clang that + # Python is limited to alignemnt on 8 bytes to use MOVUPS instruction + # instead: slower but don't trigger a SIGSEGV if the memory is not aligned + # on 16 bytes. + # + # Sadly, the flag must be added to CFLAGS and not just CFLAGS_NODIST, + # since third party C extensions can have the same issue. + # + # Check if -fmax-type-align flag is supported (it's not supported by old + # clang versions): + if "$CC" -v --help 2>/dev/null |grep -- -fmax-type-align > /dev/null; then + CFLAGS="$CFLAGS -fmax-type-align=8" + fi +fi + AC_SUBST(BASECFLAGS) AC_SUBST(CFLAGS_NODIST) AC_SUBST(LDFLAGS_NODIST) @@ -2667,12 +2701,6 @@ then # -u libsys_s pulls in all symbols in libsys Darwin/*) LINKFORSHARED="$extra_undefs -framework CoreFoundation" - - # Issue #18075: the default maximum stack size (8MBytes) is too - # small for the default recursion limit. Increase the stack size - # to ensure that tests don't crash - LINKFORSHARED="-Wl,-stack_size,1000000 $LINKFORSHARED" - if test "$enable_framework" then LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' @@ -2706,7 +2734,7 @@ then # when running test_compile.py. LINKFORSHARED='-Wl,-E -N 2048K';; VxWorks*) - LINKFORSHARED='--export-dynamic';; + LINKFORSHARED='--export-dynamic';; esac fi AC_MSG_RESULT($LINKFORSHARED) @@ -3379,7 +3407,6 @@ if test "$with_pymalloc" != "no" then AC_DEFINE(WITH_PYMALLOC, 1, [Define if you want to compile in Python-specific mallocs]) - ABIFLAGS="${ABIFLAGS}m" fi AC_MSG_RESULT($with_pymalloc) @@ -4580,12 +4607,13 @@ AC_C_BIGENDIAN # * The Python implementation (always 'cpython-' for us) # * The major and minor version numbers # * --with-pydebug (adds a 'd') -# * --with-pymalloc (adds a 'm') -# * --with-wide-unicode (adds a 'u') # # Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, # would get a shared library ABI version tag of 'cpython-32dmu' and shared # libraries would be named 'foo.cpython-32dmu.so'. +# +# In Python 3.2 and older, --with-wide-unicode added a 'u' flag. +# In Python 3.7 and older, --with-pymalloc added a 'm' flag. AC_SUBST(SOABI) AC_MSG_CHECKING(ABIFLAGS) AC_MSG_RESULT($ABIFLAGS) @@ -4593,6 +4621,15 @@ AC_MSG_CHECKING(SOABI) SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} AC_MSG_RESULT($SOABI) +# Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI +if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then + # Similar to SOABI but remove "d" flag from ABIFLAGS + AC_SUBST(ALT_SOABI) + ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} + AC_DEFINE_UNQUOTED(ALT_SOABI, "${ALT_SOABI}", + [Alternative SOABI used in debug build to load C extensions built in release mode]) +fi + AC_SUBST(EXT_SUFFIX) case $ac_sys_system in Linux*|GNU*|Darwin|VxWorks) @@ -4605,6 +4642,14 @@ AC_MSG_CHECKING(LDVERSION) LDVERSION='$(VERSION)$(ABIFLAGS)' AC_MSG_RESULT($LDVERSION) +# On Android the shared libraries must be linked with libpython. +AC_SUBST(LIBPYTHON) +if test -z "$ANDROID_API_LEVEL"; then + LIBPYTHON='' +else + LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +fi + dnl define LIBPL after ABIFLAGS and LDVERSION is defined. AC_SUBST(PY_ENABLE_SHARED) if test x$PLATFORM_TRIPLET = x; then @@ -5245,7 +5290,7 @@ do done AC_SUBST(SRCDIRS) -SRCDIRS="Parser Objects Python Modules Programs" +SRCDIRS="Parser Objects Python Modules Modules/_io Programs" AC_MSG_CHECKING(for build directories) for dir in $SRCDIRS; do if test ! -d $dir; then diff --git a/pyconfig.h.in b/pyconfig.h.in index d41d5793276..4b779614727 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -12,6 +12,10 @@ support for AIX C++ shared extension modules. */ #undef AIX_GENUINE_CPLUSPLUS +/* Alternative SOABI used in debug build to load C extensions built in release + mode */ +#undef ALT_SOABI + /* The Android API level. */ #undef ANDROID_API_LEVEL @@ -1374,6 +1378,9 @@ externally defined: 0 */ #undef Py_HASH_ALGORITHM +/* Define if you want to enable tracing references for debugging purpose */ +#undef Py_TRACE_REFS + /* assume C89 semantics that RETSIGTYPE is always void */ #undef RETSIGTYPE diff --git a/setup.py b/setup.py index c278f08b8e6..96a49b4e353 100644 --- a/setup.py +++ b/setup.py @@ -725,13 +725,13 @@ def detect_simple_extensions(self): # heapq self.add(Extension("_heapq", ["_heapqmodule.c"])) # C-optimized pickle replacement - self.add(Extension("_pickle", ["_pickle.c"])) + self.add(Extension("_pickle", ["_pickle.c"], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) # atexit self.add(Extension("atexit", ["atexitmodule.c"])) # _json speedups self.add(Extension("_json", ["_json.c"], - # pycore_accu.h requires Py_BUILD_CORE_BUILTIN - extra_compile_args=['-DPy_BUILD_CORE_BUILTIN'])) + extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) # profiler (_lsprof is for cProfile.py) self.add(Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c'])) @@ -814,6 +814,10 @@ def detect_test_extensions(self): self.add(Extension('_testcapi', ['_testcapimodule.c'], depends=['testcapi_long.h'])) + # Python Internal C API test module + self.add(Extension('_testinternalcapi', ['_testinternalcapi.c'], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) + # Python PEP-3118 (buffer protocol) test module self.add(Extension('_testbuffer', ['_testbuffer.c'])) @@ -973,17 +977,18 @@ def detect_readline_curses(self): def detect_crypt(self): # crypt module. + if VXWORKS: + # bpo-31904: crypt() function is not provided by VxWorks. + # DES_crypt() OpenSSL provides is too weak to implement + # the encryption. + return + if self.compiler.find_library_file(self.lib_dirs, 'crypt'): libs = ['crypt'] else: libs = [] - if not VXWORKS: - self.add(Extension('_crypt', ['_cryptmodule.c'], - libraries=libs)) - elif self.compiler.find_library_file(self.lib_dirs, 'OPENSSL'): - libs = ['OPENSSL'] - self.add(Extension('_crypt', ['_cryptmodule.c'], + self.add(Extension('_crypt', ['_cryptmodule.c'], libraries=libs)) def detect_socket(self): @@ -1294,7 +1299,7 @@ def detect_sqlite(self): sqlite_setup_debug = False # verbose debug prints from this script? # We hunt for #define SQLITE_VERSION "n.n.n" - # We need to find >= sqlite version 3.0.8 + # We need to find >= sqlite version 3.3.9, for sqlite3_prepare_v2 sqlite_incdir = sqlite_libdir = None sqlite_inc_paths = [ '/usr/include', '/usr/include/sqlite', @@ -1305,7 +1310,7 @@ def detect_sqlite(self): ] if CROSS_COMPILING: sqlite_inc_paths = [] - MIN_SQLITE_VERSION_NUMBER = (3, 0, 8) + MIN_SQLITE_VERSION_NUMBER = (3, 3, 9) MIN_SQLITE_VERSION = ".".join([str(x) for x in MIN_SQLITE_VERSION_NUMBER]) @@ -1339,7 +1344,7 @@ def detect_sqlite(self): break else: if sqlite_setup_debug: - print("%s: version %d is too old, need >= %s"%(d, + print("%s: version %s is too old, need >= %s"%(d, sqlite_version, MIN_SQLITE_VERSION)) elif sqlite_setup_debug: print("sqlite: %s had no SQLITE_VERSION"%(f,)) @@ -1642,6 +1647,7 @@ def detect_modules(self): self.detect_crypt() self.detect_socket() self.detect_openssl_hashlib() + self.detect_hash_builtins() self.detect_dbm_gdbm() self.detect_sqlite() self.detect_platform_specific_exts() @@ -1882,9 +1888,6 @@ def detect_tkinter(self): libs.append('tk'+ version) libs.append('tcl'+ version) - if HOST_PLATFORM in ['aix3', 'aix4']: - libs.append('ld') - # Finally, link with the X11 libraries (not appropriate on cygwin) if not CYGWIN: libs.append('X11') @@ -2155,6 +2158,7 @@ def split_var(name, sep): openssl_libs = split_var('OPENSSL_LIBS', '-l') if not openssl_libs: # libssl and libcrypto not found + self.missing.extend(['_ssl', '_hashlib']) return None, None # Find OpenSSL includes @@ -2162,6 +2166,7 @@ def split_var(name, sep): 'openssl/ssl.h', self.inc_dirs, openssl_includes ) if ssl_incs is None: + self.missing.extend(['_ssl', '_hashlib']) return None, None # OpenSSL 1.0.2 uses Kerberos for KRB5 ciphers @@ -2187,6 +2192,7 @@ def split_var(name, sep): library_dirs=openssl_libdirs, libraries=openssl_libs)) + def detect_hash_builtins(self): # We always compile these even when OpenSSL is available (issue #14693). # It's harmless and the object code is tiny (40-50 KiB per module, # only loaded when actually used).