diff --git a/.gitattributes b/.gitattributes index 3827d09709d4a7..c66e765266382f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -47,7 +47,7 @@ PC/clinic/*.h linguist-generated=true Python/clinic/*.h linguist-generated=true Python/importlib.h linguist-generated=true Python/importlib_external.h linguist-generated=true -Include/Python-ast.h linguist-generated=true +Include/internal/pycore_ast.h linguist-generated=true Python/Python-ast.c linguist-generated=true Include/opcode.h linguist-generated=true Python/opcode_targets.h linguist-generated=true diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 00000000000000..1a03a7b6c4911d --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,31 @@ +# This workflow will upload a Python Package using Twine when a release is created +# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries + +name: Upload Python Package + +on: + release: + types: [created] + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index 5706777c41db48..63290e0a7f0bf7 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -12,6 +12,12 @@ There are two functions specifically for working with iterators. Return non-zero if the object *o* supports the iterator protocol, and ``0`` otherwise. This function always succeeds. +.. c:function:: int PyAiter_Check(PyObject *o) + + Returns non-zero if the object 'obj' provides :class:`AsyncIterator` + protocols, and ``0`` otherwise. This function always succeeds. + + .. versionadded:: 3.10 .. c:function:: PyObject* PyIter_Next(PyObject *o) diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 1100af1df2928c..42e3340acb79a0 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -356,3 +356,14 @@ Object Protocol iterator for the object argument, or the object itself if the object is already an iterator. Raises :exc:`TypeError` and returns ``NULL`` if the object cannot be iterated. + + +.. c:function:: PyObject* PyObject_GetAiter(PyObject *o) + + This is the equivalent to the Python expression ``aiter(o)``. Takes an + :class:`AsyncIterable` object and returns an :class:`AsyncIterator` for it. + This is typically a new iterator but if the argument is an + :class:`AsyncIterator`, this returns itself. Raises :exc:`TypeError` and + returns ``NULL`` if the object cannot be iterated. + + .. versionadded:: 3.10 diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 8a6ee718a012dd..505f1203dd1bdd 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -1073,6 +1073,9 @@ PyInterpreterState_New:PyInterpreterState*::: PyIter_Check:int::: PyIter_Check:PyObject*:o:0: +PyAiter_Check:int::: +PyAiter_Check:PyObject*:o:0: + PyIter_Next:PyObject*::+1: PyIter_Next:PyObject*:o:0: @@ -1679,6 +1682,9 @@ PyObject_GetItem:PyObject*:key:0: PyObject_GetIter:PyObject*::+1: PyObject_GetIter:PyObject*:o:0: +PyObject_GetAiter:PyObject*::+1: +PyObject_GetAiter:PyObject*:o:0: + PyObject_HasAttr:int::: PyObject_HasAttr:PyObject*:o:0: PyObject_HasAttr:PyObject*:attr_name:0: diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 67d01da3253073..3adee103bce2d8 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -1,5 +1,6 @@ # File generated by 'make regen-limited-abi' # This is NOT an authoritative list of stable ABI symbols +PyAiter_Check PyArg_Parse PyArg_ParseTuple PyArg_ParseTupleAndKeywords @@ -465,6 +466,7 @@ PyObject_GenericGetAttr PyObject_GenericGetDict PyObject_GenericSetAttr PyObject_GenericSetDict +PyObject_GetAiter PyObject_GetAttr PyObject_GetAttrString PyObject_GetItem diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 2a6af95cdf9efa..5cb1df93702d68 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -12,31 +12,31 @@ are always available. They are listed here in alphabetical order. +=========================+=======================+=======================+=========================+ | | **A** | | **E** | | **L** | | **R** | | | :func:`abs` | | :func:`enumerate` | | :func:`len` | | |func-range|_ | -| | :func:`all` | | :func:`eval` | | |func-list|_ | | :func:`repr` | -| | :func:`any` | | :func:`exec` | | :func:`locals` | | :func:`reversed` | -| | :func:`ascii` | | | | | | :func:`round` | -| | | | **F** | | **M** | | | -| | **B** | | :func:`filter` | | :func:`map` | | **S** | -| | :func:`bin` | | :func:`float` | | :func:`max` | | |func-set|_ | -| | :func:`bool` | | :func:`format` | | |func-memoryview|_ | | :func:`setattr` | -| | :func:`breakpoint` | | |func-frozenset|_ | | :func:`min` | | :func:`slice` | -| | |func-bytearray|_ | | | | | | :func:`sorted` | -| | |func-bytes|_ | | **G** | | **N** | | :func:`staticmethod` | -| | | | :func:`getattr` | | :func:`next` | | |func-str|_ | -| | **C** | | :func:`globals` | | | | :func:`sum` | -| | :func:`callable` | | | | **O** | | :func:`super` | -| | :func:`chr` | | **H** | | :func:`object` | | | -| | :func:`classmethod` | | :func:`hasattr` | | :func:`oct` | | **T** | -| | :func:`compile` | | :func:`hash` | | :func:`open` | | |func-tuple|_ | -| | :func:`complex` | | :func:`help` | | :func:`ord` | | :func:`type` | -| | | | :func:`hex` | | | | | -| | **D** | | | | **P** | | **V** | -| | :func:`delattr` | | **I** | | :func:`pow` | | :func:`vars` | -| | |func-dict|_ | | :func:`id` | | :func:`print` | | | -| | :func:`dir` | | :func:`input` | | :func:`property` | | **Z** | -| | :func:`divmod` | | :func:`int` | | | | :func:`zip` | -| | | | :func:`isinstance` | | | | | -| | | | :func:`issubclass` | | | | **_** | +| | :func:`aiter` | | :func:`eval` | | |func-list|_ | | :func:`repr` | +| | :func:`all` | | :func:`exec` | | :func:`locals` | | :func:`reversed` | +| | :func:`any` | | | | | | :func:`round` | +| | :func:`anext` | | **F** | | **M** | | | +| | :func:`ascii` | | :func:`filter` | | :func:`map` | | **S** | +| | | | :func:`float` | | :func:`max` | | |func-set|_ | +| | **B** | | :func:`format` | | |func-memoryview|_ | | :func:`setattr` | +| | :func:`bin` | | |func-frozenset|_ | | :func:`min` | | :func:`slice` | +| | :func:`bool` | | | | | | :func:`sorted` | +| | :func:`breakpoint` | | **G** | | **N** | | :func:`staticmethod` | +| | |func-bytearray|_ | | :func:`getattr` | | :func:`next` | | |func-str|_ | +| | |func-bytes|_ | | :func:`globals` | | | | :func:`sum` | +| | | | | | **O** | | :func:`super` | +| | **C** | | **H** | | :func:`object` | | | +| | :func:`callable` | | :func:`hasattr` | | :func:`oct` | | **T** | +| | :func:`chr` | | :func:`hash` | | :func:`open` | | |func-tuple|_ | +| | :func:`classmethod` | | :func:`help` | | :func:`ord` | | :func:`type` | +| | :func:`compile` | | :func:`hex` | | | | | +| | :func:`complex` | | | | **P** | | **V** | +| | | | **I** | | :func:`pow` | | :func:`vars` | +| | **D** | | :func:`id` | | :func:`print` | | | +| | :func:`delattr` | | :func:`input` | | :func:`property` | | **Z** | +| | |func-dict|_ | | :func:`int` | | | | :func:`zip` | +| | :func:`dir` | | :func:`isinstance` | | | | | +| | :func:`divmod` | | :func:`issubclass` | | | | **_** | | | | | :func:`iter` | | | | :func:`__import__` | +-------------------------+-----------------------+-----------------------+-------------------------+ @@ -61,6 +61,18 @@ are always available. They are listed here in alphabetical order. If the argument is a complex number, its magnitude is returned. +.. function:: aiter(async_iterable) + + Return an :term:`asynchronous iterator` for an :term:`asynchronous iterable`. + Equivalent to calling ``x.__aiter__()``. + + ``aiter(x)`` itself has an ``__aiter__()`` method that returns ``x``, + so ``aiter(aiter(x))`` is the same as ``aiter(x)``. + + Note: Unlike :func:`iter`, :func:`aiter` has no 2-argument variant. + + .. versionadded:: 3.10 + .. function:: all(iterable) Return ``True`` if all elements of the *iterable* are true (or if the iterable @@ -73,6 +85,21 @@ are always available. They are listed here in alphabetical order. return True +.. awaitablefunction:: anext(async_iterator[, default]) + + When awaited, return the next item from the given :term:`asynchronous + iterator`, or *default* if given and the iterator is exhausted. + + This is the async variant of the :func:`next` builtin, and behaves + similarly. + + This calls the :meth:`~object.__anext__` method of *async_iterator*, + returning an :term:`awaitable`. Awaiting this returns the next value of the + iterator. If *default* is given, it is returned if the iterator is exhausted, + otherwise :exc:`StopAsyncIteration` is raised. + + .. versionadded:: 3.10 + .. function:: any(iterable) Return ``True`` if any element of the *iterable* is true. If the iterable diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index fee5df84dffcb2..d9b790e4e777de 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -208,7 +208,7 @@ Functions .. versionadded:: 3.4 .. versionchanged:: 3.7 :exc:`ModuleNotFoundError` is raised when the module being reloaded lacks - a :class:`ModuleSpec`. + a :class:`~importlib.machinery.ModuleSpec`. :mod:`importlib.abc` -- Abstract base classes related to import @@ -1591,9 +1591,9 @@ an :term:`importer`. .. function:: spec_from_loader(name, loader, *, origin=None, is_package=None) - A factory function for creating a :class:`ModuleSpec` instance based - on a loader. The parameters have the same meaning as they do for - ModuleSpec. The function uses available :term:`loader` APIs, such as + A factory function for creating a :class:`~importlib.machinery.ModuleSpec` + instance based on a loader. The parameters have the same meaning as they do + for ModuleSpec. The function uses available :term:`loader` APIs, such as :meth:`InspectLoader.is_package`, to fill in any missing information on the spec. @@ -1601,9 +1601,9 @@ an :term:`importer`. .. function:: spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None) - A factory function for creating a :class:`ModuleSpec` instance based - on the path to a file. Missing information will be filled in on the - spec by making use of loader APIs and by the implication that the + A factory function for creating a :class:`~importlib.machinery.ModuleSpec` + instance based on the path to a file. Missing information will be filled in + on the spec by making use of loader APIs and by the implication that the module will be file-based. .. versionadded:: 3.4 diff --git a/Doc/library/io.rst b/Doc/library/io.rst index aecbec56866d73..96e02e839ae653 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -155,16 +155,6 @@ High-level Module Interface when an unsupported operation is called on a stream. -In-memory streams -^^^^^^^^^^^^^^^^^ - -It is also possible to use a :class:`str` or :term:`bytes-like object` as a -file for both reading and writing. For strings :class:`StringIO` can be used -like a file opened in text mode. :class:`BytesIO` can be used like a file -opened in binary mode. Both provide full read-write capabilities with random -access. - - .. seealso:: :mod:`sys` diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 16256c549208fc..b3b6ed56a5e17e 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -36,7 +36,7 @@ The :mod:`pprint` module defines one class: .. index:: single: ...; placeholder .. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \ - compact=False, sort_dicts=True) + compact=False, sort_dicts=True, underscore_numbers=False) Construct a :class:`PrettyPrinter` instance. This constructor understands several keyword parameters. An output stream may be set using the *stream* @@ -55,7 +55,10 @@ The :mod:`pprint` module defines one class: will be formatted on a separate line. If *compact* is true, as many items as will fit within the *width* will be formatted on each output line. If *sort_dicts* is true (the default), dictionaries will be formatted with their - keys sorted, otherwise they will display in insertion order. + keys sorted, otherwise they will display in insertion order. If + *underscore_numbers* is true, integers will be formatted with + ```_``` character for a thousands separator, otherwise underscores are not + displayed (the default). .. versionchanged:: 3.4 Added the *compact* parameter. @@ -63,6 +66,8 @@ The :mod:`pprint` module defines one class: .. versionchanged:: 3.8 Added the *sort_dicts* parameter. + .. versionchanged:: 3.10 + Added the *underscore_numbers* parameter. >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] @@ -91,10 +96,10 @@ The :mod:`pprint` module defines one class: The :mod:`pprint` module also provides several shortcut functions: .. function:: pformat(object, indent=1, width=80, depth=None, *, \ - compact=False, sort_dicts=True) + compact=False, sort_dicts=True, underscore_numbers=False) Return the formatted representation of *object* as a string. *indent*, - *width*, *depth*, *compact* and *sort_dicts* will be passed to the + *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* will be passed to the :class:`PrettyPrinter` constructor as formatting parameters. .. versionchanged:: 3.4 @@ -103,6 +108,9 @@ The :mod:`pprint` module also provides several shortcut functions: .. versionchanged:: 3.8 Added the *sort_dicts* parameter. + .. versionchanged:: 3.10 + Added the *underscore_numbers* parameter. + .. function:: pp(object, *args, sort_dicts=False, **kwargs) @@ -116,13 +124,13 @@ The :mod:`pprint` module also provides several shortcut functions: .. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \ - compact=False, sort_dicts=True) + compact=False, sort_dicts=True, underscore_numbers=False) Prints the formatted representation of *object* on *stream*, followed by a newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used in the interactive interpreter instead of the :func:`print` function for inspecting values (you can even reassign ``print = pprint.pprint`` for use - within a scope). *indent*, *width*, *depth*, *compact* and *sort_dicts* will + within a scope). *indent*, *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* will be passed to the :class:`PrettyPrinter` constructor as formatting parameters. .. versionchanged:: 3.4 @@ -131,6 +139,9 @@ The :mod:`pprint` module also provides several shortcut functions: .. versionchanged:: 3.8 Added the *sort_dicts* parameter. + .. versionchanged:: 3.10 + Added the *underscore_numbers* parameter. + >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> stuff.insert(0, stuff) diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 8e05f8408e545d..956b9e8f959c65 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -223,7 +223,7 @@ Standard names are defined for the following types: .. class:: ModuleType(name, doc=None) - The type of :term:`modules `. Constructor takes the name of the + The type of :term:`modules `. The constructor takes the name of the module to be created and optionally its :term:`docstring`. .. note:: @@ -238,12 +238,23 @@ Standard names are defined for the following types: The :term:`loader` which loaded the module. Defaults to ``None``. + This attribute is to match :attr:`importlib.machinery.ModuleSpec.loader` + as stored in the attr:`__spec__` object. + + .. note:: + A future version of Python may stop setting this attribute by default. + To guard against this potential change, preferrably read from the + :attr:`__spec__` attribute instead or use + ``getattr(module, "__loader__", None)`` if you explicitly need to use + this attribute. + .. versionchanged:: 3.4 Defaults to ``None``. Previously the attribute was optional. .. attribute:: __name__ - The name of the module. + The name of the module. Expected to match + :attr:`importlib.machinery.ModuleSpec.name`. .. attribute:: __package__ @@ -252,9 +263,26 @@ Standard names are defined for the following types: to ``''``, else it should be set to the name of the package (which can be :attr:`__name__` if the module is a package itself). Defaults to ``None``. + This attribute is to match :attr:`importlib.machinery.ModuleSpec.parent` + as stored in the attr:`__spec__` object. + + .. note:: + A future version of Python may stop setting this attribute by default. + To guard against this potential change, preferrably read from the + :attr:`__spec__` attribute instead or use + ``getattr(module, "__package__", None)`` if you explicitly need to use + this attribute. + .. versionchanged:: 3.4 Defaults to ``None``. Previously the attribute was optional. + .. attribute:: __spec__ + + A record of the the module's import-system-related state. Expected to be + an instance of :class:`importlib.machinery.ModuleSpec`. + + .. versionadded:: 3.4 + .. data:: EllipsisType diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index b5e425293962c5..b6791800fb6c82 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -588,6 +588,11 @@ Other Language Changes ``__globals__["__builtins__"]`` if it exists, else from the current builtins. (Contributed by Mark Shannon in :issue:`42990`.) +* Two new builtin functions -- :func:`aiter` and :func:`anext` have been added + to provide asynchronous counterparts to :func:`iter` and :func:`next`, + respectively. + (Contributed by Joshua Bronson, Daniel Pope, and Justin Wang in :issue:`31861`.) + New Modules =========== @@ -922,9 +927,10 @@ Optimizations (Contributed by Serhiy Storchaka in :issue:`41334`.) * The :mod:`runpy` module now imports fewer modules. - The ``python3 -m module-name`` command startup time is 1.3x faster in - average. - (Contributed by Victor Stinner in :issue:`41006`.) + The ``python3 -m module-name`` command startup time is 1.4x faster in + average. On Linux, ``python3 -I -m module-name`` imports 69 modules on Python + 3.9, whereas it only imports 51 modules (-18) on Python 3.10. + (Contributed by Victor Stinner in :issue:`41006` and :issue:`41718`.) * The ``LOAD_ATTR`` instruction now uses new "per opcode cache" mechanism. It is about 36% faster now for regular attributes and 44% faster for slots. @@ -940,7 +946,6 @@ Optimizations for more details. (Contributed by Victor Stinner and Pablo Galindo in :issue:`38980`.) - * Function parameters and their annotations are no longer computed at runtime, but rather at compilation time. They are stored as a tuple of strings at the bytecode level. It is now around 2 times faster to create a function with @@ -952,6 +957,10 @@ Optimizations algorithm to avoid quadratic behavior on long strings. (Contributed by Dennis Sweeney in :issue:`41972`) +* Added micro-optimizations to ``_PyType_Lookup()`` to improve type attribute cache lookup + performance in the common case of cache hits. This makes the interpreter 1.04 times faster + in average (Contributed by Dino Viehland in :issue:`43452`) + Deprecated ========== @@ -995,6 +1004,12 @@ Deprecated :meth:`~importlib.abc.Loader.exec_module` is preferred. (Contributed by Brett Cannon in :issue:`26131`.) +* The import system now uses the ``__spec__`` attribute on modules before + falling back on :meth:`~importlib.abc.Loader.module_repr` for a module's + ``__repr__()`` method. Removal of the use of ``module_repr()`` is scheduled + for Python 3.12. + (Contributed by Brett Cannon in :issue:`42137`.) + * ``sqlite3.OptimizedUnicode`` has been undocumented and obsolete since Python 3.3, when it was made an alias to :class:`str`. It is now deprecated, scheduled for removal in Python 3.12. @@ -1383,5 +1398,41 @@ Removed it could not be used, because the ``symtable.h`` header file was excluded from the limited C API. - The Python :mod:`symtable` module remains available and is unchanged. + Use Python :mod:`symtable` module instead. + (Contributed by Victor Stinner in :issue:`43244`.) + +* Remove ``ast.h``, ``asdl.h``, and ``Python-ast.h`` header files. + These functions were undocumented and excluded from the limited C API. + Most names defined by these header files were not prefixed by ``Py`` and so + could create names conflicts. For example, ``Python-ast.h`` defined a + ``Yield`` macro which was conflict with the ``Yield`` name used by the + Windows ```` header. Use the Python :mod:`ast` module instead. + (Contributed by Victor Stinner in :issue:`43244`.) + +* Remove the compiler and parser functions using ``struct _mod`` type, because + the public AST C API was removed: + + * ``PyAST_Compile()`` + * ``PyAST_CompileEx()`` + * ``PyAST_CompileObject()`` + * ``PyFuture_FromAST()`` + * ``PyFuture_FromASTObject()`` + * ``PyParser_ASTFromFile()`` + * ``PyParser_ASTFromFileObject()`` + * ``PyParser_ASTFromFilename()`` + * ``PyParser_ASTFromString()`` + * ``PyParser_ASTFromStringObject()`` + + These functions were undocumented and excluded from the limited C API. + (Contributed by Victor Stinner in :issue:`43244`.) + +* Remove the ``pyarena.h`` header file with functions: + + * ``PyArena_New()`` + * ``PyArena_Free()`` + * ``PyArena_Malloc()`` + * ``PyArena_AddPyObject()`` + + These functions were undocumented, excluded from the limited C API, and were + only used internally by the compiler. (Contributed by Victor Stinner in :issue:`43244`.) diff --git a/Grammar/python.gram b/Grammar/python.gram index 7247962d3b9717..4f3b649f9d57ee 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -842,6 +842,8 @@ invalid_for_target: invalid_group: | '(' a=starred_expression ')' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "can't use starred expression here") } + | '(' a='**' expression ')' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "can't use double starred expression here") } invalid_import_from_targets: | import_from_as_names ',' { RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") } diff --git a/Include/Python-ast.h b/Include/Python-ast.h deleted file mode 100644 index bd127ca2ab0cad..00000000000000 --- a/Include/Python-ast.h +++ /dev/null @@ -1,828 +0,0 @@ -// File automatically generated by Parser/asdl_c.py. - -#ifndef Py_PYTHON_AST_H -#define Py_PYTHON_AST_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_LIMITED_API -#include "asdl.h" - -#undef Yield /* undefine macro conflicting with */ - -typedef struct _mod *mod_ty; - -typedef struct _stmt *stmt_ty; - -typedef struct _expr *expr_ty; - -typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty; - -typedef enum _boolop { And=1, Or=2 } boolop_ty; - -typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, - LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, - FloorDiv=13 } operator_ty; - -typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; - -typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, - In=9, NotIn=10 } cmpop_ty; - -typedef struct _comprehension *comprehension_ty; - -typedef struct _excepthandler *excepthandler_ty; - -typedef struct _arguments *arguments_ty; - -typedef struct _arg *arg_ty; - -typedef struct _keyword *keyword_ty; - -typedef struct _alias *alias_ty; - -typedef struct _withitem *withitem_ty; - -typedef struct _match_case *match_case_ty; - -typedef struct _type_ignore *type_ignore_ty; - - -typedef struct { - _ASDL_SEQ_HEAD - mod_ty typed_elements[1]; -} asdl_mod_seq; - -asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - stmt_ty typed_elements[1]; -} asdl_stmt_seq; - -asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - expr_ty typed_elements[1]; -} asdl_expr_seq; - -asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - comprehension_ty typed_elements[1]; -} asdl_comprehension_seq; - -asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena - *arena); - -typedef struct { - _ASDL_SEQ_HEAD - excepthandler_ty typed_elements[1]; -} asdl_excepthandler_seq; - -asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena - *arena); - -typedef struct { - _ASDL_SEQ_HEAD - arguments_ty typed_elements[1]; -} asdl_arguments_seq; - -asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - arg_ty typed_elements[1]; -} asdl_arg_seq; - -asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - keyword_ty typed_elements[1]; -} asdl_keyword_seq; - -asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - alias_ty typed_elements[1]; -} asdl_alias_seq; - -asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - withitem_ty typed_elements[1]; -} asdl_withitem_seq; - -asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - match_case_ty typed_elements[1]; -} asdl_match_case_seq; - -asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena - *arena); - -typedef struct { - _ASDL_SEQ_HEAD - type_ignore_ty typed_elements[1]; -} asdl_type_ignore_seq; - -asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena - *arena); - - -enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, - FunctionType_kind=4}; -struct _mod { - enum _mod_kind kind; - union { - struct { - asdl_stmt_seq *body; - asdl_type_ignore_seq *type_ignores; - } Module; - - struct { - asdl_stmt_seq *body; - } Interactive; - - struct { - expr_ty body; - } Expression; - - struct { - asdl_expr_seq *argtypes; - expr_ty returns; - } FunctionType; - - } v; -}; - -enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, - Return_kind=4, Delete_kind=5, Assign_kind=6, - AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, - AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, - AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17, - Assert_kind=18, Import_kind=19, ImportFrom_kind=20, - Global_kind=21, Nonlocal_kind=22, Expr_kind=23, Pass_kind=24, - Break_kind=25, Continue_kind=26}; -struct _stmt { - enum _stmt_kind kind; - union { - struct { - identifier name; - arguments_ty args; - asdl_stmt_seq *body; - asdl_expr_seq *decorator_list; - expr_ty returns; - string type_comment; - } FunctionDef; - - struct { - identifier name; - arguments_ty args; - asdl_stmt_seq *body; - asdl_expr_seq *decorator_list; - expr_ty returns; - string type_comment; - } AsyncFunctionDef; - - struct { - identifier name; - asdl_expr_seq *bases; - asdl_keyword_seq *keywords; - asdl_stmt_seq *body; - asdl_expr_seq *decorator_list; - } ClassDef; - - struct { - expr_ty value; - } Return; - - struct { - asdl_expr_seq *targets; - } Delete; - - struct { - asdl_expr_seq *targets; - expr_ty value; - string type_comment; - } Assign; - - struct { - expr_ty target; - operator_ty op; - expr_ty value; - } AugAssign; - - struct { - expr_ty target; - expr_ty annotation; - expr_ty value; - int simple; - } AnnAssign; - - struct { - expr_ty target; - expr_ty iter; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - string type_comment; - } For; - - struct { - expr_ty target; - expr_ty iter; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - string type_comment; - } AsyncFor; - - struct { - expr_ty test; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - } While; - - struct { - expr_ty test; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - } If; - - struct { - asdl_withitem_seq *items; - asdl_stmt_seq *body; - string type_comment; - } With; - - struct { - asdl_withitem_seq *items; - asdl_stmt_seq *body; - string type_comment; - } AsyncWith; - - struct { - expr_ty subject; - asdl_match_case_seq *cases; - } Match; - - struct { - expr_ty exc; - expr_ty cause; - } Raise; - - struct { - asdl_stmt_seq *body; - asdl_excepthandler_seq *handlers; - asdl_stmt_seq *orelse; - asdl_stmt_seq *finalbody; - } Try; - - struct { - expr_ty test; - expr_ty msg; - } Assert; - - struct { - asdl_alias_seq *names; - } Import; - - struct { - identifier module; - asdl_alias_seq *names; - int level; - } ImportFrom; - - struct { - asdl_identifier_seq *names; - } Global; - - struct { - asdl_identifier_seq *names; - } Nonlocal; - - struct { - expr_ty value; - } Expr; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, - Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8, - ListComp_kind=9, SetComp_kind=10, DictComp_kind=11, - GeneratorExp_kind=12, Await_kind=13, Yield_kind=14, - YieldFrom_kind=15, Compare_kind=16, Call_kind=17, - FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, - Attribute_kind=21, Subscript_kind=22, Starred_kind=23, - Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27, - MatchAs_kind=28, MatchOr_kind=29}; -struct _expr { - enum _expr_kind kind; - union { - struct { - boolop_ty op; - asdl_expr_seq *values; - } BoolOp; - - struct { - expr_ty target; - expr_ty value; - } NamedExpr; - - struct { - expr_ty left; - operator_ty op; - expr_ty right; - } BinOp; - - struct { - unaryop_ty op; - expr_ty operand; - } UnaryOp; - - struct { - arguments_ty args; - expr_ty body; - } Lambda; - - struct { - expr_ty test; - expr_ty body; - expr_ty orelse; - } IfExp; - - struct { - asdl_expr_seq *keys; - asdl_expr_seq *values; - } Dict; - - struct { - asdl_expr_seq *elts; - } Set; - - struct { - expr_ty elt; - asdl_comprehension_seq *generators; - } ListComp; - - struct { - expr_ty elt; - asdl_comprehension_seq *generators; - } SetComp; - - struct { - expr_ty key; - expr_ty value; - asdl_comprehension_seq *generators; - } DictComp; - - struct { - expr_ty elt; - asdl_comprehension_seq *generators; - } GeneratorExp; - - struct { - expr_ty value; - } Await; - - struct { - expr_ty value; - } Yield; - - struct { - expr_ty value; - } YieldFrom; - - struct { - expr_ty left; - asdl_int_seq *ops; - asdl_expr_seq *comparators; - } Compare; - - struct { - expr_ty func; - asdl_expr_seq *args; - asdl_keyword_seq *keywords; - } Call; - - struct { - expr_ty value; - int conversion; - expr_ty format_spec; - } FormattedValue; - - struct { - asdl_expr_seq *values; - } JoinedStr; - - struct { - constant value; - string kind; - } Constant; - - struct { - expr_ty value; - identifier attr; - expr_context_ty ctx; - } Attribute; - - struct { - expr_ty value; - expr_ty slice; - expr_context_ty ctx; - } Subscript; - - struct { - expr_ty value; - expr_context_ty ctx; - } Starred; - - struct { - identifier id; - expr_context_ty ctx; - } Name; - - struct { - asdl_expr_seq *elts; - expr_context_ty ctx; - } List; - - struct { - asdl_expr_seq *elts; - expr_context_ty ctx; - } Tuple; - - struct { - expr_ty lower; - expr_ty upper; - expr_ty step; - } Slice; - - struct { - expr_ty pattern; - identifier name; - } MatchAs; - - struct { - asdl_expr_seq *patterns; - } MatchOr; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _comprehension { - expr_ty target; - expr_ty iter; - asdl_expr_seq *ifs; - int is_async; -}; - -enum _excepthandler_kind {ExceptHandler_kind=1}; -struct _excepthandler { - enum _excepthandler_kind kind; - union { - struct { - expr_ty type; - identifier name; - asdl_stmt_seq *body; - } ExceptHandler; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _arguments { - asdl_arg_seq *posonlyargs; - asdl_arg_seq *args; - arg_ty vararg; - asdl_arg_seq *kwonlyargs; - asdl_expr_seq *kw_defaults; - arg_ty kwarg; - asdl_expr_seq *defaults; -}; - -struct _arg { - identifier arg; - expr_ty annotation; - string type_comment; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _keyword { - identifier arg; - expr_ty value; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _alias { - identifier name; - identifier asname; -}; - -struct _withitem { - expr_ty context_expr; - expr_ty optional_vars; -}; - -struct _match_case { - expr_ty pattern; - expr_ty guard; - asdl_stmt_seq *body; -}; - -enum _type_ignore_kind {TypeIgnore_kind=1}; -struct _type_ignore { - enum _type_ignore_kind kind; - union { - struct { - int lineno; - string tag; - } TypeIgnore; - - } v; -}; - - -// Note: these macros affect function definitions, not only call sites. -#define Module(a0, a1, a2) _Py_Module(a0, a1, a2) -mod_ty _Py_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, - PyArena *arena); -#define Interactive(a0, a1) _Py_Interactive(a0, a1) -mod_ty _Py_Interactive(asdl_stmt_seq * body, PyArena *arena); -#define Expression(a0, a1) _Py_Expression(a0, a1) -mod_ty _Py_Expression(expr_ty body, PyArena *arena); -#define FunctionType(a0, a1, a2) _Py_FunctionType(a0, a1, a2) -mod_ty _Py_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena - *arena); -#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * - body, asdl_expr_seq * decorator_list, expr_ty returns, - string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq - * body, asdl_expr_seq * decorator_list, expr_ty - returns, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * - keywords, asdl_stmt_seq * body, asdl_expr_seq * - decorator_list, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Return(a0, a1, a2, a3, a4, a5) _Py_Return(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define Delete(a0, a1, a2, a3, a4, a5) _Py_Delete(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Assign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Assign(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) -stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int - simple, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, - asdl_stmt_seq * orelse, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena); -#define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, - asdl_stmt_seq * orelse, string type_comment, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define While(a0, a1, a2, a3, a4, a5, a6, a7) _Py_While(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define If(a0, a1, a2, a3, a4, a5, a6, a7) _Py_If(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define With(a0, a1, a2, a3, a4, a5, a6, a7) _Py_With(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string - type_comment, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string - type_comment, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define Match(a0, a1, a2, a3, a4, a5, a6) _Py_Match(a0, a1, a2, a3, a4, a5, a6) -stmt_ty _Py_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Raise(a0, a1, a2, a3, a4, a5, a6) _Py_Raise(a0, a1, a2, a3, a4, a5, a6) -stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) -stmt_ty _Py_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, - asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Assert(a0, a1, a2, a3, a4, a5, a6) _Py_Assert(a0, a1, a2, a3, a4, a5, a6) -stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Import(a0, a1, a2, a3, a4, a5) _Py_Import(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Import(asdl_alias_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) -stmt_ty _Py_ImportFrom(identifier module, asdl_alias_seq * names, int level, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Global(a0, a1, a2, a3, a4, a5) _Py_Global(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Global(asdl_identifier_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Nonlocal(a0, a1, a2, a3, a4, a5) _Py_Nonlocal(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define Expr(a0, a1, a2, a3, a4, a5) _Py_Expr(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Pass(a0, a1, a2, a3, a4) _Py_Pass(a0, a1, a2, a3, a4) -stmt_ty _Py_Pass(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Break(a0, a1, a2, a3, a4) _Py_Break(a0, a1, a2, a3, a4) -stmt_ty _Py_Break(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Continue(a0, a1, a2, a3, a4) _Py_Continue(a0, a1, a2, a3, a4) -stmt_ty _Py_Continue(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define BoolOp(a0, a1, a2, a3, a4, a5, a6) _Py_BoolOp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define NamedExpr(a0, a1, a2, a3, a4, a5, a6) _Py_NamedExpr(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_NamedExpr(expr_ty target, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define BinOp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_BinOp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define UnaryOp(a0, a1, a2, a3, a4, a5, a6) _Py_UnaryOp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define Lambda(a0, a1, a2, a3, a4, a5, a6) _Py_Lambda(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define IfExp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_IfExp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Dict(a0, a1, a2, a3, a4, a5, a6) _Py_Dict(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Set(a0, a1, a2, a3, a4, a5) _Py_Set(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Set(asdl_expr_seq * elts, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define ListComp(a0, a1, a2, a3, a4, a5, a6) _Py_ListComp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define SetComp(a0, a1, a2, a3, a4, a5, a6) _Py_SetComp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -#define DictComp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_DictComp(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * - generators, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define GeneratorExp(a0, a1, a2, a3, a4, a5, a6) _Py_GeneratorExp(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Await(a0, a1, a2, a3, a4, a5) _Py_Await(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define Yield(a0, a1, a2, a3, a4, a5) _Py_Yield(a0, a1, a2, a3, a4, a5) -expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define YieldFrom(a0, a1, a2, a3, a4, a5) _Py_YieldFrom(a0, a1, a2, a3, a4, a5) -expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Compare(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Compare(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * - comparators, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * - keywords, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) -expr_ty _Py_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define Constant(a0, a1, a2, a3, a4, a5, a6) _Py_Constant(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Constant(constant value, string kind, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -#define Attribute(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Attribute(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Subscript(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Subscript(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -#define Starred(a0, a1, a2, a3, a4, a5, a6) _Py_Starred(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Starred(expr_ty value, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Name(a0, a1, a2, a3, a4, a5, a6) _Py_Name(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define List(a0, a1, a2, a3, a4, a5, a6) _Py_List(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Tuple(a0, a1, a2, a3, a4, a5, a6) _Py_Tuple(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define Slice(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Slice(a0, a1, a2, a3, a4, a5, a6, a7) -expr_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define MatchAs(a0, a1, a2, a3, a4, a5, a6) _Py_MatchAs(a0, a1, a2, a3, a4, a5, a6) -expr_ty _Py_MatchAs(expr_ty pattern, identifier name, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define MatchOr(a0, a1, a2, a3, a4, a5) _Py_MatchOr(a0, a1, a2, a3, a4, a5) -expr_ty _Py_MatchOr(asdl_expr_seq * patterns, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -#define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) -comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq - * ifs, int is_async, PyArena *arena); -#define ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) -excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_stmt_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, a7) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7) -arguments_ty _Py_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, - arg_ty vararg, asdl_arg_seq * kwonlyargs, - asdl_expr_seq * kw_defaults, arg_ty kwarg, - asdl_expr_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, - PyArena *arena); -#define keyword(a0, a1, a2, a3, a4, a5, a6) _Py_keyword(a0, a1, a2, a3, a4, a5, a6) -keyword_ty _Py_keyword(identifier arg, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) -alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); -#define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) -withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena - *arena); -#define match_case(a0, a1, a2, a3) _Py_match_case(a0, a1, a2, a3) -match_case_ty _Py_match_case(expr_ty pattern, expr_ty guard, asdl_stmt_seq * - body, PyArena *arena); -#define TypeIgnore(a0, a1, a2) _Py_TypeIgnore(a0, a1, a2) -type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); - -PyObject* PyAST_mod2obj(mod_ty t); -mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); -int PyAST_Check(PyObject* obj); -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYTHON_AST_H */ diff --git a/Include/Python.h b/Include/Python.h index 86dbbcf6bd85da..1df2fd5343b23a 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -137,11 +137,9 @@ #include "pystate.h" #include "context.h" -#include "cpython/pyarena.h" #include "modsupport.h" #include "compile.h" #include "pythonrun.h" -#include "cpython/parser_interface.h" #include "pylifecycle.h" #include "ceval.h" #include "sysmodule.h" diff --git a/Include/abstract.h b/Include/abstract.h index a47c944060d3d0..1af1487deec916 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -324,11 +324,21 @@ PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj, returns itself. */ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); +/* Takes an AsyncIterable object and returns an AsyncIterator for it. + This is typically a new iterator but if the argument is an AsyncIterator, + this returns itself. */ +PyAPI_FUNC(PyObject *) PyObject_GetAiter(PyObject *); + /* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise. This function always succeeds. */ PyAPI_FUNC(int) PyIter_Check(PyObject *); +/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyAiter_Check(PyObject *); + /* Takes an iterator object and calls its tp_iternext slot, returning the next value. diff --git a/Include/ast.h b/Include/ast.h deleted file mode 100644 index 82bfa4800cdd55..00000000000000 --- a/Include/ast.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_AST_H -#define Py_AST_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python-ast.h" /* mod_ty */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_AST_H */ -#endif /* !Py_LIMITED_API */ diff --git a/Include/compile.h b/Include/compile.h index 4dd5435ce71a96..3c5acd7209f763 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -1,102 +1,9 @@ #ifndef Py_COMPILE_H #define Py_COMPILE_H - -#ifndef Py_LIMITED_API - #ifdef __cplusplus extern "C" { #endif -/* Public interface */ -#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ - CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ - CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ - CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) -#define PyCF_MASK_OBSOLETE (CO_NESTED) - -/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. - PyCF_ constants can use bits from 0x0100 to 0x10000. - CO_FUTURE_ constants use bits starting at 0x20000. */ -#define PyCF_SOURCE_IS_UTF8 0x0100 -#define PyCF_DONT_IMPLY_DEDENT 0x0200 -#define PyCF_ONLY_AST 0x0400 -#define PyCF_IGNORE_COOKIE 0x0800 -#define PyCF_TYPE_COMMENTS 0x1000 -#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 -#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ - PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) - -#ifndef Py_LIMITED_API -typedef struct { - int cf_flags; /* bitmask of CO_xxx flags relevant to future */ - int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ -} PyCompilerFlags; - -#define _PyCompilerFlags_INIT \ - (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} -#endif - -/* Future feature support */ - -typedef struct { - int ff_features; /* flags set by future statements */ - int ff_lineno; /* line number of last future statement */ -} PyFutureFeatures; - -#define FUTURE_NESTED_SCOPES "nested_scopes" -#define FUTURE_GENERATORS "generators" -#define FUTURE_DIVISION "division" -#define FUTURE_ABSOLUTE_IMPORT "absolute_import" -#define FUTURE_WITH_STATEMENT "with_statement" -#define FUTURE_PRINT_FUNCTION "print_function" -#define FUTURE_UNICODE_LITERALS "unicode_literals" -#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" -#define FUTURE_GENERATOR_STOP "generator_stop" -#define FUTURE_ANNOTATIONS "annotations" - -struct _mod; /* Declare the existence of this type */ -#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar) -PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx( - struct _mod *mod, - const char *filename, /* decoded from the filesystem encoding */ - PyCompilerFlags *flags, - int optimize, - PyArena *arena); -PyAPI_FUNC(PyCodeObject *) PyAST_CompileObject( - struct _mod *mod, - PyObject *filename, - PyCompilerFlags *flags, - int optimize, - PyArena *arena); -PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST( - struct _mod * mod, - const char *filename /* decoded from the filesystem encoding */ - ); -PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromASTObject( - struct _mod * mod, - PyObject *filename - ); - -/* _Py_Mangle is defined in compile.c */ -PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); - -#define PY_INVALID_STACK_EFFECT INT_MAX -PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); -PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); - -typedef struct { - int optimize; - int ff_features; -} _PyASTOptimizeState; - -PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, _PyASTOptimizeState *state); - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_LIMITED_API */ - /* These definitions must match corresponding definitions in graminit.h. */ #define Py_single_input 256 #define Py_file_input 257 @@ -106,4 +13,13 @@ PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, _PyASTOptimizeSta /* This doesn't need to match anything */ #define Py_fstring_input 800 +#ifndef Py_LIMITED_API +# define Py_CPYTHON_COMPILE_H +# include "cpython/compile.h" +# undef Py_CPYTHON_COMPILE_H +#endif + +#ifdef __cplusplus +} +#endif #endif /* !Py_COMPILE_H */ diff --git a/Include/cpython/compile.h b/Include/cpython/compile.h new file mode 100644 index 00000000000000..a202c0b0e65508 --- /dev/null +++ b/Include/cpython/compile.h @@ -0,0 +1,52 @@ +#ifndef Py_CPYTHON_COMPILE_H +# error "this header file must not be included directly" +#endif + +/* Public interface */ +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ + CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) + +/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. + PyCF_ constants can use bits from 0x0100 to 0x10000. + CO_FUTURE_ constants use bits starting at 0x20000. */ +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 +#define PyCF_IGNORE_COOKIE 0x0800 +#define PyCF_TYPE_COMMENTS 0x1000 +#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 +#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) + +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ + int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ +} PyCompilerFlags; + +#define _PyCompilerFlags_INIT \ + (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + int ff_lineno; /* line number of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" +#define FUTURE_PRINT_FUNCTION "print_function" +#define FUTURE_UNICODE_LITERALS "unicode_literals" +#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" +#define FUTURE_GENERATOR_STOP "generator_stop" +#define FUTURE_ANNOTATIONS "annotations" + +#define PY_INVALID_STACK_EFFECT INT_MAX +PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); +PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); diff --git a/Include/cpython/parser_interface.h b/Include/cpython/parser_interface.h deleted file mode 100644 index 1c6576d926d8d3..00000000000000 --- a/Include/cpython/parser_interface.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef Py_PEGENINTERFACE -#define Py_PEGENINTERFACE -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python.h" - -#ifndef Py_LIMITED_API -PyAPI_FUNC(struct _mod *) PyParser_ASTFromString( - const char *str, - const char *filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromStringObject( - const char *str, - PyObject* filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( - FILE *fp, - const char *filename, - const char* enc, - int mode, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( - FILE *fp, - PyObject *filename_ob, - const char *enc, - int mode, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFilename( - const char *filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PEGENINTERFACE */ diff --git a/Include/cpython/pyarena.h b/Include/cpython/pyarena.h deleted file mode 100644 index db3ad0188fe1cd..00000000000000 --- a/Include/cpython/pyarena.h +++ /dev/null @@ -1,64 +0,0 @@ -/* An arena-like memory interface for the compiler. - */ - -#ifndef Py_LIMITED_API -#ifndef Py_PYARENA_H -#define Py_PYARENA_H - -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct _arena PyArena; - - /* PyArena_New() and PyArena_Free() create a new arena and free it, - respectively. Once an arena has been created, it can be used - to allocate memory via PyArena_Malloc(). Pointers to PyObject can - also be registered with the arena via PyArena_AddPyObject(), and the - arena will ensure that the PyObjects stay alive at least until - PyArena_Free() is called. When an arena is freed, all the memory it - allocated is freed, the arena releases internal references to registered - PyObject*, and none of its pointers are valid. - XXX (tim) What does "none of its pointers are valid" mean? Does it - XXX mean that pointers previously obtained via PyArena_Malloc() are - XXX no longer valid? (That's clearly true, but not sure that's what - XXX the text is trying to say.) - - PyArena_New() returns an arena pointer. On error, it - returns a negative number and sets an exception. - XXX (tim): Not true. On error, PyArena_New() actually returns NULL, - XXX and looks like it may or may not set an exception (e.g., if the - XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on - XXX and an exception is set; OTOH, if the internal - XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but - XXX an exception is not set in that case). - */ - PyAPI_FUNC(PyArena *) PyArena_New(void); - PyAPI_FUNC(void) PyArena_Free(PyArena *); - - /* Mostly like malloc(), return the address of a block of memory spanning - * `size` bytes, or return NULL (without setting an exception) if enough - * new memory can't be obtained. Unlike malloc(0), PyArena_Malloc() with - * size=0 does not guarantee to return a unique pointer (the pointer - * returned may equal one or more other pointers obtained from - * PyArena_Malloc()). - * Note that pointers obtained via PyArena_Malloc() must never be passed to - * the system free() or realloc(), or to any of Python's similar memory- - * management functions. PyArena_Malloc()-obtained pointers remain valid - * until PyArena_Free(ar) is called, at which point all pointers obtained - * from the arena `ar` become invalid simultaneously. - */ - PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size); - - /* This routine isn't a proper arena allocation routine. It takes - * a PyObject* and records it so that it can be DECREFed when the - * arena is freed. - */ - PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *); - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_PYARENA_H */ -#endif /* Py_LIMITED_API */ diff --git a/Include/asdl.h b/Include/internal/pycore_asdl.h similarity index 81% rename from Include/asdl.h rename to Include/internal/pycore_asdl.h index 8b61e16c329ea9..c0b07c31810b99 100644 --- a/Include/asdl.h +++ b/Include/internal/pycore_asdl.h @@ -1,6 +1,14 @@ -#ifndef Py_LIMITED_API -#ifndef Py_ASDL_H -#define Py_ASDL_H +#ifndef Py_INTERNAL_ASDL_H +#define Py_INTERNAL_ASDL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pyarena.h" // _PyArena_Malloc() typedef PyObject * identifier; typedef PyObject * string; @@ -59,7 +67,7 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a return NULL; \ } \ n += sizeof(asdl_ ## NAME ## _seq); \ - seq = (asdl_ ## NAME ## _seq *)PyArena_Malloc(arena, n); \ + seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \ if (!seq) { \ PyErr_NoMemory(); \ return NULL; \ @@ -73,8 +81,9 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a #define asdl_seq_GET_UNTYPED(S, I) (S)->elements[(I)] #define asdl_seq_GET(S, I) (S)->typed_elements[(I)] #define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) + #ifdef Py_DEBUG -#define asdl_seq_SET(S, I, V) \ +# define asdl_seq_SET(S, I, V) \ do { \ Py_ssize_t _asdl_i = (I); \ assert((S) != NULL); \ @@ -82,11 +91,11 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a (S)->typed_elements[_asdl_i] = (V); \ } while (0) #else -#define asdl_seq_SET(S, I, V) (S)->typed_elements[I] = (V) +# define asdl_seq_SET(S, I, V) (S)->typed_elements[I] = (V) #endif #ifdef Py_DEBUG -#define asdl_seq_SET_UNTYPED(S, I, V) \ +# define asdl_seq_SET_UNTYPED(S, I, V) \ do { \ Py_ssize_t _asdl_i = (I); \ assert((S) != NULL); \ @@ -94,8 +103,10 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a (S)->elements[_asdl_i] = (V); \ } while (0) #else -#define asdl_seq_SET_UNTYPED(S, I, V) (S)->elements[I] = (V) +# define asdl_seq_SET_UNTYPED(S, I, V) (S)->elements[I] = (V) #endif -#endif /* !Py_ASDL_H */ -#endif /* Py_LIMITED_API */ +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_ASDL_H */ diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h index 6cc0b9b3b000fd..ac1e387560b789 100644 --- a/Include/internal/pycore_ast.h +++ b/Include/internal/pycore_ast.h @@ -1,3 +1,5 @@ +// File automatically generated by Parser/asdl_c.py. + #ifndef Py_INTERNAL_AST_H #define Py_INTERNAL_AST_H #ifdef __cplusplus @@ -8,7 +10,820 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "Python-ast.h" // expr_ty +#include "pycore_asdl.h" + +#undef Yield /* undefine macro conflicting with */ + +typedef struct _mod *mod_ty; + +typedef struct _stmt *stmt_ty; + +typedef struct _expr *expr_ty; + +typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty; + +typedef enum _boolop { And=1, Or=2 } boolop_ty; + +typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, + LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, + FloorDiv=13 } operator_ty; + +typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; + +typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, + In=9, NotIn=10 } cmpop_ty; + +typedef struct _comprehension *comprehension_ty; + +typedef struct _excepthandler *excepthandler_ty; + +typedef struct _arguments *arguments_ty; + +typedef struct _arg *arg_ty; + +typedef struct _keyword *keyword_ty; + +typedef struct _alias *alias_ty; + +typedef struct _withitem *withitem_ty; + +typedef struct _match_case *match_case_ty; + +typedef struct _type_ignore *type_ignore_ty; + + +typedef struct { + _ASDL_SEQ_HEAD + mod_ty typed_elements[1]; +} asdl_mod_seq; + +asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + stmt_ty typed_elements[1]; +} asdl_stmt_seq; + +asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + expr_ty typed_elements[1]; +} asdl_expr_seq; + +asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + comprehension_ty typed_elements[1]; +} asdl_comprehension_seq; + +asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + excepthandler_ty typed_elements[1]; +} asdl_excepthandler_seq; + +asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + arguments_ty typed_elements[1]; +} asdl_arguments_seq; + +asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + arg_ty typed_elements[1]; +} asdl_arg_seq; + +asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + keyword_ty typed_elements[1]; +} asdl_keyword_seq; + +asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + alias_ty typed_elements[1]; +} asdl_alias_seq; + +asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + withitem_ty typed_elements[1]; +} asdl_withitem_seq; + +asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena); + +typedef struct { + _ASDL_SEQ_HEAD + match_case_ty typed_elements[1]; +} asdl_match_case_seq; + +asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD + type_ignore_ty typed_elements[1]; +} asdl_type_ignore_seq; + +asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena + *arena); + + +enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, + FunctionType_kind=4}; +struct _mod { + enum _mod_kind kind; + union { + struct { + asdl_stmt_seq *body; + asdl_type_ignore_seq *type_ignores; + } Module; + + struct { + asdl_stmt_seq *body; + } Interactive; + + struct { + expr_ty body; + } Expression; + + struct { + asdl_expr_seq *argtypes; + expr_ty returns; + } FunctionType; + + } v; +}; + +enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, + Return_kind=4, Delete_kind=5, Assign_kind=6, + AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, + AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, + AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17, + Assert_kind=18, Import_kind=19, ImportFrom_kind=20, + Global_kind=21, Nonlocal_kind=22, Expr_kind=23, Pass_kind=24, + Break_kind=25, Continue_kind=26}; +struct _stmt { + enum _stmt_kind kind; + union { + struct { + identifier name; + arguments_ty args; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; + expr_ty returns; + string type_comment; + } FunctionDef; + + struct { + identifier name; + arguments_ty args; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; + expr_ty returns; + string type_comment; + } AsyncFunctionDef; + + struct { + identifier name; + asdl_expr_seq *bases; + asdl_keyword_seq *keywords; + asdl_stmt_seq *body; + asdl_expr_seq *decorator_list; + } ClassDef; + + struct { + expr_ty value; + } Return; + + struct { + asdl_expr_seq *targets; + } Delete; + + struct { + asdl_expr_seq *targets; + expr_ty value; + string type_comment; + } Assign; + + struct { + expr_ty target; + operator_ty op; + expr_ty value; + } AugAssign; + + struct { + expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + } AnnAssign; + + struct { + expr_ty target; + expr_ty iter; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + string type_comment; + } For; + + struct { + expr_ty target; + expr_ty iter; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + string type_comment; + } AsyncFor; + + struct { + expr_ty test; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + } While; + + struct { + expr_ty test; + asdl_stmt_seq *body; + asdl_stmt_seq *orelse; + } If; + + struct { + asdl_withitem_seq *items; + asdl_stmt_seq *body; + string type_comment; + } With; + + struct { + asdl_withitem_seq *items; + asdl_stmt_seq *body; + string type_comment; + } AsyncWith; + + struct { + expr_ty subject; + asdl_match_case_seq *cases; + } Match; + + struct { + expr_ty exc; + expr_ty cause; + } Raise; + + struct { + asdl_stmt_seq *body; + asdl_excepthandler_seq *handlers; + asdl_stmt_seq *orelse; + asdl_stmt_seq *finalbody; + } Try; + + struct { + expr_ty test; + expr_ty msg; + } Assert; + + struct { + asdl_alias_seq *names; + } Import; + + struct { + identifier module; + asdl_alias_seq *names; + int level; + } ImportFrom; + + struct { + asdl_identifier_seq *names; + } Global; + + struct { + asdl_identifier_seq *names; + } Nonlocal; + + struct { + expr_ty value; + } Expr; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, + Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8, + ListComp_kind=9, SetComp_kind=10, DictComp_kind=11, + GeneratorExp_kind=12, Await_kind=13, Yield_kind=14, + YieldFrom_kind=15, Compare_kind=16, Call_kind=17, + FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, + Attribute_kind=21, Subscript_kind=22, Starred_kind=23, + Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27, + MatchAs_kind=28, MatchOr_kind=29}; +struct _expr { + enum _expr_kind kind; + union { + struct { + boolop_ty op; + asdl_expr_seq *values; + } BoolOp; + + struct { + expr_ty target; + expr_ty value; + } NamedExpr; + + struct { + expr_ty left; + operator_ty op; + expr_ty right; + } BinOp; + + struct { + unaryop_ty op; + expr_ty operand; + } UnaryOp; + + struct { + arguments_ty args; + expr_ty body; + } Lambda; + + struct { + expr_ty test; + expr_ty body; + expr_ty orelse; + } IfExp; + + struct { + asdl_expr_seq *keys; + asdl_expr_seq *values; + } Dict; + + struct { + asdl_expr_seq *elts; + } Set; + + struct { + expr_ty elt; + asdl_comprehension_seq *generators; + } ListComp; + + struct { + expr_ty elt; + asdl_comprehension_seq *generators; + } SetComp; + + struct { + expr_ty key; + expr_ty value; + asdl_comprehension_seq *generators; + } DictComp; + + struct { + expr_ty elt; + asdl_comprehension_seq *generators; + } GeneratorExp; + + struct { + expr_ty value; + } Await; + + struct { + expr_ty value; + } Yield; + + struct { + expr_ty value; + } YieldFrom; + + struct { + expr_ty left; + asdl_int_seq *ops; + asdl_expr_seq *comparators; + } Compare; + + struct { + expr_ty func; + asdl_expr_seq *args; + asdl_keyword_seq *keywords; + } Call; + + struct { + expr_ty value; + int conversion; + expr_ty format_spec; + } FormattedValue; + + struct { + asdl_expr_seq *values; + } JoinedStr; + + struct { + constant value; + string kind; + } Constant; + + struct { + expr_ty value; + identifier attr; + expr_context_ty ctx; + } Attribute; + + struct { + expr_ty value; + expr_ty slice; + expr_context_ty ctx; + } Subscript; + + struct { + expr_ty value; + expr_context_ty ctx; + } Starred; + + struct { + identifier id; + expr_context_ty ctx; + } Name; + + struct { + asdl_expr_seq *elts; + expr_context_ty ctx; + } List; + + struct { + asdl_expr_seq *elts; + expr_context_ty ctx; + } Tuple; + + struct { + expr_ty lower; + expr_ty upper; + expr_ty step; + } Slice; + + struct { + expr_ty pattern; + identifier name; + } MatchAs; + + struct { + asdl_expr_seq *patterns; + } MatchOr; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _comprehension { + expr_ty target; + expr_ty iter; + asdl_expr_seq *ifs; + int is_async; +}; + +enum _excepthandler_kind {ExceptHandler_kind=1}; +struct _excepthandler { + enum _excepthandler_kind kind; + union { + struct { + expr_ty type; + identifier name; + asdl_stmt_seq *body; + } ExceptHandler; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _arguments { + asdl_arg_seq *posonlyargs; + asdl_arg_seq *args; + arg_ty vararg; + asdl_arg_seq *kwonlyargs; + asdl_expr_seq *kw_defaults; + arg_ty kwarg; + asdl_expr_seq *defaults; +}; + +struct _arg { + identifier arg; + expr_ty annotation; + string type_comment; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _keyword { + identifier arg; + expr_ty value; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _alias { + identifier name; + identifier asname; +}; + +struct _withitem { + expr_ty context_expr; + expr_ty optional_vars; +}; + +struct _match_case { + expr_ty pattern; + expr_ty guard; + asdl_stmt_seq *body; +}; + +enum _type_ignore_kind {TypeIgnore_kind=1}; +struct _type_ignore { + enum _type_ignore_kind kind; + union { + struct { + int lineno; + string tag; + } TypeIgnore; + + } v; +}; + + +// Note: these macros affect function definitions, not only call sites. +#define Module(a0, a1, a2) _Py_Module(a0, a1, a2) +mod_ty _Py_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, + PyArena *arena); +#define Interactive(a0, a1) _Py_Interactive(a0, a1) +mod_ty _Py_Interactive(asdl_stmt_seq * body, PyArena *arena); +#define Expression(a0, a1) _Py_Expression(a0, a1) +mod_ty _Py_Expression(expr_ty body, PyArena *arena); +#define FunctionType(a0, a1, a2) _Py_FunctionType(a0, a1, a2) +mod_ty _Py_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena + *arena); +#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * + body, asdl_expr_seq * decorator_list, expr_ty returns, + string type_comment, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) +stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq + * body, asdl_expr_seq * decorator_list, expr_ty + returns, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +stmt_ty _Py_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * + keywords, asdl_stmt_seq * body, asdl_expr_seq * + decorator_list, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Return(a0, a1, a2, a3, a4, a5) _Py_Return(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define Delete(a0, a1, a2, a3, a4, a5) _Py_Delete(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Assign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Assign(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) +stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int + simple, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena); +#define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, + asdl_stmt_seq * orelse, string type_comment, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define While(a0, a1, a2, a3, a4, a5, a6, a7) _Py_While(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define If(a0, a1, a2, a3, a4, a5, a6, a7) _Py_If(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define With(a0, a1, a2, a3, a4, a5, a6, a7) _Py_With(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string + type_comment, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define Match(a0, a1, a2, a3, a4, a5, a6) _Py_Match(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Raise(a0, a1, a2, a3, a4, a5, a6) _Py_Raise(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) +stmt_ty _Py_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Assert(a0, a1, a2, a3, a4, a5, a6) _Py_Assert(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Import(a0, a1, a2, a3, a4, a5) _Py_Import(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Import(asdl_alias_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_ImportFrom(identifier module, asdl_alias_seq * names, int level, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Global(a0, a1, a2, a3, a4, a5) _Py_Global(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Global(asdl_identifier_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Nonlocal(a0, a1, a2, a3, a4, a5) _Py_Nonlocal(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define Expr(a0, a1, a2, a3, a4, a5) _Py_Expr(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Pass(a0, a1, a2, a3, a4) _Py_Pass(a0, a1, a2, a3, a4) +stmt_ty _Py_Pass(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Break(a0, a1, a2, a3, a4) _Py_Break(a0, a1, a2, a3, a4) +stmt_ty _Py_Break(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Continue(a0, a1, a2, a3, a4) _Py_Continue(a0, a1, a2, a3, a4) +stmt_ty _Py_Continue(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define BoolOp(a0, a1, a2, a3, a4, a5, a6) _Py_BoolOp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define NamedExpr(a0, a1, a2, a3, a4, a5, a6) _Py_NamedExpr(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_NamedExpr(expr_ty target, expr_ty value, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define BinOp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_BinOp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define UnaryOp(a0, a1, a2, a3, a4, a5, a6) _Py_UnaryOp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define Lambda(a0, a1, a2, a3, a4, a5, a6) _Py_Lambda(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define IfExp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_IfExp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Dict(a0, a1, a2, a3, a4, a5, a6) _Py_Dict(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Set(a0, a1, a2, a3, a4, a5) _Py_Set(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Set(asdl_expr_seq * elts, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define ListComp(a0, a1, a2, a3, a4, a5, a6) _Py_ListComp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define SetComp(a0, a1, a2, a3, a4, a5, a6) _Py_SetComp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define DictComp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_DictComp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * + generators, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define GeneratorExp(a0, a1, a2, a3, a4, a5, a6) _Py_GeneratorExp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Await(a0, a1, a2, a3, a4, a5) _Py_Await(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define Yield(a0, a1, a2, a3, a4, a5) _Py_Yield(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define YieldFrom(a0, a1, a2, a3, a4, a5) _Py_YieldFrom(a0, a1, a2, a3, a4, a5) +expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Compare(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Compare(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * + comparators, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * + keywords, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) +expr_ty _Py_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Constant(a0, a1, a2, a3, a4, a5, a6) _Py_Constant(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Constant(constant value, string kind, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define Attribute(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Attribute(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Subscript(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Subscript(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Starred(a0, a1, a2, a3, a4, a5, a6) _Py_Starred(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Starred(expr_ty value, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Name(a0, a1, a2, a3, a4, a5, a6) _Py_Name(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define List(a0, a1, a2, a3, a4, a5, a6) _Py_List(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Tuple(a0, a1, a2, a3, a4, a5, a6) _Py_Tuple(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Slice(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Slice(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define MatchAs(a0, a1, a2, a3, a4, a5, a6) _Py_MatchAs(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_MatchAs(expr_ty pattern, identifier name, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define MatchOr(a0, a1, a2, a3, a4, a5) _Py_MatchOr(a0, a1, a2, a3, a4, a5) +expr_ty _Py_MatchOr(asdl_expr_seq * patterns, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq + * ifs, int is_async, PyArena *arena); +#define ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) +excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_stmt_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, a7) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7) +arguments_ty _Py_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, + arg_ty vararg, asdl_arg_seq * kwonlyargs, + asdl_expr_seq * kw_defaults, arg_ty kwarg, + asdl_expr_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, + PyArena *arena); +#define keyword(a0, a1, a2, a3, a4, a5, a6) _Py_keyword(a0, a1, a2, a3, a4, a5, a6) +keyword_ty _Py_keyword(identifier arg, expr_ty value, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) +alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); +#define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) +withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena + *arena); +#define match_case(a0, a1, a2, a3) _Py_match_case(a0, a1, a2, a3) +match_case_ty _Py_match_case(expr_ty pattern, expr_ty guard, asdl_stmt_seq * + body, PyArena *arena); +#define TypeIgnore(a0, a1, a2) _Py_TypeIgnore(a0, a1, a2) +type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); + + +PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); +int PyAST_Check(PyObject* obj); extern int _PyAST_Validate(mod_ty); @@ -24,4 +839,3 @@ extern PyObject* _PyAST_GetDocString(asdl_stmt_seq *); } #endif #endif /* !Py_INTERNAL_AST_H */ - diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h new file mode 100644 index 00000000000000..e8859bbec6daa7 --- /dev/null +++ b/Include/internal/pycore_compile.h @@ -0,0 +1,41 @@ +#ifndef Py_INTERNAL_COMPILE_H +#define Py_INTERNAL_COMPILE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +struct _arena; // Type defined in pycore_pyarena.h +struct _mod; // Type defined in pycore_ast.h + +// Export the symbol for test_peg_generator (built as a library) +PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( + struct _mod *mod, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + struct _arena *arena); +extern PyFutureFeatures* _PyFuture_FromAST( + struct _mod * mod, + PyObject *filename + ); + +extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); + +typedef struct { + int optimize; + int ff_features; +} _PyASTOptimizeState; + +extern int _PyAST_Optimize( + struct _mod *, + struct _arena *arena, + _PyASTOptimizeState *state); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_COMPILE_H */ diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h index 0f61e751408586..3faf8cf6b2eefc 100644 --- a/Include/internal/pycore_dtoa.h +++ b/Include/internal/pycore_dtoa.h @@ -1,6 +1,4 @@ #ifndef PY_NO_SHORT_FLOAT_REPR -#ifndef Py_INTERNAL_DTOA_H -#define Py_INTERNAL_DTOA_H #ifdef __cplusplus extern "C" { #endif @@ -19,21 +17,7 @@ PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); PyAPI_FUNC(double) _Py_dg_stdnan(int sign); PyAPI_FUNC(double) _Py_dg_infinity(int sign); -#define _PyDtoa_Kmax 7 - -typedef uint32_t _PyDtoa_ULong; -typedef int32_t _PyDtoa_Long; -typedef uint64_t _PyDtoa_ULLong; - -struct -_PyDtoa_Bigint { - struct _PyDtoa_Bigint *next; - int k, maxwds, sign, wds; - _PyDtoa_ULong x[1]; -}; - #ifdef __cplusplus } #endif -#endif /* !Py_INTERNAL_DTOA_H */ #endif /* !PY_NO_SHORT_FLOAT_REPR */ diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 1e4b3ff71eed49..fa0e26feb0f843 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -13,7 +13,6 @@ extern "C" { #include "pycore_gil.h" // struct _gil_runtime_state #include "pycore_gc.h" // struct _gc_runtime_state #include "pycore_warnings.h" // struct _warnings_runtime_state -#include "pycore_dtoa.h" struct _pending_calls { PyThread_type_lock lock; @@ -322,9 +321,6 @@ struct _is { struct ast_state ast; struct type_cache type_cache; -#ifndef PY_NO_SHORT_FLOAT_REPR - struct _PyDtoa_Bigint *dtoa_freelist[_PyDtoa_Kmax + 1]; -#endif }; extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); diff --git a/Include/internal/pycore_parser.h b/Include/internal/pycore_parser.h new file mode 100644 index 00000000000000..e2de24e2ca9734 --- /dev/null +++ b/Include/internal/pycore_parser.h @@ -0,0 +1,31 @@ +#ifndef Py_INTERNAL_PARSER_H +#define Py_INTERNAL_PARSER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern struct _mod* _PyParser_ASTFromString( + const char *str, + PyObject* filename, + int mode, + PyCompilerFlags *flags, + PyArena *arena); +extern struct _mod* _PyParser_ASTFromFile( + FILE *fp, + PyObject *filename_ob, + const char *enc, + int mode, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PARSER_H */ diff --git a/Include/internal/pycore_pyarena.h b/Include/internal/pycore_pyarena.h new file mode 100644 index 00000000000000..d78972a88ca238 --- /dev/null +++ b/Include/internal/pycore_pyarena.h @@ -0,0 +1,64 @@ +/* An arena-like memory interface for the compiler. + */ + +#ifndef Py_INTERNAL_PYARENA_H +#define Py_INTERNAL_PYARENA_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct _arena PyArena; + +/* _PyArena_New() and _PyArena_Free() create a new arena and free it, + respectively. Once an arena has been created, it can be used + to allocate memory via _PyArena_Malloc(). Pointers to PyObject can + also be registered with the arena via _PyArena_AddPyObject(), and the + arena will ensure that the PyObjects stay alive at least until + _PyArena_Free() is called. When an arena is freed, all the memory it + allocated is freed, the arena releases internal references to registered + PyObject*, and none of its pointers are valid. + XXX (tim) What does "none of its pointers are valid" mean? Does it + XXX mean that pointers previously obtained via _PyArena_Malloc() are + XXX no longer valid? (That's clearly true, but not sure that's what + XXX the text is trying to say.) + + _PyArena_New() returns an arena pointer. On error, it + returns a negative number and sets an exception. + XXX (tim): Not true. On error, _PyArena_New() actually returns NULL, + XXX and looks like it may or may not set an exception (e.g., if the + XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on + XXX and an exception is set; OTOH, if the internal + XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but + XXX an exception is not set in that case). +*/ +PyAPI_FUNC(PyArena*) _PyArena_New(void); +PyAPI_FUNC(void) _PyArena_Free(PyArena *); + +/* Mostly like malloc(), return the address of a block of memory spanning + * `size` bytes, or return NULL (without setting an exception) if enough + * new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with + * size=0 does not guarantee to return a unique pointer (the pointer + * returned may equal one or more other pointers obtained from + * _PyArena_Malloc()). + * Note that pointers obtained via _PyArena_Malloc() must never be passed to + * the system free() or realloc(), or to any of Python's similar memory- + * management functions. _PyArena_Malloc()-obtained pointers remain valid + * until _PyArena_Free(ar) is called, at which point all pointers obtained + * from the arena `ar` become invalid simultaneously. + */ +PyAPI_FUNC(void*) _PyArena_Malloc(PyArena *, size_t size); + +/* This routine isn't a proper arena allocation routine. It takes + * a PyObject* and records it so that it can be DECREFed when the + * arena is freed. + */ +PyAPI_FUNC(int) _PyArena_AddPyObject(PyArena *, PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYARENA_H */ diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index 80d5fd1c417158..5d34a6c951cab3 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -8,7 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "Python-ast.h" /* mod_ty */ +struct _mod; // Type defined in pycore_ast.h typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } _Py_block_ty; @@ -74,7 +74,7 @@ extern PyTypeObject PySTEntry_Type; extern int _PyST_GetScope(PySTEntryObject *, PyObject *); extern struct symtable* _PySymtable_Build( - mod_ty mod, + struct _mod *mod, PyObject *filename, PyFutureFeatures *future); PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); diff --git a/Lib/__future__.py b/Lib/__future__.py index 0e7b5552343356..326e2b24d1d048 100644 --- a/Lib/__future__.py +++ b/Lib/__future__.py @@ -42,7 +42,7 @@ argument to the builtin function compile() to enable the feature in dynamically compiled code. This flag is stored in the .compiler_flag attribute on _Future instances. These values must match the appropriate -#defines of CO_xxx flags in Include/compile.h. +#defines of CO_xxx flags in Include/cpython/compile.h. No feature line is ever to be deleted from this file. """ diff --git a/Lib/fractions.py b/Lib/fractions.py index de3e23b759227c..96047beb4546a5 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -380,32 +380,139 @@ def reverse(b, a): return forward, reverse + # Rational arithmetic algorithms: Knuth, TAOCP, Volume 2, 4.5.1. + # + # Assume input fractions a and b are normalized. + # + # 1) Consider addition/subtraction. + # + # Let g = gcd(da, db). Then + # + # na nb na*db ± nb*da + # a ± b == -- ± -- == ------------- == + # da db da*db + # + # na*(db//g) ± nb*(da//g) t + # == ----------------------- == - + # (da*db)//g d + # + # Now, if g > 1, we're working with smaller integers. + # + # Note, that t, (da//g) and (db//g) are pairwise coprime. + # + # Indeed, (da//g) and (db//g) share no common factors (they were + # removed) and da is coprime with na (since input fractions are + # normalized), hence (da//g) and na are coprime. By symmetry, + # (db//g) and nb are coprime too. Then, + # + # gcd(t, da//g) == gcd(na*(db//g), da//g) == 1 + # gcd(t, db//g) == gcd(nb*(da//g), db//g) == 1 + # + # Above allows us optimize reduction of the result to lowest + # terms. Indeed, + # + # g2 = gcd(t, d) == gcd(t, (da//g)*(db//g)*g) == gcd(t, g) + # + # t//g2 t//g2 + # a ± b == ----------------------- == ---------------- + # (da//g)*(db//g)*(g//g2) (da//g)*(db//g2) + # + # is a normalized fraction. This is useful because the unnormalized + # denominator d could be much larger than g. + # + # We should special-case g == 1 (and g2 == 1), since 60.8% of + # randomly-chosen integers are coprime: + # https://en.wikipedia.org/wiki/Coprime_integers#Probability_of_coprimality + # Note, that g2 == 1 always for fractions, obtained from floats: here + # g is a power of 2 and the unnormalized numerator t is an odd integer. + # + # 2) Consider multiplication + # + # Let g1 = gcd(na, db) and g2 = gcd(nb, da), then + # + # na*nb na*nb (na//g1)*(nb//g2) + # a*b == ----- == ----- == ----------------- + # da*db db*da (db//g1)*(da//g2) + # + # Note, that after divisions we're multiplying smaller integers. + # + # Also, the resulting fraction is normalized, because each of + # two factors in the numerator is coprime to each of the two factors + # in the denominator. + # + # Indeed, pick (na//g1). It's coprime with (da//g2), because input + # fractions are normalized. It's also coprime with (db//g1), because + # common factors are removed by g1 == gcd(na, db). + # + # As for addition/subtraction, we should special-case g1 == 1 + # and g2 == 1 for same reason. That happens also for multiplying + # rationals, obtained from floats. + def _add(a, b): """a + b""" - da, db = a.denominator, b.denominator - return Fraction(a.numerator * db + b.numerator * da, - da * db) + na, da = a.numerator, a.denominator + nb, db = b.numerator, b.denominator + g = math.gcd(da, db) + if g == 1: + return Fraction(na * db + da * nb, da * db, _normalize=False) + s = da // g + t = na * (db // g) + nb * s + g2 = math.gcd(t, g) + if g2 == 1: + return Fraction(t, s * db, _normalize=False) + return Fraction(t // g2, s * (db // g2), _normalize=False) __add__, __radd__ = _operator_fallbacks(_add, operator.add) def _sub(a, b): """a - b""" - da, db = a.denominator, b.denominator - return Fraction(a.numerator * db - b.numerator * da, - da * db) + na, da = a.numerator, a.denominator + nb, db = b.numerator, b.denominator + g = math.gcd(da, db) + if g == 1: + return Fraction(na * db - da * nb, da * db, _normalize=False) + s = da // g + t = na * (db // g) - nb * s + g2 = math.gcd(t, g) + if g2 == 1: + return Fraction(t, s * db, _normalize=False) + return Fraction(t // g2, s * (db // g2), _normalize=False) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) def _mul(a, b): """a * b""" - return Fraction(a.numerator * b.numerator, a.denominator * b.denominator) + na, da = a.numerator, a.denominator + nb, db = b.numerator, b.denominator + g1 = math.gcd(na, db) + if g1 > 1: + na //= g1 + db //= g1 + g2 = math.gcd(nb, da) + if g2 > 1: + nb //= g2 + da //= g2 + return Fraction(na * nb, db * da, _normalize=False) __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) def _div(a, b): """a / b""" - return Fraction(a.numerator * b.denominator, - a.denominator * b.numerator) + # Same as _mul(), with inversed b. + na, da = a.numerator, a.denominator + nb, db = b.numerator, b.denominator + g1 = math.gcd(na, nb) + if g1 > 1: + na //= g1 + nb //= g1 + g2 = math.gcd(db, da) + if g2 > 1: + da //= g2 + db //= g2 + n, d = na * db, nb * da + if d < 0: + n, d = -n, -d + return Fraction(n, d, _normalize=False) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index e4f893c38c1aad..5038b46a018bbf 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -275,7 +275,7 @@ def _requires_frozen_wrapper(self, fullname): def _load_module_shim(self, fullname): """Load the specified module into sys.modules and return it. - This method is deprecated. Use loader.exec_module instead. + This method is deprecated. Use loader.exec_module() instead. """ msg = ("the load_module() method is deprecated and slated for removal in " @@ -292,24 +292,16 @@ def _load_module_shim(self, fullname): # Module specifications ####################################################### def _module_repr(module): - # The implementation of ModuleType.__repr__(). + """The implementation of ModuleType.__repr__().""" loader = getattr(module, '__loader__', None) - if hasattr(loader, 'module_repr'): - # As soon as BuiltinImporter, FrozenImporter, and NamespaceLoader - # drop their implementations for module_repr. we can add a - # deprecation warning here. + if spec := getattr(module, "__spec__", None): + return _module_repr_from_spec(spec) + elif hasattr(loader, 'module_repr'): try: return loader.module_repr(module) except Exception: pass - try: - spec = module.__spec__ - except AttributeError: - pass - else: - if spec is not None: - return _module_repr_from_spec(spec) - + # Fall through to a catch-all which always succeeds. # We could use module.__class__.__name__ instead of 'module' in the # various repr permutations. try: diff --git a/Lib/pprint.py b/Lib/pprint.py index a8af50e5a68611..b45cfdd99a8e11 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -45,18 +45,19 @@ def pprint(object, stream=None, indent=1, width=80, depth=None, *, - compact=False, sort_dicts=True): + compact=False, sort_dicts=True, underscore_numbers=False): """Pretty-print a Python object to a stream [default is sys.stdout].""" printer = PrettyPrinter( stream=stream, indent=indent, width=width, depth=depth, - compact=compact, sort_dicts=sort_dicts) + compact=compact, sort_dicts=sort_dicts, underscore_numbers=False) printer.pprint(object) def pformat(object, indent=1, width=80, depth=None, *, - compact=False, sort_dicts=True): + compact=False, sort_dicts=True, underscore_numbers=False): """Format a Python object into a pretty-printed representation.""" return PrettyPrinter(indent=indent, width=width, depth=depth, - compact=compact, sort_dicts=sort_dicts).pformat(object) + compact=compact, sort_dicts=sort_dicts, + underscore_numbers=underscore_numbers).pformat(object) def pp(object, *args, sort_dicts=False, **kwargs): """Pretty-print a Python object""" @@ -102,7 +103,7 @@ def _safe_tuple(t): class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None, *, - compact=False, sort_dicts=True): + compact=False, sort_dicts=True, underscore_numbers=False): """Handle pretty printing operations onto a stream using a set of configured parameters. @@ -143,6 +144,7 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *, self._stream = _sys.stdout self._compact = bool(compact) self._sort_dicts = sort_dicts + self._underscore_numbers = underscore_numbers def pprint(self, object): self._format(object, self._stream, 0, 0, {}, 0) @@ -525,6 +527,13 @@ def _safe_repr(self, object, context, maxlevels, level): return repr(object), True, False r = getattr(typ, "__repr__", None) + + if issubclass(typ, int) and r is int.__repr__: + if self._underscore_numbers: + return f"{object:_d}", True, False + else: + return repr(object), True, False + if issubclass(typ, dict) and r is dict.__repr__: if not object: return "{}", True, False @@ -592,7 +601,7 @@ def _safe_repr(self, object, context, maxlevels, level): rep = repr(object) return rep, (rep and not rep.startswith('<')), False -_builtin_scalars = frozenset({str, bytes, bytearray, int, float, complex, +_builtin_scalars = frozenset({str, bytes, bytearray, float, complex, bool, type(None)}) def _recursion(object): diff --git a/Lib/runpy.py b/Lib/runpy.py index 7e1e1ac5dde2df..caba1214262380 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -16,7 +16,6 @@ import io import types import os -from pkgutil import read_code, get_importer __all__ = [ "run_module", "run_path", @@ -233,6 +232,7 @@ def _get_main_module_details(error=ImportError): def _get_code_from_file(run_name, fname): # Check for a compiled file first + from pkgutil import read_code decoded_path = os.path.abspath(os.fsdecode(fname)) with io.open_code(decoded_path) as f: code = read_code(f) @@ -255,6 +255,7 @@ def run_path(path_name, init_globals=None, run_name=None): if run_name is None: run_name = "" pkg_name = run_name.rpartition(".")[0] + from pkgutil import get_importer importer = get_importer(path_name) # Trying to avoid importing imp so as to not consume the deprecation warning. is_NullImporter = False diff --git a/Lib/shutil.py b/Lib/shutil.py index 89d924dec8aa4e..e29fe4d83e9277 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -32,16 +32,6 @@ except ImportError: _LZMA_SUPPORTED = False -try: - from pwd import getpwnam -except ImportError: - getpwnam = None - -try: - from grp import getgrnam -except ImportError: - getgrnam = None - _WINDOWS = os.name == 'nt' posix = nt = None if os.name == 'posix': @@ -843,8 +833,14 @@ def _is_immutable(src): def _get_gid(name): """Returns a gid, given a group name.""" - if getgrnam is None or name is None: + if name is None: + return None + + try: + from grp import getgrnam + except ImportError: return None + try: result = getgrnam(name) except KeyError: @@ -855,8 +851,14 @@ def _get_gid(name): def _get_uid(name): """Returns an uid, given a user name.""" - if getpwnam is None or name is None: + if name is None: return None + + try: + from pwd import getpwnam + except ImportError: + return None + try: result = getpwnam(name) except KeyError: diff --git a/Lib/subprocess.py b/Lib/subprocess.py index d375514b2dd0a6..4b011e4ce55794 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -53,14 +53,6 @@ from time import monotonic as _time import types -try: - import pwd -except ImportError: - pwd = None -try: - import grp -except ImportError: - grp = None try: import fcntl except ImportError: @@ -875,7 +867,9 @@ def __init__(self, args, bufsize=-1, executable=None, "current platform") elif isinstance(group, str): - if grp is None: + try: + import grp + except ImportError: raise ValueError("The group parameter cannot be a string " "on systems without the grp module") @@ -901,7 +895,9 @@ def __init__(self, args, bufsize=-1, executable=None, gids = [] for extra_group in extra_groups: if isinstance(extra_group, str): - if grp is None: + try: + import grp + except ImportError: raise ValueError("Items in extra_groups cannot be " "strings on systems without the " "grp module") @@ -927,10 +923,11 @@ def __init__(self, args, bufsize=-1, executable=None, "the current platform") elif isinstance(user, str): - if pwd is None: + try: + import pwd + except ImportError: raise ValueError("The user parameter cannot be a string " "on systems without the pwd module") - uid = pwd.getpwnam(user).pw_uid elif isinstance(user, int): uid = user diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 793c99a8f4ca32..1df927da403d6e 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -1,4 +1,3 @@ -import datetime import faulthandler import locale import os @@ -150,9 +149,12 @@ def log(self, line=''): # add the timestamp prefix: "0:01:05 " test_time = time.monotonic() - self.start_time - test_time = datetime.timedelta(seconds=int(test_time)) - line = f"{test_time} {line}" + mins, secs = divmod(int(test_time), 60) + hours, mins = divmod(mins, 60) + test_time = "%d:%02d:%02d" % (hours, mins, secs) + + line = f"{test_time} {line}" if empty: line = line[:-1] diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 77298d318898db..7c7086a806b1cd 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -5,6 +5,7 @@ from inspect import isabstract from test import support from test.support import os_helper +from test.libregrtest.utils import clear_caches try: from _abc import _get_dump @@ -181,102 +182,6 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs): clear_caches() -def clear_caches(): - # Clear the warnings registry, so they can be displayed again - for mod in sys.modules.values(): - if hasattr(mod, '__warningregistry__'): - del mod.__warningregistry__ - - # Flush standard output, so that buffered data is sent to the OS and - # associated Python objects are reclaimed. - for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): - if stream is not None: - stream.flush() - - # Clear assorted module caches. - # Don't worry about resetting the cache if the module is not loaded - try: - distutils_dir_util = sys.modules['distutils.dir_util'] - except KeyError: - pass - else: - distutils_dir_util._path_created.clear() - re.purge() - - try: - _strptime = sys.modules['_strptime'] - except KeyError: - pass - else: - _strptime._regex_cache.clear() - - try: - urllib_parse = sys.modules['urllib.parse'] - except KeyError: - pass - else: - urllib_parse.clear_cache() - - try: - urllib_request = sys.modules['urllib.request'] - except KeyError: - pass - else: - urllib_request.urlcleanup() - - try: - linecache = sys.modules['linecache'] - except KeyError: - pass - else: - linecache.clearcache() - - try: - mimetypes = sys.modules['mimetypes'] - except KeyError: - pass - else: - mimetypes._default_mime_types() - - try: - filecmp = sys.modules['filecmp'] - except KeyError: - pass - else: - filecmp._cache.clear() - - try: - struct = sys.modules['struct'] - except KeyError: - pass - else: - struct._clearcache() - - try: - doctest = sys.modules['doctest'] - except KeyError: - pass - else: - doctest.master = None - - try: - ctypes = sys.modules['ctypes'] - except KeyError: - pass - else: - ctypes._reset_cache() - - try: - typing = sys.modules['typing'] - except KeyError: - pass - else: - for f in typing._cleanups: - f() - - support.gc_collect() - - def warm_caches(): # char cache s = bytes(range(256)) diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index e46cc31caea5ae..927c4706629705 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -11,9 +11,8 @@ import unittest from test import support -from test.support import import_helper from test.support import os_helper -from test.libregrtest.refleak import dash_R, clear_caches +from test.libregrtest.utils import clear_caches from test.libregrtest.save_env import saved_test_environment from test.libregrtest.utils import format_duration, print_warning @@ -211,6 +210,10 @@ def _test_module(the_module): support.run_unittest(tests) +def save_env(ns, test_name): + return saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) + + def _runtest_inner2(ns, test_name): # Load the test function, run the test function, handle huntrleaks # and findleaks to detect leaks @@ -218,10 +221,16 @@ def _runtest_inner2(ns, test_name): abstest = get_abs_module(ns, test_name) # remove the module from sys.module to reload it if it was already imported - import_helper.unload(abstest) + try: + del sys.modules[abstest] + except KeyError: + pass the_module = importlib.import_module(abstest) + if ns.huntrleaks: + from test.libregrtest.refleak import dash_R + # 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) @@ -229,12 +238,13 @@ def _runtest_inner2(ns, test_name): 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: - test_runner() - refleak = False + with save_env(ns, test_name): + if ns.huntrleaks: + # Return True if the test leaked references + refleak = dash_R(ns, test_name, test_runner) + else: + test_runner() + refleak = False finally: cleanup_test_droppings(test_name, ns.verbose) @@ -268,7 +278,7 @@ def _runtest_inner(ns, test_name, display_failure=True): try: clear_caches() - with saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) as environment: + with save_env(ns, test_name): refleak = _runtest_inner2(ns, test_name) except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: @@ -298,7 +308,7 @@ def _runtest_inner(ns, test_name, display_failure=True): if refleak: return FAILED - if environment.changed: + if support.environment_altered: return ENV_CHANGED return PASSED diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index 4c9c692400b920..f0bfcf389992d8 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -1,21 +1,15 @@ -import asyncio import builtins import locale -import logging import os -import shutil import sys -import sysconfig import threading -import urllib.request -import warnings from test import support from test.support import os_helper from test.libregrtest.utils import print_warning -try: - import _multiprocessing, multiprocessing.process -except ImportError: - multiprocessing = None + + +class SkipTestEnvironment(Exception): + pass # Unit tests are supposed to leave the execution environment unchanged @@ -33,15 +27,13 @@ class saved_test_environment: #stuff Unless quiet is True, a warning is printed to stderr if any of - the saved items was changed by the test. The attribute 'changed' - is initially False, but is set to True if a change is detected. + the saved items was changed by the test. The support.environment_altered + attribute is set to True if a change is detected. If verbose is more than 1, the before and after state of changed items is also printed. """ - changed = False - def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): self.testname = testname self.verbose = verbose @@ -73,20 +65,36 @@ def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): 'urllib.requests._url_tempfiles', 'urllib.requests._opener', ) + def get_module(self, name): + # function for restore() methods + return sys.modules[name] + + def try_get_module(self, name): + # function for get() methods + try: + return self.get_module(name) + except KeyError: + raise SkipTestEnvironment + def get_urllib_requests__url_tempfiles(self): - return list(urllib.request._url_tempfiles) + urllib_request = self.try_get_module('urllib.request') + return list(urllib_request._url_tempfiles) def restore_urllib_requests__url_tempfiles(self, tempfiles): for filename in tempfiles: os_helper.unlink(filename) def get_urllib_requests__opener(self): - return urllib.request._opener + urllib_request = self.try_get_module('urllib.request') + return urllib_request._opener def restore_urllib_requests__opener(self, opener): - urllib.request._opener = opener + urllib_request = self.get_module('urllib.request') + urllib_request._opener = opener def get_asyncio_events__event_loop_policy(self): + self.try_get_module('asyncio') return support.maybe_get_event_loop_policy() def restore_asyncio_events__event_loop_policy(self, policy): + asyncio = self.get_module('asyncio') asyncio.set_event_loop_policy(policy) def get_sys_argv(self): @@ -145,8 +153,10 @@ def restore___import__(self, import_): builtins.__import__ = import_ def get_warnings_filters(self): + warnings = self.try_get_module('warnings') return id(warnings.filters), warnings.filters, warnings.filters[:] def restore_warnings_filters(self, saved_filters): + warnings = self.get_module('warnings') warnings.filters = saved_filters[1] warnings.filters[:] = saved_filters[2] @@ -161,23 +171,28 @@ def restore_asyncore_socket_map(self, saved_map): asyncore.socket_map.update(saved_map) def get_shutil_archive_formats(self): + shutil = self.try_get_module('shutil') # we could call get_archives_formats() but that only returns the # registry keys; we want to check the values too (the functions that # are registered) return shutil._ARCHIVE_FORMATS, shutil._ARCHIVE_FORMATS.copy() def restore_shutil_archive_formats(self, saved): + shutil = self.get_module('shutil') shutil._ARCHIVE_FORMATS = saved[0] shutil._ARCHIVE_FORMATS.clear() shutil._ARCHIVE_FORMATS.update(saved[1]) def get_shutil_unpack_formats(self): + shutil = self.try_get_module('shutil') return shutil._UNPACK_FORMATS, shutil._UNPACK_FORMATS.copy() def restore_shutil_unpack_formats(self, saved): + shutil = self.get_module('shutil') shutil._UNPACK_FORMATS = saved[0] shutil._UNPACK_FORMATS.clear() shutil._UNPACK_FORMATS.update(saved[1]) def get_logging__handlers(self): + logging = self.try_get_module('logging') # _handlers is a WeakValueDictionary return id(logging._handlers), logging._handlers, logging._handlers.copy() def restore_logging__handlers(self, saved_handlers): @@ -185,6 +200,7 @@ def restore_logging__handlers(self, saved_handlers): pass def get_logging__handlerList(self): + logging = self.try_get_module('logging') # _handlerList is a list of weakrefs to handlers return id(logging._handlerList), logging._handlerList, logging._handlerList[:] def restore_logging__handlerList(self, saved_handlerList): @@ -208,32 +224,34 @@ def restore_threading__dangling(self, saved): # Same for Process objects def get_multiprocessing_process__dangling(self): - if not multiprocessing: - return None + multiprocessing_process = self.try_get_module('multiprocessing.process') # Unjoined process objects can survive after process exits - multiprocessing.process._cleanup() + multiprocessing_process._cleanup() # This copies the weakrefs without making any strong reference - return multiprocessing.process._dangling.copy() + return multiprocessing_process._dangling.copy() def restore_multiprocessing_process__dangling(self, saved): - if not multiprocessing: - return - multiprocessing.process._dangling.clear() - multiprocessing.process._dangling.update(saved) + multiprocessing_process = self.get_module('multiprocessing.process') + multiprocessing_process._dangling.clear() + multiprocessing_process._dangling.update(saved) def get_sysconfig__CONFIG_VARS(self): # make sure the dict is initialized + sysconfig = self.try_get_module('sysconfig') sysconfig.get_config_var('prefix') return (id(sysconfig._CONFIG_VARS), sysconfig._CONFIG_VARS, dict(sysconfig._CONFIG_VARS)) def restore_sysconfig__CONFIG_VARS(self, saved): + sysconfig = self.get_module('sysconfig') sysconfig._CONFIG_VARS = saved[1] sysconfig._CONFIG_VARS.clear() sysconfig._CONFIG_VARS.update(saved[2]) def get_sysconfig__INSTALL_SCHEMES(self): + sysconfig = self.try_get_module('sysconfig') return (id(sysconfig._INSTALL_SCHEMES), sysconfig._INSTALL_SCHEMES, sysconfig._INSTALL_SCHEMES.copy()) def restore_sysconfig__INSTALL_SCHEMES(self, saved): + sysconfig = self.get_module('sysconfig') sysconfig._INSTALL_SCHEMES = saved[1] sysconfig._INSTALL_SCHEMES.clear() sysconfig._INSTALL_SCHEMES.update(saved[2]) @@ -264,8 +282,10 @@ def restore_locale(self, saved): locale.setlocale(lc, setting) def get_warnings_showwarning(self): + warnings = self.try_get_module('warnings') return warnings.showwarning def restore_warnings_showwarning(self, fxn): + warnings = self.get_module('warnings') warnings.showwarning = fxn def resource_info(self): @@ -276,26 +296,28 @@ def resource_info(self): yield name, getattr(self, get_name), getattr(self, restore_name) def __enter__(self): - self.saved_values = dict((name, get()) for name, get, restore - in self.resource_info()) + self.saved_values = [] + for name, get, restore in self.resource_info(): + try: + original = get() + except SkipTestEnvironment: + continue + + self.saved_values.append((name, get, restore, original)) return self def __exit__(self, exc_type, exc_val, exc_tb): saved_values = self.saved_values - del self.saved_values + self.saved_values = None # Some resources use weak references support.gc_collect() - # Read support.environment_altered, set by support helper functions - self.changed |= support.environment_altered - - for name, get, restore in self.resource_info(): + for name, get, restore, original in saved_values: current = get() - original = saved_values.pop(name) # Check for changes to the resource's value if current != original: - self.changed = True + support.environment_altered = True restore(original) if not self.quiet and not self.pgo: print_warning(f"{name} was modified by {self.testname}") diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index 7738d4f28b6582..715d4b96cf91d4 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -93,6 +93,10 @@ def _test_audit_hook(name, args): support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, ns.timeout) support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout) + if ns.xmlpath: + from test.support.testresult import RegressionTestResult + RegressionTestResult.USE_XML = True + def replace_stdout(): """Set stdout encoder error handler to backslashreplace (as stderr error diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 71f538f0c45338..13efdb45818b7d 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -84,3 +84,105 @@ def setup_unraisable_hook(): global orig_unraisablehook orig_unraisablehook = sys.unraisablehook sys.unraisablehook = regrtest_unraisable_hook + + +def clear_caches(): + # Clear the warnings registry, so they can be displayed again + for mod in sys.modules.values(): + if hasattr(mod, '__warningregistry__'): + del mod.__warningregistry__ + + # Flush standard output, so that buffered data is sent to the OS and + # associated Python objects are reclaimed. + for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): + if stream is not None: + stream.flush() + + # Clear assorted module caches. + # Don't worry about resetting the cache if the module is not loaded + try: + distutils_dir_util = sys.modules['distutils.dir_util'] + except KeyError: + pass + else: + distutils_dir_util._path_created.clear() + + try: + re = sys.modules['re'] + except KeyError: + pass + else: + re.purge() + + try: + _strptime = sys.modules['_strptime'] + except KeyError: + pass + else: + _strptime._regex_cache.clear() + + try: + urllib_parse = sys.modules['urllib.parse'] + except KeyError: + pass + else: + urllib_parse.clear_cache() + + try: + urllib_request = sys.modules['urllib.request'] + except KeyError: + pass + else: + urllib_request.urlcleanup() + + try: + linecache = sys.modules['linecache'] + except KeyError: + pass + else: + linecache.clearcache() + + try: + mimetypes = sys.modules['mimetypes'] + except KeyError: + pass + else: + mimetypes._default_mime_types() + + try: + filecmp = sys.modules['filecmp'] + except KeyError: + pass + else: + filecmp._cache.clear() + + try: + struct = sys.modules['struct'] + except KeyError: + pass + else: + struct._clearcache() + + try: + doctest = sys.modules['doctest'] + except KeyError: + pass + else: + doctest.master = None + + try: + ctypes = sys.modules['ctypes'] + except KeyError: + pass + else: + ctypes._reset_cache() + + try: + typing = sys.modules['typing'] + except KeyError: + pass + else: + for f in typing._cleanups: + f() + + support.gc_collect() diff --git a/Lib/test/support/testresult.py b/Lib/test/support/testresult.py index 67e126dcf7527a..670afbea2659de 100644 --- a/Lib/test/support/testresult.py +++ b/Lib/test/support/testresult.py @@ -9,21 +9,21 @@ import traceback import unittest -import xml.etree.ElementTree as ET - -from datetime import datetime - class RegressionTestResult(unittest.TextTestResult): separator1 = '=' * 70 + '\n' separator2 = '-' * 70 + '\n' + USE_XML = False def __init__(self, stream, descriptions, verbosity): super().__init__(stream=stream, descriptions=descriptions, verbosity=0) self.buffer = True - self.__suite = ET.Element('testsuite') - self.__suite.set('start', datetime.utcnow().isoformat(' ')) - - self.__e = None + if self.USE_XML: + from xml.etree import ElementTree as ET + from datetime import datetime + self.__ET = ET + self.__suite = ET.Element('testsuite') + self.__suite.set('start', datetime.utcnow().isoformat(' ')) + self.__e = None self.__start_time = None self.__results = [] self.__verbose = bool(verbosity) @@ -42,17 +42,22 @@ def __getId(cls, test): def startTest(self, test): super().startTest(test) - self.__e = e = ET.SubElement(self.__suite, 'testcase') + if self.USE_XML: + self.__e = e = self.__ET.SubElement(self.__suite, 'testcase') self.__start_time = time.perf_counter() if self.__verbose: self.stream.write(f'{self.getDescription(test)} ... ') self.stream.flush() def _add_result(self, test, capture=False, **args): + if not self.USE_XML: + return e = self.__e self.__e = None if e is None: return + ET = self.__ET + e.set('name', args.pop('name', self.__getId(test))) e.set('status', args.pop('status', 'run')) e.set('result', args.pop('result', 'completed')) @@ -147,6 +152,8 @@ def printErrorList(self, flavor, errors): self.stream.write('%s\n' % err) def get_xml_element(self): + if not self.USE_XML: + raise ValueError("USE_XML is false") e = self.__suite e.set('tests', str(self.testsRun)) e.set('errors', str(len(self.errors))) @@ -174,6 +181,9 @@ def get_test_runner(stream, verbosity, capture_output=False): return get_test_runner_class(verbosity, capture_output)(stream) if __name__ == '__main__': + import xml.etree.ElementTree as ET + RegressionTestResult.USE_XML = True + class TestTests(unittest.TestCase): def test_pass(self): pass diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 1f7e05b42be99c..99464e3d0929fd 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -372,6 +372,88 @@ def tearDown(self): self.loop = None asyncio.set_event_loop_policy(None) + def test_async_gen_anext(self): + async def gen(): + yield 1 + yield 2 + g = gen() + async def consume(): + results = [] + results.append(await anext(g)) + results.append(await anext(g)) + results.append(await anext(g, 'buckle my shoe')) + return results + res = self.loop.run_until_complete(consume()) + self.assertEqual(res, [1, 2, 'buckle my shoe']) + with self.assertRaises(StopAsyncIteration): + self.loop.run_until_complete(consume()) + + def test_async_gen_aiter(self): + async def gen(): + yield 1 + yield 2 + g = gen() + async def consume(): + return [i async for i in aiter(g)] + res = self.loop.run_until_complete(consume()) + self.assertEqual(res, [1, 2]) + + def test_async_gen_aiter_class(self): + results = [] + class Gen: + async def __aiter__(self): + yield 1 + yield 2 + g = Gen() + async def consume(): + ait = aiter(g) + while True: + try: + results.append(await anext(ait)) + except StopAsyncIteration: + break + self.loop.run_until_complete(consume()) + self.assertEqual(results, [1, 2]) + + def test_aiter_idempotent(self): + async def gen(): + yield 1 + applied_once = aiter(gen()) + applied_twice = aiter(applied_once) + self.assertIs(applied_once, applied_twice) + + def test_anext_bad_args(self): + async def gen(): + yield 1 + async def call_with_too_few_args(): + await anext() + async def call_with_too_many_args(): + await anext(gen(), 1, 3) + async def call_with_wrong_type_args(): + await anext(1, gen()) + with self.assertRaises(TypeError): + self.loop.run_until_complete(call_with_too_few_args()) + with self.assertRaises(TypeError): + self.loop.run_until_complete(call_with_too_many_args()) + with self.assertRaises(TypeError): + self.loop.run_until_complete(call_with_wrong_type_args()) + + def test_aiter_bad_args(self): + async def gen(): + yield 1 + async def call_with_too_few_args(): + await aiter() + async def call_with_too_many_args(): + await aiter(gen(), 1) + async def call_with_wrong_type_arg(): + await aiter(1) + with self.assertRaises(TypeError): + self.loop.run_until_complete(call_with_too_few_args()) + with self.assertRaises(TypeError): + self.loop.run_until_complete(call_with_too_many_args()) + with self.assertRaises(TypeError): + self.loop.run_until_complete(call_with_wrong_type_arg()) + async def to_list(self, gen): res = [] async for i in gen: diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index e87eede0c26761..25d3eec40c13de 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -851,13 +851,19 @@ def test_sys_flags_not_set(self): ) class SyntaxErrorTests(unittest.TestCase): - def test_tokenizer_error_with_stdin(self): - proc = subprocess.run([sys.executable, "-"], input = b"(1+2+3", + def check_string(self, code): + proc = subprocess.run([sys.executable, "-"], input=code, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.assertNotEqual(proc.returncode, 0) self.assertNotEqual(proc.stderr, None) self.assertIn(b"\nSyntaxError", proc.stderr) + def test_tokenizer_error_with_stdin(self): + self.check_string(b"(1+2+3") + + def test_decoding_error_at_the_end_of_the_line(self): + self.check_string(b"'\u1f'") + def test_main(): support.run_unittest(CmdLineTest, IgnoreEnvironmentTest, SyntaxErrorTests) support.reap_children() diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 0845f7921c39ec..b92552531d6bb2 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -369,7 +369,9 @@ def testArithmetic(self): self.assertEqual(F(1, 2), F(1, 10) + F(2, 5)) self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5)) self.assertEqual(F(1, 25), F(1, 10) * F(2, 5)) + self.assertEqual(F(5, 6), F(2, 3) * F(5, 4)) self.assertEqual(F(1, 4), F(1, 10) / F(2, 5)) + self.assertEqual(F(-15, 8), F(3, 4) / F(-2, 5)) self.assertTypedEquals(2, F(9, 10) // F(2, 5)) self.assertTypedEquals(10**23, F(10**23, 1) // F(1)) self.assertEqual(F(5, 6), F(7, 3) % F(3, 2)) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index d7143d154a1bc1..79e123f4b8cec6 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1275,5 +1275,14 @@ def test_with_an_underscore_and_a_comma_in_format_specifier(self): with self.assertRaisesRegex(ValueError, error_msg): f'{1:_,}' + def test_syntax_error_for_starred_expressions(self): + error_msg = re.escape("can't use starred expression here") + with self.assertRaisesRegex(SyntaxError, error_msg): + compile("f'{*a}'", "?", "exec") + + error_msg = re.escape("can't use double starred expression here") + with self.assertRaisesRegex(SyntaxError, error_msg): + compile("f'{**a}'", "?", "exec") + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py index 8eaffa798a5b7a..632246ade08265 100644 --- a/Lib/test/test_importlib/frozen/test_loader.py +++ b/Lib/test/test_importlib/frozen/test_loader.py @@ -160,14 +160,6 @@ def test_module_repr(self): self.assertEqual(repr_str, "") - def test_module_repr_indirect(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - with util.uncache('__hello__'), captured_stdout(): - module = self.machinery.FrozenImporter.load_module('__hello__') - self.assertEqual(repr(module), - "") - # No way to trigger an error in a frozen module. test_state_after_failure = None diff --git a/Lib/test/test_importlib/test_namespace_pkgs.py b/Lib/test/test_importlib/test_namespace_pkgs.py index a8f95a035e2450..ab5847c5553121 100644 --- a/Lib/test/test_importlib/test_namespace_pkgs.py +++ b/Lib/test/test_importlib/test_namespace_pkgs.py @@ -82,7 +82,8 @@ def test_cant_import_other(self): def test_module_repr(self): import foo.one - self.assertEqual(repr(foo), "") + self.assertEqual(foo.__spec__.loader.module_repr(foo), + "") class DynamicPathNamespacePackage(NamespacePackageTest): diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 706fcbe3439b48..72feaedbe7513a 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -3860,6 +3860,9 @@ def test_builtins_have_signatures(self): needs_groups = {"range", "slice", "dir", "getattr", "next", "iter", "vars"} no_signature |= needs_groups + # These have unrepresentable parameter default values of NULL + needs_null = {"anext"} + no_signature |= needs_null # These need PEP 457 groups or a signature change to accept None needs_semantic_update = {"round"} no_signature |= needs_semantic_update diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index c4a8578a9fc8fb..e5d2ac52d12836 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -206,6 +206,7 @@ def test_same_as_repr(self): self.assertEqual(pprint.pformat(simple), native) self.assertEqual(pprint.pformat(simple, width=1, indent=0) .replace('\n', ' '), native) + self.assertEqual(pprint.pformat(simple, underscore_numbers=True), native) self.assertEqual(pprint.saferepr(simple), native) def test_container_repr_override_called(self): @@ -323,6 +324,18 @@ def test_width(self): '1 ' '2']]]]]""") + def test_integer(self): + self.assertEqual(pprint.pformat(1234567), '1234567') + self.assertEqual(pprint.pformat(1234567, underscore_numbers=True), '1_234_567') + + class Temperature(int): + def __new__(cls, celsius_degrees): + return super().__new__(Temperature, celsius_degrees) + def __repr__(self): + kelvin_degrees = self + 273.15 + return f"{kelvin_degrees}°K" + self.assertEqual(pprint.pformat(Temperature(1000)), '1273.15°K') + def test_sorted_dict(self): # Starting in Python 2.5, pprint sorts dict displays by key regardless # of how small the dictionary may be. diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 24233b29171f8c..730c297717af5d 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1162,6 +1162,11 @@ def func2(): """ self._check_error(code, "expected ':'") + def test_invalid_line_continuation_error_position(self): + self._check_error(r"a = 3 \ 4", + "unexpected character after line continuation character", + lineno=1, offset=9) + def test_invalid_line_continuation_left_recursive(self): # Check bpo-42218: SyntaxErrors following left-recursive rules # (t_primary_raw in this case) need to be tested explicitly diff --git a/Makefile.pre.in b/Makefile.pre.in index 5b47530a2a7748..365449d644583f 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -317,7 +317,7 @@ PEGEN_OBJS= \ PEGEN_HEADERS= \ - $(srcdir)/Include/cpython/parser_interface.h \ + $(srcdir)/Include/internal/pycore_parser.h \ $(srcdir)/Parser/pegen.h \ $(srcdir)/Parser/string_parser.h @@ -849,16 +849,19 @@ regen-pegen: .PHONY=regen-ast regen-ast: - # Regenerate Include/Python-ast.h and Python/Python-ast.c using Parser/asdl_c.py + # Regenerate 3 files using using Parser/asdl_c.py: + # - Include/internal/pycore_ast.h + # - Include/internal/pycore_ast_state.h + # - Python/Python-ast.c $(MKDIR_P) $(srcdir)/Include $(MKDIR_P) $(srcdir)/Python $(PYTHON_FOR_REGEN) $(srcdir)/Parser/asdl_c.py \ $(srcdir)/Parser/Python.asdl \ - -H $(srcdir)/Include/Python-ast.h.new \ + -H $(srcdir)/Include/internal/pycore_ast.h.new \ -I $(srcdir)/Include/internal/pycore_ast_state.h.new \ -C $(srcdir)/Python/Python-ast.c.new - $(UPDATE_FILE) $(srcdir)/Include/Python-ast.h $(srcdir)/Include/Python-ast.h.new + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_ast.h $(srcdir)/Include/internal/pycore_ast.h.new $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_ast_state.h $(srcdir)/Include/internal/pycore_ast_state.h.new $(UPDATE_FILE) $(srcdir)/Python/Python-ast.c $(srcdir)/Python/Python-ast.c.new @@ -922,7 +925,7 @@ regen-stdlib-module-names: build_all Programs/_testembed > $(srcdir)/Python/stdlib_module_names.h.new $(UPDATE_FILE) $(srcdir)/Python/stdlib_module_names.h $(srcdir)/Python/stdlib_module_names.h.new -Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o Python/future.o: $(srcdir)/Include/Python-ast.h +Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o Python/future.o: $(srcdir)/Include/internal/pycore_ast.h Python/getplatform.o: $(srcdir)/Python/getplatform.c $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c @@ -1020,8 +1023,6 @@ regen-typeslots: PYTHON_HEADERS= \ $(srcdir)/Include/Python.h \ $(srcdir)/Include/abstract.h \ - $(srcdir)/Include/asdl.h \ - $(srcdir)/Include/ast.h \ $(srcdir)/Include/bltinmodule.h \ $(srcdir)/Include/boolobject.h \ $(srcdir)/Include/bytearrayobject.h \ @@ -1098,13 +1099,13 @@ PYTHON_HEADERS= \ \ pyconfig.h \ $(PARSER_HEADERS) \ - $(srcdir)/Include/Python-ast.h \ \ $(srcdir)/Include/cpython/abstract.h \ $(srcdir)/Include/cpython/bytearrayobject.h \ $(srcdir)/Include/cpython/bytesobject.h \ $(srcdir)/Include/cpython/ceval.h \ $(srcdir)/Include/cpython/code.h \ + $(srcdir)/Include/cpython/compile.h \ $(srcdir)/Include/cpython/dictobject.h \ $(srcdir)/Include/cpython/fileobject.h \ $(srcdir)/Include/cpython/fileutils.h \ @@ -1118,7 +1119,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/objimpl.h \ $(srcdir)/Include/cpython/odictobject.h \ $(srcdir)/Include/cpython/picklebufobject.h \ - $(srcdir)/Include/cpython/pyarena.h \ $(srcdir)/Include/cpython/pyctype.h \ $(srcdir)/Include/cpython/pydebug.h \ $(srcdir)/Include/cpython/pyerrors.h \ @@ -1135,6 +1135,7 @@ PYTHON_HEADERS= \ \ $(srcdir)/Include/internal/pycore_abstract.h \ $(srcdir)/Include/internal/pycore_accu.h \ + $(srcdir)/Include/internal/pycore_asdl.h \ $(srcdir)/Include/internal/pycore_ast.h \ $(srcdir)/Include/internal/pycore_ast_state.h \ $(srcdir)/Include/internal/pycore_atomic.h \ @@ -1144,6 +1145,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ $(srcdir)/Include/internal/pycore_code.h \ + $(srcdir)/Include/internal/pycore_compile.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ $(srcdir)/Include/internal/pycore_dtoa.h \ @@ -1160,6 +1162,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_long.h \ $(srcdir)/Include/internal/pycore_object.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ + $(srcdir)/Include/internal/pycore_pyarena.h \ $(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyhash.h \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ @@ -1488,6 +1491,7 @@ TESTSUBDIRS= ctypes/test \ test/test_importlib/namespace_pkgs/project3 \ test/test_importlib/namespace_pkgs/project3/parent \ test/test_importlib/namespace_pkgs/project3/parent/child \ + test/test_importlib/namespacedata01 \ test/test_importlib/partial \ test/test_importlib/source \ test/test_importlib/zipdata01 \ diff --git a/Misc/ACKS b/Misc/ACKS index d1cee7d02b7869..5d3f75a4165b11 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -902,6 +902,7 @@ James King W. Trevor King Jeffrey Kintscher Paul Kippes +Sergey B Kirpichev Steve Kirsch Sebastian Kirsche Kamil Kisiel diff --git a/Misc/NEWS.d/next/C API/2021-03-19-12-56-11.bpo-43244.VuIyOD.rst b/Misc/NEWS.d/next/C API/2021-03-19-12-56-11.bpo-43244.VuIyOD.rst new file mode 100644 index 00000000000000..1afe11e1921612 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-03-19-12-56-11.bpo-43244.VuIyOD.rst @@ -0,0 +1,8 @@ +Remove ``ast.h``, ``asdl.h``, and ``Python-ast.h`` header files. +These functions were undocumented and excluded from the limited C API. +Most names defined by these header files were not prefixed by ``Py`` and so +could create names conflicts. For example, ``Python-ast.h`` defined a ``Yield`` +macro which was conflict with the ``Yield`` name used by the Windows +```` header. +Use the Python :mod:`ast` module instead. +Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst b/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst new file mode 100644 index 00000000000000..fcc8076dea63e0 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst @@ -0,0 +1,16 @@ +Remove the compiler and parser functions using ``struct _mod`` type, because +the public AST C API was removed: + +* ``PyAST_Compile()`` +* ``PyAST_CompileEx()`` +* ``PyAST_CompileObject()`` +* ``PyFuture_FromAST()`` +* ``PyFuture_FromASTObject()`` +* ``PyParser_ASTFromFile()`` +* ``PyParser_ASTFromFileObject()`` +* ``PyParser_ASTFromFilename()`` +* ``PyParser_ASTFromString()`` +* ``PyParser_ASTFromStringObject()`` + +These functions were undocumented and excluded from the limited C API. +Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2021-03-24-01-22-14.bpo-43244.31-97x.rst b/Misc/NEWS.d/next/C API/2021-03-24-01-22-14.bpo-43244.31-97x.rst new file mode 100644 index 00000000000000..389ee3e1339480 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-03-24-01-22-14.bpo-43244.31-97x.rst @@ -0,0 +1,10 @@ +Remove the ``pyarena.h`` header file with functions: + +* ``PyArena_New()`` +* ``PyArena_Free()`` +* ``PyArena_Malloc()`` +* ``PyArena_AddPyObject()`` + +These functions were undocumented, excluded from the limited C API, and were +only used internally by the compiler. +Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-02-03-13-23-10.bpo-29988.8_UB5w.rst b/Misc/NEWS.d/next/Core and Builtins/2020-02-03-13-23-10.bpo-29988.8_UB5w.rst new file mode 100644 index 00000000000000..9a19c615a88f63 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-02-03-13-23-10.bpo-29988.8_UB5w.rst @@ -0,0 +1,3 @@ +Only handle asynchronous exceptions and requests to drop the GIL when +returning from a call or on the back edges of loops. Makes sure that +:meth:`__exit__` is always called in with statements, even for interrupts. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-19-22-49-40.bpo-43555.ZmhYSA.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-19-22-49-40.bpo-43555.ZmhYSA.rst new file mode 100644 index 00000000000000..55a2fe22aa8abf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-19-22-49-40.bpo-43555.ZmhYSA.rst @@ -0,0 +1,2 @@ +Report the column offset for :exc:`SyntaxError` for invalid line +continuation characters. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-20-19-54-47.bpo-42137.A8aQvj.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-20-19-54-47.bpo-42137.A8aQvj.rst new file mode 100644 index 00000000000000..e13ce49b954b17 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-20-19-54-47.bpo-42137.A8aQvj.rst @@ -0,0 +1,2 @@ +The import system now prefers using ``__spec__`` for ``ModuleType.__repr__`` +over ``module_repr()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst new file mode 100644 index 00000000000000..102325830347ae --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst @@ -0,0 +1,2 @@ +Speed up calls to ``map()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst new file mode 100644 index 00000000000000..f6ea4d0bda6a01 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-24-00-32-20.bpo-41064._H0K_g.rst @@ -0,0 +1,2 @@ +Improve the syntax error for invalid usage of double starred elements ('**') +in f-strings. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2018-08-24-01-08-09.bpo-31861.-q9RKJ.rst b/Misc/NEWS.d/next/Library/2018-08-24-01-08-09.bpo-31861.-q9RKJ.rst new file mode 100644 index 00000000000000..1526deb995c3dc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-08-24-01-08-09.bpo-31861.-q9RKJ.rst @@ -0,0 +1,2 @@ +Add builtins.aiter and builtins.anext. +Patch by Joshua Bronson (@jab), Daniel Pope (@lordmauve), and Justin Wang (@justin39). diff --git a/Misc/NEWS.d/next/Library/2021-03-07-08-03-31.bpo-43420.cee_X5.rst b/Misc/NEWS.d/next/Library/2021-03-07-08-03-31.bpo-43420.cee_X5.rst new file mode 100644 index 00000000000000..f9b3228772c121 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-03-07-08-03-31.bpo-43420.cee_X5.rst @@ -0,0 +1,2 @@ +Improve performance of class:`fractions.Fraction` arithmetics for large +components. Contributed by Sergey B. Kirpichev. diff --git a/Misc/NEWS.d/next/Library/2021-03-14-21-47-28.bpo-42914.9U1o33.rst b/Misc/NEWS.d/next/Library/2021-03-14-21-47-28.bpo-42914.9U1o33.rst new file mode 100644 index 00000000000000..ae6ef2f0bfa424 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-03-14-21-47-28.bpo-42914.9U1o33.rst @@ -0,0 +1,3 @@ +:func:`pprint.pprint` gains a new boolean ``underscore_numbers`` optional +argument to emit integers with thousands separated by an underscore character +for improved readability (for example ``1_000_000`` instead of ``1000000``). diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 699f906a6aec12..acbf068637b4ea 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -354,7 +354,7 @@ static int fuzz_csv_reader(const char* data, size_t size) { return 0; } /* Ignore non null-terminated strings since _csv can't handle - embeded nulls */ + embedded nulls */ if (memchr(data, '\0', size) == NULL) { return 0; } @@ -383,7 +383,7 @@ static int fuzz_csv_reader(const char* data, size_t size) { } /* Ignore csv.Error because we're probably going to generate - some bad files (embeded new-lines, unterminated quotes etc) */ + some bad files (embedded new-lines, unterminated quotes etc) */ if (PyErr_ExceptionMatches(csv_error)) { PyErr_Clear(); } diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index c3234920d57ef9..cf10b4deaf4520 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -1,6 +1,4 @@ #include "Python.h" - -#include "Python-ast.h" #include "pycore_symtable.h" // struct symtable #include "clinic/symtablemodule.c.h" diff --git a/Objects/abstract.c b/Objects/abstract.c index 4cd59100ddc567..fcfe2dbe483f4f 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2738,6 +2738,26 @@ PyObject_GetIter(PyObject *o) } } +PyObject * +PyObject_GetAiter(PyObject *o) { + PyTypeObject *t = Py_TYPE(o); + unaryfunc f; + + if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) { + return type_error("'%.200s' object is not an AsyncIterable", o); + } + f = t->tp_as_async->am_aiter; + PyObject *it = (*f)(o); + if (it != NULL && !PyAiter_Check(it)) { + PyErr_Format(PyExc_TypeError, + "aiter() returned non-AsyncIterator of type '%.100s'", + Py_TYPE(it)->tp_name); + Py_DECREF(it); + it = NULL; + } + return it; +} + int PyIter_Check(PyObject *obj) { @@ -2746,6 +2766,17 @@ PyIter_Check(PyObject *obj) tp->tp_iternext != &_PyObject_NextNotImplemented); } +int +PyAiter_Check(PyObject *obj) +{ + PyTypeObject *tp = Py_TYPE(obj); + return (tp->tp_as_async != NULL && + tp->tp_as_async->am_aiter != NULL && + tp->tp_as_async->am_aiter != &_PyObject_NextNotImplemented && + tp->tp_as_async->am_anext != NULL && + tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented); +} + /* Return next item. * If an error occurs, return NULL. PyErr_Occurred() will be true. * If the iteration terminates normally, return NULL and clear the diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 6cac41ad539db1..f0c6b799176804 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -157,7 +157,7 @@ PyTypeObject PySeqIter_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)iter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -276,7 +276,7 @@ PyTypeObject PyCallIter_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)calliter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -288,3 +288,95 @@ PyTypeObject PyCallIter_Type = { }; +/* -------------------------------------- */ + +typedef struct { + PyObject_HEAD + PyObject *wrapped; + PyObject *default_value; +} anextawaitableobject; + +static void +anextawaitable_dealloc(anextawaitableobject *obj) +{ + _PyObject_GC_UNTRACK(obj); + Py_XDECREF(obj->wrapped); + Py_XDECREF(obj->default_value); + PyObject_GC_Del(obj); +} + +static int +anextawaitable_traverse(anextawaitableobject *obj, visitproc visit, void *arg) +{ + Py_VISIT(obj->wrapped); + Py_VISIT(obj->default_value); + return 0; +} + +static PyObject * +anextawaitable_iternext(anextawaitableobject *obj) +{ + PyObject *result = PyIter_Next(obj->wrapped); + if (result != NULL) { + return result; + } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) { + _PyGen_SetStopIterationValue(obj->default_value); + } + return NULL; +} + +static PyAsyncMethods anextawaitable_as_async = { + PyObject_SelfIter, /* am_await */ + 0, /* am_aiter */ + 0, /* am_anext */ + 0, /* am_send */ +}; + +PyTypeObject PyAnextAwaitable_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "anext_awaitable", /* tp_name */ + sizeof(anextawaitableobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)anextawaitable_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &anextawaitable_as_async, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)anextawaitable_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (unaryfunc)anextawaitable_iternext, /* tp_iternext */ + 0, /* tp_methods */ +}; + +PyObject * +PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value) +{ + anextawaitableobject *anext = PyObject_GC_New( + anextawaitableobject, &PyAnextAwaitable_Type); + if (anext == NULL) { + return NULL; + } + Py_INCREF(awaitable); + anext->wrapped = awaitable; + Py_INCREF(default_value); + anext->default_value = default_value; + _PyObject_GC_TRACK(anext); + return (PyObject *)anext; +} diff --git a/Objects/setobject.c b/Objects/setobject.c index e8912ff1a29d78..caff85c9e38939 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -103,6 +103,7 @@ static int set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) { setentry *table; + setentry *freeslot; setentry *entry; size_t perturb; size_t mask; @@ -118,6 +119,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) mask = so->mask; i = (size_t)hash & mask; + freeslot = NULL; perturb = hash; while (1) { @@ -125,7 +127,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0; do { if (entry->hash == 0 && entry->key == NULL) - goto found_unused; + goto found_unused_or_dummy; if (entry->hash == hash) { PyObject *startkey = entry->key; assert(startkey != dummy); @@ -147,12 +149,24 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) goto restart; mask = so->mask; } + else if (entry->hash == -1) { + assert (entry->key == dummy); + freeslot = entry; + } entry++; } while (probes--); perturb >>= PERTURB_SHIFT; i = (i * 5 + 1 + perturb) & mask; } + found_unused_or_dummy: + if (freeslot == NULL) + goto found_unused; + so->used++; + freeslot->key = key; + freeslot->hash = hash; + return 0; + found_unused: so->fill++; so->used++; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2b6ff59e5fd3ca..d1bbbe77ee1b98 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_call.h" +#include "pycore_compile.h" // _Py_Mangle() #include "pycore_initconfig.h" #include "pycore_object.h" #include "pycore_pyerrors.h" diff --git a/PCbuild/prepare_ssl.py b/PCbuild/prepare_ssl.py index 0f3c63ee24ffba..af4e605338ec19 100755 --- a/PCbuild/prepare_ssl.py +++ b/PCbuild/prepare_ssl.py @@ -25,6 +25,70 @@ import sys import subprocess from shutil import copy +import os +import yaml +from typing import NoReturn + + +def create_directory(directory: str) -> NoReturn: + """ + Create a directory if it doesn't exist. + + Parameters + ---------- + directory : string + A ``string`` of the full directory path to create if it doesn't exist. + """ + if not os.path.exists(directory): + os.makedirs(directory) + + +def update_log(logfile: str, contents: str) -> NoReturn: + """ + Append a log with new output from a test. + + Parameters + ---------- + logfile : string + A ``string`` of the logfile to write data to. + contents : string + A ``string`` of the contents to append the log file with. + """ + with open(logfile, 'a') as log: + log.write(contents) + + +def write_file(filename: str, contents: str) -> NoReturn: + """ + Write data to a file. + + Parameters + ---------- + filename : string + A ``string`` of the file to write data to. + contents : string + A ``string`` of the contents to write to the file. + """ + with open(filename, 'w') as fp: + fp.write(contents) + + +def read_yaml(filename: str) -> dict: + """ + Read a YAML file and return the contents. + + Parameters + ---------- + filename : string + A ``string`` of the full file path to read. + + Returns + ------- + dict + Returns a ``dict`` representing the entire contents of the file. + """ + with open(filename, 'r') as handler: + return yaml.safe_load(handler) # Find all "foo.exe" files on the PATH. def find_all_on_path(filename, extras=None): @@ -71,12 +135,12 @@ def copy_includes(makefile, suffix): os.makedirs(dir) except OSError: pass - copy_if_different = r'$(PERL) $(SRC_D)\util\copy-if-different.pl' with open(makefile) as fin: + copy_if_different = r'$(PERL) $(SRC_D)\util\copy-if-different.pl' for line in fin: if copy_if_different in line: perl, script, src, dest = line.split() - if not '$(INCO_D)' in dest: + if '$(INCO_D)' not in dest: continue # We're in the root of the source tree src = src.replace('$(SRC_D)', '.').strip('"') diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index bab711e6f1b8de..81ac2360cb878b 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -110,11 +110,8 @@ - - - @@ -131,6 +128,7 @@ + @@ -175,6 +173,7 @@ + @@ -184,6 +183,7 @@ + @@ -201,6 +201,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 1f51715eb754d0..8c104bf7b31034 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -42,12 +42,6 @@ Include - - Include - - - Include - Include @@ -210,9 +204,6 @@ Include - - Include - Include @@ -393,6 +384,9 @@ Include\cpython + + Include + Include\cpython @@ -486,6 +480,9 @@ Include\internal + + Include\internal + Include\internal @@ -513,6 +510,9 @@ Include\internal + + Include\internal + Include\internal @@ -564,6 +564,9 @@ Include\internal + + Include\internal + Include\internal diff --git a/PCbuild/regen.vcxproj b/PCbuild/regen.vcxproj index 166468a93bfc3c..ef355a21820a4f 100644 --- a/PCbuild/regen.vcxproj +++ b/PCbuild/regen.vcxproj @@ -139,7 +139,7 @@ - + @@ -163,9 +163,9 @@ - - - + + + @@ -208,7 +208,7 @@ - + diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index aefea12c64857e..3bdeedb394d612 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -362,7 +362,7 @@ def emit(s, depth=0, reflow=True): emit('return NULL;', 2) emit('}', 1) - emit("p = (%s)PyArena_Malloc(arena, sizeof(*p));" % ctype, 1); + emit("p = (%s)_PyArena_Malloc(arena, sizeof(*p));" % ctype, 1); emit("if (!p)", 1) emit("return NULL;", 2) if union: @@ -946,7 +946,7 @@ def visitModule(self, mod): if (obj == Py_None) obj = NULL; if (obj) { - if (PyArena_AddPyObject(arena, obj) < 0) { + if (_PyArena_AddPyObject(arena, obj) < 0) { *out = NULL; return -1; } @@ -958,7 +958,7 @@ def visitModule(self, mod): static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) { - if (PyArena_AddPyObject(arena, obj) < 0) { + if (_PyArena_AddPyObject(arena, obj) < 0) { *out = NULL; return -1; } @@ -1445,13 +1445,12 @@ def generate_module_def(mod, f, internal_h): } """) - # f-string for {mod.name} - f.write(f""" -// Include {mod.name}-ast.h after pycore_interp.h to avoid conflicts -// with the Yield macro redefined by -#include "{mod.name}-ast.h" -#include "structmember.h" -""") + print(textwrap.dedent(""" + // Include pycore_ast.h after pycore_interp.h to avoid conflicts + // with the Yield macro redefined by + #include "pycore_ast.h" + #include "structmember.h" + """).rstrip(), file=f) generate_ast_fini(module_state, f) @@ -1465,33 +1464,49 @@ def generate_module_def(mod, f, internal_h): f.write('};\n\n') def write_header(mod, f): - f.write('#ifndef Py_PYTHON_AST_H\n') - f.write('#define Py_PYTHON_AST_H\n') - f.write('#ifdef __cplusplus\n') - f.write('extern "C" {\n') - f.write('#endif\n') - f.write('\n') - f.write('#ifndef Py_LIMITED_API\n') - f.write('#include "asdl.h"\n') - f.write('\n') - f.write('#undef Yield /* undefine macro conflicting with */\n') - f.write('\n') + f.write(textwrap.dedent(""" + #ifndef Py_INTERNAL_AST_H + #define Py_INTERNAL_AST_H + #ifdef __cplusplus + extern "C" { + #endif + + #ifndef Py_BUILD_CORE + # error "this header requires Py_BUILD_CORE define" + #endif + + #include "pycore_asdl.h" + + #undef Yield /* undefine macro conflicting with */ + + """).lstrip()) c = ChainOfVisitors(TypeDefVisitor(f), SequenceDefVisitor(f), StructVisitor(f)) c.visit(mod) f.write("// Note: these macros affect function definitions, not only call sites.\n") PrototypeVisitor(f).visit(mod) - f.write("\n") - f.write("PyObject* PyAST_mod2obj(mod_ty t);\n") - f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n") - f.write("int PyAST_Check(PyObject* obj);\n") - f.write("#endif /* !Py_LIMITED_API */\n") - f.write('\n') - f.write('#ifdef __cplusplus\n') - f.write('}\n') - f.write('#endif\n') - f.write('#endif /* !Py_PYTHON_AST_H */\n') + f.write(textwrap.dedent(""" + + PyObject* PyAST_mod2obj(mod_ty t); + mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); + int PyAST_Check(PyObject* obj); + + extern int _PyAST_Validate(mod_ty); + + /* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ + extern PyObject* _PyAST_ExprAsUnicode(expr_ty); + + /* Return the borrowed reference to the first literal string in the + sequence of statements or NULL if it doesn't start from a literal string. + Doesn't set exception. */ + extern PyObject* _PyAST_GetDocString(asdl_stmt_seq *); + + #ifdef __cplusplus + } + #endif + #endif /* !Py_INTERNAL_AST_H */ + """)) def write_internal_h_header(mod, f): diff --git a/Parser/parser.c b/Parser/parser.c index 6efaebe179b9c9..de90c87db38e69 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -18285,7 +18285,7 @@ invalid_for_target_rule(Parser *p) return _res; } -// invalid_group: '(' starred_expression ')' +// invalid_group: '(' starred_expression ')' | '(' '**' expression ')' static void * invalid_group_rule(Parser *p) { @@ -18326,6 +18326,39 @@ invalid_group_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' starred_expression ')'")); } + { // '(' '**' expression ')' + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'")); + Token * _literal; + Token * _literal_1; + Token * a; + expr_ty expression_var; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (a = _PyPegen_expect_token(p, 35)) // token='**' + && + (expression_var = expression_rule(p)) // expression + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "can't use double starred expression here" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + D(p->level--); + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_group[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' '**' expression ')'")); + } _res = NULL; done: D(p->level--); diff --git a/Parser/peg_api.c b/Parser/peg_api.c index 1555dea51c2d97..1487ac4ff856c2 100644 --- a/Parser/peg_api.c +++ b/Parser/peg_api.c @@ -4,21 +4,8 @@ #include "pegen.h" mod_ty -PyParser_ASTFromString(const char *str, const char *filename, int mode, - PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - mod_ty result = PyParser_ASTFromStringObject(str, filename_ob, mode, flags, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyParser_ASTFromStringObject(const char *str, PyObject* filename, int mode, - PyCompilerFlags *flags, PyArena *arena) +_PyParser_ASTFromString(const char *str, PyObject* filename, int mode, + PyCompilerFlags *flags, PyArena *arena) { if (PySys_Audit("compile", "yO", str, filename) < 0) { return NULL; @@ -29,37 +16,9 @@ PyParser_ASTFromStringObject(const char *str, PyObject* filename, int mode, } mod_ty -PyParser_ASTFromFilename(const char *filename, int mode, PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_file(filename, mode, filename_ob, flags, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyParser_ASTFromFile(FILE *fp, const char *filename, const char *enc, - int mode, const char *ps1, const char* ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - mod_ty result = PyParser_ASTFromFileObject(fp, filename_ob, enc, mode, - ps1, ps2, flags, errcode, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyParser_ASTFromFileObject(FILE *fp, PyObject *filename_ob, const char *enc, - int mode, const char *ps1, const char* ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) +_PyParser_ASTFromFile(FILE *fp, PyObject *filename_ob, const char *enc, + int mode, const char *ps1, const char* ps2, + PyCompilerFlags *flags, int *errcode, PyArena *arena) { if (PySys_Audit("compile", "OO", Py_None, filename_ob) < 0) { return NULL; diff --git a/Parser/pegen.c b/Parser/pegen.c index 24aa3af336c347..1d23b99dd980c3 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -5,7 +5,6 @@ #include "pegen.h" #include "string_parser.h" -#include "ast.h" PyObject * _PyPegen_new_type_comment(Parser *p, char *s) @@ -14,7 +13,7 @@ _PyPegen_new_type_comment(Parser *p, char *s) if (res == NULL) { return NULL; } - if (PyArena_AddPyObject(p->arena, res) < 0) { + if (_PyArena_AddPyObject(p->arena, res) < 0) { Py_DECREF(res); return NULL; } @@ -122,7 +121,7 @@ _PyPegen_new_identifier(Parser *p, char *n) id = id2; } PyUnicode_InternInPlace(&id); - if (PyArena_AddPyObject(p->arena, id) < 0) + if (_PyArena_AddPyObject(p->arena, id) < 0) { Py_DECREF(id); goto error; @@ -147,7 +146,11 @@ byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) if (!str) { return 0; } - assert(col_offset >= 0 && (unsigned long)col_offset <= strlen(str)); + Py_ssize_t len = strlen(str); + if (col_offset > len) { + col_offset = len; + } + assert(col_offset >= 0); PyObject *text = PyUnicode_DecodeUTF8(str, col_offset, "replace"); if (!text) { return 0; @@ -324,6 +327,7 @@ tokenizer_error(Parser *p) const char *msg = NULL; PyObject* errtype = PyExc_SyntaxError; + Py_ssize_t col_offset = -1; switch (p->tok->done) { case E_TOKEN: msg = "invalid token"; @@ -355,16 +359,14 @@ tokenizer_error(Parser *p) msg = "too many levels of indentation"; break; case E_LINECONT: + col_offset = strlen(strtok(p->tok->buf, "\n")) - 1; msg = "unexpected character after line continuation character"; break; default: msg = "unknown parsing error"; } - PyErr_Format(errtype, msg); - // There is no reliable column information for this error - PyErr_SyntaxLocationObject(p->tok->filename, p->tok->lineno, 0); - + RAISE_ERROR_KNOWN_LOCATION(p, errtype, p->tok->lineno, col_offset, msg); return -1; } @@ -392,10 +394,10 @@ _PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...) static PyObject * get_error_line(Parser *p, Py_ssize_t lineno) { - /* If p->tok->fp == NULL, then we're parsing from a string, which means that - the whole source is stored in p->tok->str. If not, then we're parsing - from the REPL, so the source lines of the current (multi-line) statement - are stored in p->tok->stdin_content */ + /* If the file descriptor is interactive, the source lines of the current + * (multi-line) statement are stored in p->tok->interactive_src_start. + * If not, we're parsing from a string, which means that the whole source + * is stored in p->tok->str. */ assert(p->tok->fp == NULL || p->tok->fp == stdin); char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; @@ -524,7 +526,7 @@ int _PyPegen_insert_memo(Parser *p, int mark, int type, void *node) { // Insert in front - Memo *m = PyArena_Malloc(p->arena, sizeof(Memo)); + Memo *m = _PyArena_Malloc(p->arena, sizeof(Memo)); if (m == NULL) { return -1; } @@ -688,7 +690,7 @@ _PyPegen_fill_token(Parser *p) if (t->bytes == NULL) { return -1; } - PyArena_AddPyObject(p->arena, t->bytes); + _PyArena_AddPyObject(p->arena, t->bytes); int lineno = type == STRING ? p->tok->first_lineno : p->tok->lineno; const char *line_start = type == STRING ? p->tok->multi_line_start : p->tok->line_start; @@ -1027,7 +1029,7 @@ _PyPegen_number_token(Parser *p) return NULL; } - if (PyArena_AddPyObject(p->arena, c) < 0) { + if (_PyArena_AddPyObject(p->arena, c) < 0) { Py_DECREF(c); p->error_indicator = 1; return NULL; @@ -1319,23 +1321,6 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena return result; } -mod_ty -_PyPegen_run_parser_from_file(const char *filename, int start_rule, - PyObject *filename_ob, PyCompilerFlags *flags, PyArena *arena) -{ - FILE *fp = fopen(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_file_pointer(fp, start_rule, filename_ob, - NULL, NULL, NULL, flags, NULL, arena); - - fclose(fp); - return result; -} - mod_ty _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filename_ob, PyCompilerFlags *flags, PyArena *arena) @@ -1524,7 +1509,7 @@ _PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name) return NULL; } PyUnicode_InternInPlace(&uni); - if (PyArena_AddPyObject(p->arena, uni) < 0) { + if (_PyArena_AddPyObject(p->arena, uni) < 0) { Py_DECREF(uni); return NULL; } @@ -1562,7 +1547,7 @@ _PyPegen_alias_for_star(Parser *p) if (!str) { return NULL; } - if (PyArena_AddPyObject(p->arena, str) < 0) { + if (_PyArena_AddPyObject(p->arena, str) < 0) { Py_DECREF(str); return NULL; } @@ -1592,7 +1577,7 @@ CmpopExprPair * _PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr) { assert(expr != NULL); - CmpopExprPair *a = PyArena_Malloc(p->arena, sizeof(CmpopExprPair)); + CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair)); if (!a) { return NULL; } @@ -1733,7 +1718,7 @@ _PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx) KeyValuePair * _PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value) { - KeyValuePair *a = PyArena_Malloc(p->arena, sizeof(KeyValuePair)); + KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair)); if (!a) { return NULL; } @@ -1778,7 +1763,7 @@ _PyPegen_get_values(Parser *p, asdl_seq *seq) NameDefaultPair * _PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc) { - NameDefaultPair *a = PyArena_Malloc(p->arena, sizeof(NameDefaultPair)); + NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair)); if (!a) { return NULL; } @@ -1791,7 +1776,7 @@ _PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc) SlashWithDefault * _PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults) { - SlashWithDefault *a = PyArena_Malloc(p->arena, sizeof(SlashWithDefault)); + SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault)); if (!a) { return NULL; } @@ -1804,7 +1789,7 @@ _PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *name StarEtc * _PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg) { - StarEtc *a = PyArena_Malloc(p->arena, sizeof(StarEtc)); + StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc)); if (!a) { return NULL; } @@ -2040,7 +2025,7 @@ _PyPegen_empty_arguments(Parser *p) AugOperator * _PyPegen_augoperator(Parser *p, operator_ty kind) { - AugOperator *a = PyArena_Malloc(p->arena, sizeof(AugOperator)); + AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator)); if (!a) { return NULL; } @@ -2085,7 +2070,7 @@ _PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty clas KeywordOrStarred * _PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword) { - KeywordOrStarred *a = PyArena_Malloc(p->arena, sizeof(KeywordOrStarred)); + KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred)); if (!a) { return NULL; } @@ -2226,7 +2211,7 @@ _PyPegen_concatenate_strings(Parser *p, asdl_seq *strings) } if (bytesmode) { - if (PyArena_AddPyObject(p->arena, bytes_str) < 0) { + if (_PyArena_AddPyObject(p->arena, bytes_str) < 0) { goto error; } return Constant(bytes_str, NULL, first->lineno, first->col_offset, last->end_lineno, diff --git a/Parser/pegen.h b/Parser/pegen.h index 3765b2425fff7e..af160d6a43d6b0 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -4,7 +4,7 @@ #define PY_SSIZE_T_CLEAN #include #include -#include +#include #if 0 #define PyPARSE_YIELD_IS_KEYWORD 0x0001 @@ -101,7 +101,7 @@ typedef struct { arg_ty kwarg; } StarEtc; -typedef struct { operator_ty kind; } AugOperator; +typedef struct { operator_ty kind; } AugOperator; typedef struct { void *element; int is_keyword; @@ -136,8 +136,9 @@ void *_PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, void *_PyPegen_dummy_name(Parser *p, ...); Py_LOCAL_INLINE(void *) -RAISE_ERROR_KNOWN_LOCATION(Parser *p, PyObject *errtype, int lineno, - int col_offset, const char *errmsg, ...) +RAISE_ERROR_KNOWN_LOCATION(Parser *p, PyObject *errtype, + Py_ssize_t lineno, Py_ssize_t col_offset, + const char *errmsg, ...) { va_list va; va_start(va, errmsg); @@ -226,7 +227,6 @@ void _PyPegen_Parser_Free(Parser *); mod_ty _PyPegen_run_parser_from_file_pointer(FILE *, int, PyObject *, const char *, const char *, const char *, PyCompilerFlags *, int *, PyArena *); void *_PyPegen_run_parser(Parser *); -mod_ty _PyPegen_run_parser_from_file(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); asdl_stmt_seq *_PyPegen_interactive_exit(Parser *); asdl_seq *_PyPegen_singleton_seq(Parser *, void *); diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 0f3665c3453e2e..6a1a3952e72f7e 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -1031,7 +1031,7 @@ make_str_node_and_del(Parser *p, PyObject **str, Token* first_token, Token *last PyObject *kind = NULL; *str = NULL; assert(PyUnicode_CheckExact(s)); - if (PyArena_AddPyObject(p->arena, s) < 0) { + if (_PyArena_AddPyObject(p->arena, s) < 0) { Py_DECREF(s); return NULL; } diff --git a/Parser/string_parser.h b/Parser/string_parser.h index cd85bd57d0a383..4a22f3d3086f47 100644 --- a/Parser/string_parser.h +++ b/Parser/string_parser.h @@ -2,7 +2,7 @@ #define STRINGS_H #include -#include +#include #include "pegen.h" #define EXPRLIST_N_CACHED 64 diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 4524877dd4278e..3c4b0ba8b83c55 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -24,9 +24,9 @@ get_ast_state(void) return state; } -// Include Python-ast.h after pycore_interp.h to avoid conflicts +// Include pycore_ast.h after pycore_interp.h to avoid conflicts // with the Yield macro redefined by -#include "Python-ast.h" +#include "pycore_ast.h" #include "structmember.h" void _PyAST_Fini(PyInterpreterState *interp) @@ -961,7 +961,7 @@ static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyO if (obj == Py_None) obj = NULL; if (obj) { - if (PyArena_AddPyObject(arena, obj) < 0) { + if (_PyArena_AddPyObject(arena, obj) < 0) { *out = NULL; return -1; } @@ -973,7 +973,7 @@ static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyO static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) { - if (PyArena_AddPyObject(arena, obj) < 0) { + if (_PyArena_AddPyObject(arena, obj) < 0) { *out = NULL; return -1; } @@ -1787,7 +1787,7 @@ Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, PyArena *arena) { mod_ty p; - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Module_kind; @@ -1800,7 +1800,7 @@ mod_ty Interactive(asdl_stmt_seq * body, PyArena *arena) { mod_ty p; - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Interactive_kind; @@ -1817,7 +1817,7 @@ Expression(expr_ty body, PyArena *arena) "field 'body' is required for Expression"); return NULL; } - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Expression_kind; @@ -1834,7 +1834,7 @@ FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena) "field 'returns' is required for FunctionType"); return NULL; } - p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = FunctionType_kind; @@ -1860,7 +1860,7 @@ FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, "field 'args' is required for FunctionDef"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = FunctionDef_kind; @@ -1894,7 +1894,7 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, "field 'args' is required for AsyncFunctionDef"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AsyncFunctionDef_kind; @@ -1922,7 +1922,7 @@ ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * keywords, "field 'name' is required for ClassDef"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ClassDef_kind; @@ -1943,7 +1943,7 @@ Return(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Return_kind; @@ -1960,7 +1960,7 @@ Delete(asdl_expr_seq * targets, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Delete_kind; @@ -1982,7 +1982,7 @@ Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int lineno, "field 'value' is required for Assign"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Assign_kind; @@ -2016,7 +2016,7 @@ AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int "field 'value' is required for AugAssign"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AugAssign_kind; @@ -2046,7 +2046,7 @@ AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int "field 'annotation' is required for AnnAssign"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AnnAssign_kind; @@ -2077,7 +2077,7 @@ For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq * orelse, "field 'iter' is required for For"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = For_kind; @@ -2109,7 +2109,7 @@ AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq * "field 'iter' is required for AsyncFor"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AsyncFor_kind; @@ -2135,7 +2135,7 @@ While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int lineno, "field 'test' is required for While"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = While_kind; @@ -2159,7 +2159,7 @@ If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int lineno, int "field 'test' is required for If"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = If_kind; @@ -2178,7 +2178,7 @@ With(asdl_withitem_seq * items, asdl_stmt_seq * body, string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = With_kind; @@ -2198,7 +2198,7 @@ AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string type_comment, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = AsyncWith_kind; @@ -2222,7 +2222,7 @@ Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int col_offset, "field 'subject' is required for Match"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Match_kind; @@ -2240,7 +2240,7 @@ Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Raise_kind; @@ -2259,7 +2259,7 @@ Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, asdl_stmt_seq * end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Try_kind; @@ -2284,7 +2284,7 @@ Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, "field 'test' is required for Assert"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Assert_kind; @@ -2302,7 +2302,7 @@ Import(asdl_alias_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Import_kind; @@ -2319,7 +2319,7 @@ ImportFrom(identifier module, asdl_alias_seq * names, int level, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ImportFrom_kind; @@ -2338,7 +2338,7 @@ Global(asdl_identifier_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Global_kind; @@ -2355,7 +2355,7 @@ Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Nonlocal_kind; @@ -2377,7 +2377,7 @@ Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int "field 'value' is required for Expr"); return NULL; } - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Expr_kind; @@ -2394,7 +2394,7 @@ Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Pass_kind; @@ -2410,7 +2410,7 @@ Break(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Break_kind; @@ -2426,7 +2426,7 @@ Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Continue_kind; @@ -2447,7 +2447,7 @@ BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int col_offset, int "field 'op' is required for BoolOp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = BoolOp_kind; @@ -2475,7 +2475,7 @@ NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int "field 'value' is required for NamedExpr"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = NamedExpr_kind; @@ -2508,7 +2508,7 @@ BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset, "field 'right' is required for BinOp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = BinOp_kind; @@ -2537,7 +2537,7 @@ UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int "field 'operand' is required for UnaryOp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = UnaryOp_kind; @@ -2565,7 +2565,7 @@ Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int "field 'body' is required for Lambda"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Lambda_kind; @@ -2598,7 +2598,7 @@ IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, "field 'orelse' is required for IfExp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = IfExp_kind; @@ -2617,7 +2617,7 @@ Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Dict_kind; @@ -2635,7 +2635,7 @@ Set(asdl_expr_seq * elts, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Set_kind; @@ -2657,7 +2657,7 @@ ListComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int "field 'elt' is required for ListComp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ListComp_kind; @@ -2680,7 +2680,7 @@ SetComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int "field 'elt' is required for SetComp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = SetComp_kind; @@ -2709,7 +2709,7 @@ DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * generators, int "field 'value' is required for DictComp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = DictComp_kind; @@ -2733,7 +2733,7 @@ GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, int "field 'elt' is required for GeneratorExp"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = GeneratorExp_kind; @@ -2756,7 +2756,7 @@ Await(expr_ty value, int lineno, int col_offset, int end_lineno, int "field 'value' is required for Await"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Await_kind; @@ -2773,7 +2773,7 @@ Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Yield_kind; @@ -2795,7 +2795,7 @@ YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int "field 'value' is required for YieldFrom"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = YieldFrom_kind; @@ -2818,7 +2818,7 @@ Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * comparators, int "field 'left' is required for Compare"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Compare_kind; @@ -2842,7 +2842,7 @@ Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * keywords, int "field 'func' is required for Call"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Call_kind; @@ -2867,7 +2867,7 @@ FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, "field 'value' is required for FormattedValue"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = FormattedValue_kind; @@ -2886,7 +2886,7 @@ JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = JoinedStr_kind; @@ -2908,7 +2908,7 @@ Constant(constant value, string kind, int lineno, int col_offset, int "field 'value' is required for Constant"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Constant_kind; @@ -2941,7 +2941,7 @@ Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int "field 'ctx' is required for Attribute"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Attribute_kind; @@ -2975,7 +2975,7 @@ Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int "field 'ctx' is required for Subscript"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Subscript_kind; @@ -3004,7 +3004,7 @@ Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for Starred"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Starred_kind; @@ -3032,7 +3032,7 @@ Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for Name"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Name_kind; @@ -3055,7 +3055,7 @@ List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int "field 'ctx' is required for List"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = List_kind; @@ -3078,7 +3078,7 @@ Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int col_offset, "field 'ctx' is required for Tuple"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Tuple_kind; @@ -3096,7 +3096,7 @@ Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = Slice_kind; @@ -3125,7 +3125,7 @@ MatchAs(expr_ty pattern, identifier name, int lineno, int col_offset, int "field 'name' is required for MatchAs"); return NULL; } - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = MatchAs_kind; @@ -3143,7 +3143,7 @@ MatchOr(asdl_expr_seq * patterns, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) { expr_ty p; - p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = MatchOr_kind; @@ -3170,7 +3170,7 @@ comprehension(expr_ty target, expr_ty iter, asdl_expr_seq * ifs, int is_async, "field 'iter' is required for comprehension"); return NULL; } - p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (comprehension_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->target = target; @@ -3186,7 +3186,7 @@ ExceptHandler(expr_ty type, identifier name, asdl_stmt_seq * body, int lineno, *arena) { excepthandler_ty p; - p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (excepthandler_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = ExceptHandler_kind; @@ -3206,7 +3206,7 @@ arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, arg_ty vararg, asdl_expr_seq * defaults, PyArena *arena) { arguments_ty p; - p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (arguments_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->posonlyargs = posonlyargs; @@ -3229,7 +3229,7 @@ arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int "field 'arg' is required for arg"); return NULL; } - p = (arg_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (arg_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->arg = arg; @@ -3252,7 +3252,7 @@ keyword(identifier arg, expr_ty value, int lineno, int col_offset, int "field 'value' is required for keyword"); return NULL; } - p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (keyword_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->arg = arg; @@ -3273,7 +3273,7 @@ alias(identifier name, identifier asname, PyArena *arena) "field 'name' is required for alias"); return NULL; } - p = (alias_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (alias_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->name = name; @@ -3290,7 +3290,7 @@ withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) "field 'context_expr' is required for withitem"); return NULL; } - p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (withitem_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->context_expr = context_expr; @@ -3307,7 +3307,7 @@ match_case(expr_ty pattern, expr_ty guard, asdl_stmt_seq * body, PyArena *arena) "field 'pattern' is required for match_case"); return NULL; } - p = (match_case_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (match_case_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->pattern = pattern; @@ -3325,7 +3325,7 @@ TypeIgnore(int lineno, string tag, PyArena *arena) "field 'tag' is required for TypeIgnore"); return NULL; } - p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p)); + p = (type_ignore_ty)_PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = TypeIgnore_kind; diff --git a/Python/asdl.c b/Python/asdl.c index 4ff07e4377b18e..a7f2180c88ed35 100644 --- a/Python/asdl.c +++ b/Python/asdl.c @@ -1,5 +1,5 @@ #include "Python.h" -#include "asdl.h" +#include "pycore_asdl.h" GENERATE_ASDL_SEQ_CONSTRUCTOR(generic, void*); GENERATE_ASDL_SEQ_CONSTRUCTOR(identifier, PyObject*); diff --git a/Python/ast.c b/Python/ast.c index 8ac2e60c92fde7..c87795305e507f 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3,8 +3,7 @@ * of the given abstract syntax tree (potentially constructed manually). */ #include "Python.h" -#include "Python-ast.h" -#include "ast.h" +#include "pycore_ast.h" // asdl_stmt_seq #include diff --git a/Python/ast_opt.c b/Python/ast_opt.c index c76b428f97298d..0310466b34f3f0 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -1,6 +1,7 @@ /* AST Optimizer */ #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() +#include "pycore_compile.h" // _PyASTOptimizeState static int @@ -15,7 +16,7 @@ make_const(expr_ty node, PyObject *val, PyArena *arena) PyErr_Clear(); return 1; } - if (PyArena_AddPyObject(arena, val) < 0) { + if (_PyArena_AddPyObject(arena, val) < 0) { Py_DECREF(val); return 0; } diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index a04ff93e9d9d90..5276b2fcd6698b 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -1,7 +1,7 @@ -#include /* DBL_MAX_10_EXP */ -#include #include "Python.h" -#include "Python-ast.h" +#include "pycore_ast.h" // expr_ty +#include // DBL_MAX_10_EXP +#include static PyObject *_str_open_br; static PyObject *_str_dbl_open_br; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 4683103e09437e..a076006d652313 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2,9 +2,9 @@ #include "Python.h" #include -#include "ast.h" -#undef Yield /* undefine macro conflicting with */ #include "pycore_ast.h" // _PyAST_Validate() +#undef Yield /* undefine macro conflicting with */ +#include "pycore_compile.h" // _PyAST_Compile() #include "pycore_object.h" // _Py_AddToAllObjects() #include "pycore_pyerrors.h" // _PyErr_NoMemory() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -828,21 +828,21 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, PyArena *arena; mod_ty mod; - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) goto error; mod = PyAST_obj2mod(source, arena, compile_mode); if (mod == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); goto error; } if (!_PyAST_Validate(mod)) { - PyArena_Free(arena); + _PyArena_Free(arena); goto error; } - result = (PyObject*)PyAST_CompileObject(mod, filename, - &cf, optimize, arena); - PyArena_Free(arena); + result = (PyObject*)_PyAST_Compile(mod, filename, + &cf, optimize, arena); + _PyArena_Free(arena); } goto finally; } @@ -1264,8 +1264,48 @@ map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } lz->iters = iters; func = PyTuple_GET_ITEM(args, 0); - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); + + return (PyObject *)lz; +} + +static PyObject * +map_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + PyTypeObject *tp = (PyTypeObject *)type; + if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs < 2) { + PyErr_SetString(PyExc_TypeError, + "map() must have at least two arguments."); + return NULL; + } + + PyObject *iters = PyTuple_New(nargs-1); + if (iters == NULL) { + return NULL; + } + + for (int i=1; itp_alloc(tp, 0); + if (lz == NULL) { + Py_DECREF(iters); + return NULL; + } + lz->iters = iters; + lz->func = Py_NewRef(args[0]); return (PyObject *)lz; } @@ -1403,6 +1443,7 @@ PyTypeObject PyMap_Type = { PyType_GenericAlloc, /* tp_alloc */ map_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)map_vectorcall }; @@ -1570,6 +1611,62 @@ supply its own iterator, or be a sequence.\n\ In the second form, the callable is called until it returns the sentinel."); +/*[clinic input] +aiter as builtin_aiter + + async_iterable: object + / + +Return an AsyncIterator for an AsyncIterable object. +[clinic start generated code]*/ + +static PyObject * +builtin_aiter(PyObject *module, PyObject *async_iterable) +/*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/ +{ + return PyObject_GetAiter(async_iterable); +} + +PyObject *PyAnextAwaitable_New(PyObject *, PyObject *); + +/*[clinic input] +anext as builtin_anext + + aiterator: object + default: object = NULL + / + +Return the next item from the async iterator. +[clinic start generated code]*/ + +static PyObject * +builtin_anext_impl(PyObject *module, PyObject *aiterator, + PyObject *default_value) +/*[clinic end generated code: output=f02c060c163a81fa input=699d11f4e38eca24]*/ +{ + PyTypeObject *t; + PyObject *awaitable; + + t = Py_TYPE(aiterator); + if (t->tp_as_async == NULL || t->tp_as_async->am_anext == NULL) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not an async iterator", + t->tp_name); + return NULL; + } + + awaitable = (*t->tp_as_async->am_anext)(aiterator); + if (default_value == NULL) { + return awaitable; + } + + PyObject* new_awaitable = PyAnextAwaitable_New( + awaitable, default_value); + Py_DECREF(awaitable); + return new_awaitable; +} + + /*[clinic input] len as builtin_len @@ -2850,11 +2947,13 @@ static PyMethodDef builtin_methods[] = { BUILTIN_ISINSTANCE_METHODDEF BUILTIN_ISSUBCLASS_METHODDEF {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc}, + BUILTIN_AITER_METHODDEF BUILTIN_LEN_METHODDEF BUILTIN_LOCALS_METHODDEF {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc}, + BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF BUILTIN_POW_METHODDEF diff --git a/Python/ceval.c b/Python/ceval.c index 3a37017c000d4a..aef79e1a9db314 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1331,7 +1331,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) TARGET_##op #ifdef LLTRACE -#define FAST_DISPATCH() \ +#define DISPATCH() \ { \ if (!lltrace && !_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \ f->f_lasti = INSTR_OFFSET(); \ @@ -1341,7 +1341,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) goto fast_next_opcode; \ } #else -#define FAST_DISPATCH() \ +#define DISPATCH() \ { \ if (!_Py_TracingPossible(ceval2) && !PyDTrace_LINE_ENABLED()) { \ f->f_lasti = INSTR_OFFSET(); \ @@ -1352,20 +1352,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) } #endif -#define DISPATCH() \ - { \ - if (!_Py_atomic_load_relaxed(eval_breaker)) { \ - FAST_DISPATCH(); \ - } \ - continue; \ - } - #else #define TARGET(op) op -#define FAST_DISPATCH() goto fast_next_opcode -#define DISPATCH() continue +#define DISPATCH() goto fast_next_opcode + #endif +#define CHECK_EVAL_BREAKER() \ + if (_Py_atomic_load_relaxed(eval_breaker)) { \ + continue; \ + } + /* Tuple access macros */ @@ -1857,7 +1854,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) and that all operation that succeed call [FAST_]DISPATCH() ! */ case TARGET(NOP): { - FAST_DISPATCH(); + DISPATCH(); } case TARGET(LOAD_FAST): { @@ -1870,7 +1867,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) } Py_INCREF(value); PUSH(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(LOAD_CONST): { @@ -1878,20 +1875,20 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) PyObject *value = GETITEM(consts, oparg); Py_INCREF(value); PUSH(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(STORE_FAST): { PREDICTED(STORE_FAST); PyObject *value = POP(); SETLOCAL(oparg, value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(POP_TOP): { PyObject *value = POP(); Py_DECREF(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(ROT_TWO): { @@ -1899,7 +1896,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) PyObject *second = SECOND(); SET_TOP(second); SET_SECOND(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(ROT_THREE): { @@ -1909,7 +1906,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) SET_TOP(second); SET_SECOND(third); SET_THIRD(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(ROT_FOUR): { @@ -1921,14 +1918,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) SET_SECOND(third); SET_THIRD(fourth); SET_FOURTH(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(DUP_TOP): { PyObject *top = TOP(); Py_INCREF(top); PUSH(top); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(DUP_TOP_TWO): { @@ -1939,7 +1936,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) STACK_GROW(2); SET_TOP(top); SET_SECOND(second); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(UNARY_POSITIVE): { @@ -2704,7 +2701,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) UNWIND_EXCEPT_HANDLER(b); Py_DECREF(POP()); JUMPBY(oparg); - FAST_DISPATCH(); + DISPATCH(); } else { PyObject *val = POP(); @@ -2718,7 +2715,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) PyObject *value = PyExc_AssertionError; Py_INCREF(value); PUSH(value); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(LOAD_BUILD_CLASS): { @@ -3620,7 +3617,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) Py_DECREF(right); PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(CONTAINS_OP): { @@ -3637,7 +3634,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) PUSH(b); PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); - FAST_DISPATCH(); + DISPATCH(); } #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ @@ -3734,7 +3731,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) case TARGET(JUMP_FORWARD): { JUMPBY(oparg); - FAST_DISPATCH(); + DISPATCH(); } case TARGET(POP_JUMP_IF_FALSE): { @@ -3743,12 +3740,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) int err; if (cond == Py_True) { Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } if (cond == Py_False) { Py_DECREF(cond); JUMPTO(oparg); - FAST_DISPATCH(); + DISPATCH(); } err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -3767,12 +3764,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) int err; if (cond == Py_False) { Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } if (cond == Py_True) { Py_DECREF(cond); JUMPTO(oparg); - FAST_DISPATCH(); + DISPATCH(); } err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -3792,11 +3789,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (cond == Py_True) { STACK_SHRINK(1); Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } if (cond == Py_False) { JUMPTO(oparg); - FAST_DISPATCH(); + DISPATCH(); } err = PyObject_IsTrue(cond); if (err > 0) { @@ -3816,11 +3813,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (cond == Py_False) { STACK_SHRINK(1); Py_DECREF(cond); - FAST_DISPATCH(); + DISPATCH(); } if (cond == Py_True) { JUMPTO(oparg); - FAST_DISPATCH(); + DISPATCH(); } err = PyObject_IsTrue(cond); if (err > 0) { @@ -3838,18 +3835,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) case TARGET(JUMP_ABSOLUTE): { PREDICTED(JUMP_ABSOLUTE); JUMPTO(oparg); -#if FAST_LOOPS - /* Enabling this path speeds-up all while and for-loops by bypassing - the per-loop checks for signals. By default, this should be turned-off - because it prevents detection of a control-break in tight loops like - "while 1: pass". Compile with this option turned-on when you need - the speed-up and do not need break checking inside tight loops (ones - that contain only instructions ending with FAST_DISPATCH). - */ - FAST_DISPATCH(); -#else + CHECK_EVAL_BREAKER(); DISPATCH(); -#endif } case TARGET(GET_LEN): { @@ -4260,6 +4247,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) PUSH(res); if (res == NULL) goto error; + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -4273,6 +4261,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (res == NULL) { goto error; } + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -4292,6 +4281,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (res == NULL) { goto error; } + CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -4338,6 +4328,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) if (result == NULL) { goto error; } + CHECK_EVAL_BREAKER(); DISPATCH(); } diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index bc3b518792811d..545f5b53f6e549 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -530,6 +530,50 @@ PyDoc_STRVAR(builtin_hex__doc__, #define BUILTIN_HEX_METHODDEF \ {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, +PyDoc_STRVAR(builtin_aiter__doc__, +"aiter($module, async_iterable, /)\n" +"--\n" +"\n" +"Return an AsyncIterator for an AsyncIterable object."); + +#define BUILTIN_AITER_METHODDEF \ + {"aiter", (PyCFunction)builtin_aiter, METH_O, builtin_aiter__doc__}, + +PyDoc_STRVAR(builtin_anext__doc__, +"anext($module, aiterator, default=, /)\n" +"--\n" +"\n" +"Return the next item from the async iterator."); + +#define BUILTIN_ANEXT_METHODDEF \ + {"anext", (PyCFunction)(void(*)(void))builtin_anext, METH_FASTCALL, builtin_anext__doc__}, + +static PyObject * +builtin_anext_impl(PyObject *module, PyObject *aiterator, + PyObject *default_value); + +static PyObject * +builtin_anext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *aiterator; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("anext", nargs, 1, 2)) { + goto exit; + } + aiterator = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = builtin_anext_impl(module, aiterator, default_value); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_len__doc__, "len($module, obj, /)\n" "--\n" @@ -830,4 +874,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=e2fcf0201790367c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=da9ae459e9233259 input=a9049054013a1b77]*/ diff --git a/Python/compile.c b/Python/compile.c index 27274ec884dc3f..bed2a1c944d962 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1,7 +1,7 @@ /* * This file compiles an abstract syntax tree (AST) into Python bytecode. * - * The primary entry point is PyAST_Compile(), which returns a + * The primary entry point is _PyAST_Compile(), which returns a * PyCodeObject. The compiler makes several passes to build the code * object: * 1. Checks for future statements. See future.c @@ -23,6 +23,7 @@ #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() +#include "pycore_compile.h" // _PyFuture_FromAST() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_symtable.h" // PySTEntryObject @@ -350,8 +351,8 @@ compiler_init(struct compiler *c) } PyCodeObject * -PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, - int optimize, PyArena *arena) +_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, + int optimize, PyArena *arena) { struct compiler c; PyCodeObject *co = NULL; @@ -373,7 +374,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, Py_INCREF(filename); c.c_filename = filename; c.c_arena = arena; - c.c_future = PyFuture_FromASTObject(mod, filename); + c.c_future = _PyFuture_FromAST(mod, filename); if (c.c_future == NULL) goto finally; if (!flags) { @@ -409,21 +410,6 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, return co; } -PyCodeObject * -PyAST_CompileEx(mod_ty mod, const char *filename_str, PyCompilerFlags *flags, - int optimize, PyArena *arena) -{ - PyObject *filename; - PyCodeObject *co; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - co = PyAST_CompileObject(mod, filename, flags, optimize, arena); - Py_DECREF(filename); - return co; - -} - static void compiler_free(struct compiler *c) { @@ -6758,15 +6744,6 @@ assemble(struct compiler *c, int addNone) return co; } -#undef PyAST_Compile -PyCodeObject * -PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, - PyArena *arena) -{ - return PyAST_CompileEx(mod, filename, flags, -1, arena); -} - - /* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n with LOAD_CONST (c1, c2, ... cn). The consts table must still be in list form so that the diff --git a/Python/dtoa.c b/Python/dtoa.c index c7002e5d86d51b..e629b296426f31 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -119,16 +119,6 @@ #include "Python.h" #include "pycore_dtoa.h" -#include "pycore_interp.h" -#include "pycore_pystate.h" - -#define ULong _PyDtoa_ULong -#define Long _PyDtoa_Long -#define ULLong _PyDtoa_ULLong -#define Kmax _PyDtoa_Kmax - -typedef struct _PyDtoa_Bigint Bigint; - /* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile the following code */ @@ -164,6 +154,11 @@ typedef struct _PyDtoa_Bigint Bigint; #error "doubles and ints have incompatible endianness" #endif + +typedef uint32_t ULong; +typedef int32_t Long; +typedef uint64_t ULLong; + #undef DEBUG #ifdef Py_DEBUG #define DEBUG @@ -302,6 +297,8 @@ BCinfo { #define FFFFFFFF 0xffffffffUL +#define Kmax 7 + /* struct Bigint is used to represent arbitrary-precision integers. These integers are stored in sign-magnitude format, with the magnitude stored as an array of base 2**32 digits. Bigints are always normalized: if x is a @@ -324,6 +321,14 @@ BCinfo { significant (x[0]) to most significant (x[wds-1]). */ +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +typedef struct Bigint Bigint; #ifndef Py_USING_MEMORY_DEBUGGER @@ -346,13 +351,7 @@ BCinfo { Bfree to PyMem_Free. Investigate whether this has any significant performance on impact. */ - -/* Get Bigint freelist from interpreter */ -static Bigint ** -get_freelist(void) { - PyInterpreterState *interp = _PyInterpreterState_GET(); - return interp->dtoa_freelist; -} +static Bigint *freelist[Kmax+1]; /* Allocate space for a Bigint with up to 1<next; else { @@ -394,7 +393,6 @@ Bfree(Bigint *v) if (v->k > Kmax) FREE((void*)v); else { - Bigint **freelist = get_freelist(); v->next = freelist[v->k]; freelist[v->k] = v; } diff --git a/Python/future.c b/Python/future.c index 37e7a22f81c2bb..05ade8e250ab33 100644 --- a/Python/future.c +++ b/Python/future.c @@ -116,7 +116,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) PyFutureFeatures * -PyFuture_FromASTObject(mod_ty mod, PyObject *filename) +_PyFuture_FromAST(mod_ty mod, PyObject *filename) { PyFutureFeatures *ff; @@ -134,18 +134,3 @@ PyFuture_FromASTObject(mod_ty mod, PyObject *filename) } return ff; } - - -PyFutureFeatures * -PyFuture_FromAST(mod_ty mod, const char *filename_str) -{ - PyFutureFeatures *ff; - PyObject *filename; - - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - ff = PyFuture_FromASTObject(mod, filename); - Py_DECREF(filename); - return ff; -} diff --git a/Python/import.c b/Python/import.c index d92e46aa670cbd..6fba057baddeb4 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2,7 +2,6 @@ #include "Python.h" -#include "Python-ast.h" #undef Yield /* undefine macro conflicting with */ #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" @@ -1744,26 +1743,29 @@ PyImport_ReloadModule(PyObject *m) PyObject * PyImport_Import(PyObject *module_name) { + _Py_IDENTIFIER(__import__); + _Py_IDENTIFIER(__builtins__); + PyThreadState *tstate = _PyThreadState_GET(); - static PyObject *silly_list = NULL; - static PyObject *builtins_str = NULL; - static PyObject *import_str = NULL; PyObject *globals = NULL; PyObject *import = NULL; PyObject *builtins = NULL; PyObject *r = NULL; /* Initialize constant string objects */ - if (silly_list == NULL) { - import_str = PyUnicode_InternFromString("__import__"); - if (import_str == NULL) - return NULL; - builtins_str = PyUnicode_InternFromString("__builtins__"); - if (builtins_str == NULL) - return NULL; - silly_list = PyList_New(0); - if (silly_list == NULL) - return NULL; + PyObject *import_str = _PyUnicode_FromId(&PyId___import__); // borrowed ref + if (import_str == NULL) { + return NULL; + } + + PyObject *builtins_str = _PyUnicode_FromId(&PyId___builtins__); // borrowed ref + if (builtins_str == NULL) { + return NULL; + } + + PyObject *from_list = PyList_New(0); + if (from_list == NULL) { + goto err; } /* Get the builtins from current globals */ @@ -1778,8 +1780,9 @@ PyImport_Import(PyObject *module_name) /* No globals -- use standard builtins, and fake globals */ builtins = PyImport_ImportModuleLevel("builtins", NULL, NULL, NULL, 0); - if (builtins == NULL) - return NULL; + if (builtins == NULL) { + goto err; + } globals = Py_BuildValue("{OO}", builtins_str, builtins); if (globals == NULL) goto err; @@ -1801,7 +1804,7 @@ PyImport_Import(PyObject *module_name) Always use absolute import here. Calling for side-effect of import. */ r = PyObject_CallFunction(import, "OOOOi", module_name, globals, - globals, silly_list, 0, NULL); + globals, from_list, 0, NULL); if (r == NULL) goto err; Py_DECREF(r); @@ -1815,6 +1818,7 @@ PyImport_Import(PyObject *module_name) Py_XDECREF(globals); Py_XDECREF(builtins); Py_XDECREF(import); + Py_XDECREF(from_list); return r; } diff --git a/Python/importlib.h b/Python/importlib.h index 90cfa4cc2daed1..633c642a1401ff 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -492,67 +492,68 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 124,1,116,4,106,5,118,0,114,66,116,4,106,5,124,1, 25,0,125,4,116,6,124,3,124,4,131,2,1,0,116,4, 106,5,124,1,25,0,83,0,116,7,124,3,131,1,83,0, - 41,3,122,128,76,111,97,100,32,116,104,101,32,115,112,101, + 41,3,122,130,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,122,103,116,104,101,32,108,111,97,100,95,109, - 111,100,117,108,101,40,41,32,109,101,116,104,111,100,32,105, - 115,32,100,101,112,114,101,99,97,116,101,100,32,97,110,100, - 32,115,108,97,116,101,100,32,102,111,114,32,114,101,109,111, - 118,97,108,32,105,110,32,80,121,116,104,111,110,32,51,46, - 49,50,59,32,117,115,101,32,101,120,101,99,95,109,111,100, - 117,108,101,40,41,32,105,110,115,116,101,97,100,78,41,8, - 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,16,115,112,101,99,95,102,114,111,109, - 95,108,111,97,100,101,114,114,18,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,5,114,33,0,0,0,114,89,0,0,0,218, - 3,109,115,103,218,4,115,112,101,99,218,6,109,111,100,117, - 108,101,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,218,17,95,108,111,97,100,95,109,111,100,117,108,101,95, - 115,104,105,109,19,1,0,0,115,18,0,0,0,4,6,12, - 2,10,1,10,1,10,1,10,1,10,1,8,2,255,128,114, - 111,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,206,0, - 0,0,116,0,124,0,100,1,100,0,131,3,125,1,116,1, - 124,1,100,2,131,2,114,50,122,12,124,1,160,2,124,0, - 161,1,87,0,83,0,4,0,116,3,121,204,1,0,1,0, - 1,0,89,0,122,10,124,0,106,4,125,2,87,0,110,16, - 4,0,116,5,121,202,1,0,1,0,1,0,89,0,110,16, - 124,2,100,0,117,1,114,94,116,6,124,2,131,1,83,0, - 122,10,124,0,106,7,125,3,87,0,110,18,4,0,116,5, - 121,200,1,0,1,0,1,0,100,3,125,3,89,0,122,10, - 124,0,106,8,125,4,87,0,110,50,4,0,116,5,121,198, - 1,0,1,0,1,0,124,1,100,0,117,0,114,170,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,100,6,160,9, - 124,3,124,4,161,2,83,0,119,0,119,0,119,0,119,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, - 13,0,0,0,114,11,0,0,0,114,113,0,0,0,218,9, - 69,120,99,101,112,116,105,111,110,218,8,95,95,115,112,101, - 99,95,95,114,2,0,0,0,218,22,95,109,111,100,117,108, + 111,100,117,108,101,40,41,32,105,110,115,116,101,97,100,46, + 10,10,32,32,32,32,122,103,116,104,101,32,108,111,97,100, + 95,109,111,100,117,108,101,40,41,32,109,101,116,104,111,100, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,97, + 110,100,32,115,108,97,116,101,100,32,102,111,114,32,114,101, + 109,111,118,97,108,32,105,110,32,80,121,116,104,111,110,32, + 51,46,49,50,59,32,117,115,101,32,101,120,101,99,95,109, + 111,100,117,108,101,40,41,32,105,110,115,116,101,97,100,78, + 41,8,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,16,115,112,101,99,95,102,114, + 111,109,95,108,111,97,100,101,114,114,18,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,5,114,33,0,0,0,114,89,0,0, + 0,218,3,109,115,103,218,4,115,112,101,99,218,6,109,111, + 100,117,108,101,114,5,0,0,0,114,5,0,0,0,114,6, + 0,0,0,218,17,95,108,111,97,100,95,109,111,100,117,108, + 101,95,115,104,105,109,19,1,0,0,115,18,0,0,0,4, + 6,12,2,10,1,10,1,10,1,10,1,10,1,8,2,255, + 128,114,111,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, + 184,0,0,0,116,0,124,0,100,1,100,2,131,3,125,1, + 116,0,124,0,100,3,100,2,131,3,4,0,125,2,114,36, + 116,1,124,2,131,1,83,0,116,2,124,1,100,4,131,2, + 114,74,122,12,124,1,160,3,124,0,161,1,87,0,83,0, + 4,0,116,4,121,182,1,0,1,0,1,0,89,0,122,10, + 124,0,106,5,125,3,87,0,110,18,4,0,116,6,121,180, + 1,0,1,0,1,0,100,5,125,3,89,0,122,10,124,0, + 106,7,125,4,87,0,110,50,4,0,116,6,121,178,1,0, + 1,0,1,0,124,1,100,2,117,0,114,150,100,6,160,8, + 124,3,161,1,6,0,89,0,83,0,100,7,160,8,124,3, + 124,1,161,2,6,0,89,0,83,0,100,8,160,8,124,3, + 124,4,161,2,83,0,119,0,119,0,119,0,41,9,122,44, + 84,104,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,77,111,100,117,108,101,84,121,112,101, + 46,95,95,114,101,112,114,95,95,40,41,46,218,10,95,95, + 108,111,97,100,101,114,95,95,78,218,8,95,95,115,112,101, + 99,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,9,114,13,0,0,0,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,9,0,0,0,218,8,95,95,102,105,108,101,95,95,114, - 50,0,0,0,41,5,114,110,0,0,0,218,6,108,111,97, - 100,101,114,114,109,0,0,0,114,20,0,0,0,218,8,102, - 105,108,101,110,97,109,101,114,5,0,0,0,114,5,0,0, - 0,114,6,0,0,0,218,12,95,109,111,100,117,108,101,95, - 114,101,112,114,38,1,0,0,115,56,0,0,0,12,2,10, - 1,2,4,12,1,12,1,2,1,2,1,10,1,12,1,4, - 1,8,2,8,1,2,4,10,1,12,1,6,1,2,1,10, - 1,12,1,8,1,14,1,16,2,12,2,2,250,2,252,2, - 246,2,252,255,128,114,124,0,0,0,99,0,0,0,0,0, + 114,11,0,0,0,114,114,0,0,0,218,9,69,120,99,101, + 112,116,105,111,110,114,9,0,0,0,114,2,0,0,0,218, + 8,95,95,102,105,108,101,95,95,114,50,0,0,0,41,5, + 114,110,0,0,0,218,6,108,111,97,100,101,114,114,109,0, + 0,0,114,20,0,0,0,218,8,102,105,108,101,110,97,109, + 101,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, + 218,12,95,109,111,100,117,108,101,95,114,101,112,114,38,1, + 0,0,115,46,0,0,0,12,2,16,1,8,1,10,1,2, + 1,12,1,12,1,2,1,2,4,10,1,12,1,6,1,2, + 1,10,1,12,1,8,1,14,1,16,2,12,2,2,250,2, + 252,2,249,255,128,114,124,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, @@ -671,7 +672,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 99,104,101,100,41,6,114,33,0,0,0,114,20,0,0,0, 114,122,0,0,0,114,126,0,0,0,114,127,0,0,0,114, 128,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,34,0,0,0,111,1,0,0,115,16,0,0, + 0,0,0,114,34,0,0,0,103,1,0,0,115,16,0,0, 0,6,2,6,1,6,1,6,1,14,1,6,3,10,1,255, 128,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,0, @@ -693,7 +694,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 218,9,95,95,99,108,97,115,115,95,95,114,9,0,0,0, 218,4,106,111,105,110,41,2,114,33,0,0,0,114,62,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,53,0,0,0,123,1,0,0,115,22,0,0,0,10, + 0,114,53,0,0,0,115,1,0,0,115,22,0,0,0,10, 1,10,1,4,255,10,2,18,1,10,1,6,1,8,1,4, 255,22,2,255,128,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, @@ -711,7 +712,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 2,0,0,0,218,14,78,111,116,73,109,112,108,101,109,101, 110,116,101,100,41,3,114,33,0,0,0,90,5,111,116,104, 101,114,90,4,115,109,115,108,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,218,6,95,95,101,113,95,95,133, + 0,0,114,6,0,0,0,218,6,95,95,101,113,95,95,125, 1,0,0,115,34,0,0,0,6,1,2,1,12,1,10,1, 2,255,10,2,2,254,8,3,2,253,10,4,2,252,10,5, 4,251,12,6,8,1,2,255,255,128,122,17,77,111,100,117, @@ -727,7 +728,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,52,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,6,0,0,0,114,135,0,0,0,145,1,0,0,115, + 0,114,6,0,0,0,114,135,0,0,0,137,1,0,0,115, 14,0,0,0,10,2,16,1,8,1,4,1,14,1,6,1, 255,128,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, @@ -735,7 +736,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,124,1,124,0,95,0,100,0,83,0,114,0,0, 0,0,41,1,114,131,0,0,0,41,2,114,33,0,0,0, 114,135,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 6,0,0,0,114,135,0,0,0,154,1,0,0,115,4,0, + 6,0,0,0,114,135,0,0,0,146,1,0,0,115,4,0, 0,0,10,2,255,128,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, 32,0,0,0,124,0,106,0,100,1,117,0,114,26,124,0, @@ -746,14 +747,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,41,3,114,129,0,0,0,114,20,0,0,0,218,10,114, 112,97,114,116,105,116,105,111,110,114,52,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,6,0,0,0,218,6,112, - 97,114,101,110,116,158,1,0,0,115,8,0,0,0,10,3, + 97,114,101,110,116,150,1,0,0,115,8,0,0,0,10,3, 16,1,6,2,255,128,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,0,0, 0,0,41,1,114,130,0,0,0,114,52,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,6,0,0,0,114,136,0, - 0,0,166,1,0,0,115,4,0,0,0,6,2,255,128,122, + 0,0,158,1,0,0,115,4,0,0,0,6,2,255,128,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, @@ -761,14 +762,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 100,0,83,0,114,0,0,0,0,41,2,218,4,98,111,111, 108,114,130,0,0,0,41,2,114,33,0,0,0,218,5,118, 97,108,117,101,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,136,0,0,0,170,1,0,0,115,4,0,0, + 0,0,0,114,136,0,0,0,162,1,0,0,115,4,0,0, 0,14,2,255,128,41,12,114,9,0,0,0,114,8,0,0, 0,114,1,0,0,0,114,10,0,0,0,114,34,0,0,0, 114,53,0,0,0,114,138,0,0,0,218,8,112,114,111,112, 101,114,116,121,114,135,0,0,0,218,6,115,101,116,116,101, 114,114,143,0,0,0,114,136,0,0,0,114,5,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,114, - 125,0,0,0,74,1,0,0,115,36,0,0,0,8,0,4, + 125,0,0,0,66,1,0,0,115,36,0,0,0,8,0,4, 1,4,36,2,1,12,255,8,12,8,10,2,12,10,1,4, 8,10,1,2,3,10,1,2,7,10,1,4,3,14,1,255, 128,114,125,0,0,0,169,2,114,126,0,0,0,114,128,0, @@ -796,7 +797,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,125,0,0,0,41,6,114,20,0,0,0,114,122,0,0, 0,114,126,0,0,0,114,128,0,0,0,114,149,0,0,0, 90,6,115,101,97,114,99,104,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,104,0,0,0,175,1,0,0, + 0,0,114,6,0,0,0,114,104,0,0,0,167,1,0,0, 115,40,0,0,0,10,2,8,1,4,1,6,1,8,2,12, 1,12,1,6,1,2,1,6,255,8,3,10,1,2,1,14, 1,12,1,8,1,4,3,16,2,2,250,255,128,114,104,0, @@ -821,7 +822,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 117,0,144,1,114,10,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, 119,0,119,0,119,0,119,0,119,0,119,0,41,4,78,169, - 1,114,126,0,0,0,70,84,41,13,114,119,0,0,0,114, + 1,114,126,0,0,0,70,84,41,13,114,113,0,0,0,114, 2,0,0,0,114,9,0,0,0,114,112,0,0,0,114,121, 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, @@ -831,7 +832,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,20,0,0,0,90,8,108,111,99,97,116,105,111, 110,114,135,0,0,0,114,129,0,0,0,114,5,0,0,0, 114,5,0,0,0,114,6,0,0,0,218,17,95,115,112,101, - 99,95,102,114,111,109,95,109,111,100,117,108,101,201,1,0, + 99,95,102,114,111,109,95,109,111,100,117,108,101,193,1,0, 0,115,86,0,0,0,2,2,10,1,14,1,4,1,8,2, 4,1,6,2,8,1,2,1,10,1,14,1,2,2,2,1, 10,1,14,1,6,1,8,1,8,1,2,1,10,1,14,1, @@ -878,13 +879,13 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,121,0,0,0,114,112,0,0,0,114,143,0, - 0,0,114,158,0,0,0,114,119,0,0,0,114,154,0,0, + 0,0,114,158,0,0,0,114,113,0,0,0,114,154,0,0, 0,114,136,0,0,0,114,126,0,0,0,114,135,0,0,0, 114,152,0,0,0,41,5,114,109,0,0,0,114,110,0,0, 0,114,157,0,0,0,114,122,0,0,0,114,159,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, 18,95,105,110,105,116,95,109,111,100,117,108,101,95,97,116, - 116,114,115,246,1,0,0,115,114,0,0,0,20,4,2,1, + 116,114,115,238,1,0,0,115,114,0,0,0,20,4,2,1, 12,1,14,1,2,1,20,2,6,1,8,1,10,2,8,1, 4,1,6,1,10,2,8,1,6,1,6,11,2,1,10,1, 14,1,2,1,20,2,2,1,12,1,14,1,2,1,2,2, @@ -913,7 +914,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,114,161,0,0,0,169,2,114,109,0,0,0,114, 110,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, 0,0,0,218,16,109,111,100,117,108,101,95,102,114,111,109, - 95,115,112,101,99,62,2,0,0,115,20,0,0,0,4,3, + 95,115,112,101,99,54,2,0,0,115,20,0,0,0,4,3, 12,1,14,3,12,1,8,1,8,2,10,1,10,1,4,1, 255,128,114,165,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, @@ -926,15 +927,15 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,124,0,106,1,161,2,83,0,41,7,122,38,82,101,116, 117,114,110,32,116,104,101,32,114,101,112,114,32,116,111,32, 117,115,101,32,102,111,114,32,116,104,101,32,109,111,100,117, - 108,101,46,78,114,114,0,0,0,114,115,0,0,0,114,116, - 0,0,0,114,117,0,0,0,250,18,60,109,111,100,117,108, + 108,101,46,78,114,115,0,0,0,114,116,0,0,0,114,117, + 0,0,0,114,118,0,0,0,250,18,60,109,111,100,117,108, 101,32,123,33,114,125,32,40,123,125,41,62,41,5,114,20, 0,0,0,114,126,0,0,0,114,122,0,0,0,114,50,0, 0,0,114,136,0,0,0,41,2,114,109,0,0,0,114,20, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,114,120,0,0,0,79,2,0,0,115,18,0,0,0, + 0,0,114,119,0,0,0,71,2,0,0,115,18,0,0,0, 20,3,10,1,10,1,10,1,14,2,6,2,14,1,16,2, - 255,128,114,120,0,0,0,99,2,0,0,0,0,0,0,0, + 255,128,114,119,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,26,1,0,0,124,0,106,0,125,2,116,1,124,2,131, 1,143,246,1,0,116,2,106,3,160,4,124,2,161,1,124, @@ -975,7 +976,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 95,109,111,100,117,108,101,114,163,0,0,0,218,3,112,111, 112,41,4,114,109,0,0,0,114,110,0,0,0,114,20,0, 0,0,114,108,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,6,0,0,0,114,106,0,0,0,96,2,0,0,115, + 0,114,6,0,0,0,114,106,0,0,0,88,2,0,0,115, 50,0,0,0,6,2,10,1,16,1,10,1,12,1,2,1, 10,1,10,1,14,1,16,2,14,2,12,1,16,1,12,2, 14,1,12,2,2,128,14,4,14,1,14,255,26,1,4,1, @@ -1000,15 +1001,15 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 8,144,1,121,12,1,0,1,0,1,0,89,0,124,1,83, 0,124,1,83,0,119,0,119,0,119,0,41,7,78,114,112, 0,0,0,114,158,0,0,0,114,154,0,0,0,114,141,0, - 0,0,114,25,0,0,0,114,119,0,0,0,41,14,114,122, + 0,0,114,25,0,0,0,114,113,0,0,0,41,14,114,122, 0,0,0,114,170,0,0,0,114,20,0,0,0,114,18,0, 0,0,114,105,0,0,0,114,171,0,0,0,114,13,0,0, 0,114,112,0,0,0,114,2,0,0,0,114,9,0,0,0, 114,158,0,0,0,114,11,0,0,0,114,142,0,0,0,114, - 119,0,0,0,114,164,0,0,0,114,5,0,0,0,114,5, + 113,0,0,0,114,164,0,0,0,114,5,0,0,0,114,5, 0,0,0,114,6,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,126,2,0,0,115,66,0,0,0,2,3,18,1, + 98,108,101,118,2,0,0,115,66,0,0,0,2,3,18,1, 6,1,12,1,14,1,12,1,2,1,14,3,12,1,16,1, 2,1,12,1,14,1,2,1,16,1,2,1,8,4,10,1, 18,1,4,128,14,1,2,1,18,1,2,1,8,1,4,3, @@ -1042,7 +1043,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,114,83,0,0,0,41,3,114,109,0,0,0,114,108,0, 0,0,114,110,0,0,0,114,5,0,0,0,114,5,0,0, 0,114,6,0,0,0,218,14,95,108,111,97,100,95,117,110, - 108,111,99,107,101,100,162,2,0,0,115,62,0,0,0,10, + 108,111,99,107,101,100,154,2,0,0,115,62,0,0,0,10, 2,12,2,16,1,12,2,8,1,8,2,6,5,2,1,12, 1,2,1,10,1,10,1,14,1,2,255,12,4,4,128,6, 1,2,1,12,1,2,3,12,254,2,1,2,1,14,5,12, @@ -1067,7 +1068,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 101,100,46,10,10,32,32,32,32,78,41,3,114,57,0,0, 0,114,20,0,0,0,114,173,0,0,0,169,1,114,109,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,107,0,0,0,207,2,0,0,115,8,0,0,0,12, + 0,114,107,0,0,0,199,2,0,0,115,8,0,0,0,12, 9,22,1,20,128,255,128,114,107,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,140,0,0,0,101,0,90,1,100,0, @@ -1104,7 +1105,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 122,8,60,109,111,100,117,108,101,32,122,2,32,40,122,2, 41,62,78,41,3,114,9,0,0,0,114,175,0,0,0,114, 151,0,0,0,169,1,114,110,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,114,113,0,0,0,233, + 114,5,0,0,0,114,6,0,0,0,114,114,0,0,0,225, 2,0,0,115,4,0,0,0,22,7,255,128,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, @@ -1117,7 +1118,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,151,0,0,0,169,4,218,3,99,108,115,114,89, 0,0,0,218,4,112,97,116,104,218,6,116,97,114,103,101, 116,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, - 218,9,102,105,110,100,95,115,112,101,99,242,2,0,0,115, + 218,9,102,105,110,100,95,115,112,101,99,234,2,0,0,115, 12,0,0,0,8,2,4,1,10,1,16,1,4,2,255,128, 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, @@ -1139,7 +1140,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,122,0,0,0,41,4,114,180,0,0,0,114,89, 0,0,0,114,181,0,0,0,114,109,0,0,0,114,5,0, 0,0,114,5,0,0,0,114,6,0,0,0,218,11,102,105, - 110,100,95,109,111,100,117,108,101,251,2,0,0,115,6,0, + 110,100,95,109,111,100,117,108,101,243,2,0,0,115,6,0, 0,0,12,9,18,1,255,128,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,1,0,0,0,0,0,0,0,0,0, @@ -1154,7 +1155,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,114,74,0,0,0,114,64,0,0,0,90,14,99, 114,101,97,116,101,95,98,117,105,108,116,105,110,114,174,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,162,0,0,0,7,3,0,0,115,12,0,0,0,12, + 0,114,162,0,0,0,255,2,0,0,115,12,0,0,0,12, 3,12,1,4,1,6,255,12,2,255,128,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,1,0,0,0,0, @@ -1165,7 +1166,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 108,101,78,41,3,114,74,0,0,0,114,64,0,0,0,90, 12,101,120,101,99,95,98,117,105,108,116,105,110,114,177,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,163,0,0,0,15,3,0,0,115,4,0,0,0,16, + 0,114,163,0,0,0,7,3,0,0,115,4,0,0,0,16, 3,255,128,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, @@ -1176,7 +1177,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 101,32,99,111,100,101,32,111,98,106,101,99,116,115,46,78, 114,5,0,0,0,169,2,114,180,0,0,0,114,89,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, - 218,8,103,101,116,95,99,111,100,101,20,3,0,0,243,4, + 218,8,103,101,116,95,99,111,100,101,12,3,0,0,243,4, 0,0,0,4,4,255,128,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, @@ -1187,7 +1188,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 111,117,114,99,101,32,99,111,100,101,46,78,114,5,0,0, 0,114,186,0,0,0,114,5,0,0,0,114,5,0,0,0, 114,6,0,0,0,218,10,103,101,116,95,115,111,117,114,99, - 101,26,3,0,0,114,188,0,0,0,122,26,66,117,105,108, + 101,18,3,0,0,114,188,0,0,0,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,0, 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,114, @@ -1196,18 +1197,18 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,78,114,5, 0,0,0,114,186,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,128,0,0,0,32,3,0,0, + 0,0,114,6,0,0,0,114,128,0,0,0,24,3,0,0, 114,188,0,0,0,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,18,114,9,0,0,0,114, 8,0,0,0,114,1,0,0,0,114,10,0,0,0,114,151, 0,0,0,218,12,115,116,97,116,105,99,109,101,116,104,111, - 100,114,113,0,0,0,218,11,99,108,97,115,115,109,101,116, + 100,114,114,0,0,0,218,11,99,108,97,115,115,109,101,116, 104,111,100,114,183,0,0,0,114,184,0,0,0,114,162,0, 0,0,114,163,0,0,0,114,95,0,0,0,114,187,0,0, 0,114,189,0,0,0,114,128,0,0,0,114,111,0,0,0, 114,170,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,114,175,0,0,0,222,2, + 5,0,0,0,114,6,0,0,0,114,175,0,0,0,214,2, 0,0,115,48,0,0,0,8,0,4,2,4,7,2,2,10, 1,2,8,12,1,2,8,12,1,2,11,10,1,2,7,10, 1,2,4,2,1,12,1,2,4,2,1,12,1,2,4,2, @@ -1239,7 +1240,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 83,0,41,3,114,176,0,0,0,114,166,0,0,0,78,41, 4,114,50,0,0,0,114,9,0,0,0,114,192,0,0,0, 114,151,0,0,0,41,1,218,1,109,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,114,113,0,0,0,52,3, + 5,0,0,0,114,6,0,0,0,114,114,0,0,0,44,3, 0,0,115,4,0,0,0,16,7,255,128,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, @@ -1249,7 +1250,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 100,0,83,0,114,178,0,0,0,41,4,114,64,0,0,0, 114,98,0,0,0,114,104,0,0,0,114,151,0,0,0,114, 179,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,183,0,0,0,61,3,0,0,115,8,0,0, + 0,0,0,114,183,0,0,0,53,3,0,0,115,8,0,0, 0,10,2,16,1,4,2,255,128,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,0,0,0,0, @@ -1264,7 +1265,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 32,32,32,32,78,41,2,114,64,0,0,0,114,98,0,0, 0,41,3,114,180,0,0,0,114,89,0,0,0,114,181,0, 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,184,0,0,0,68,3,0,0,115,4,0,0,0,18, + 0,114,184,0,0,0,60,3,0,0,115,4,0,0,0,18, 7,255,128,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, 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, @@ -1273,7 +1274,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,5,0,0, 0,114,174,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,6,0,0,0,114,162,0,0,0,77,3,0,0,115,4, + 114,6,0,0,0,114,162,0,0,0,69,3,0,0,115,4, 0,0,0,4,0,255,128,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, @@ -1282,14 +1283,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,97,0,0,0,41,10,114,119,0,0,0,114, + 0,83,0,114,97,0,0,0,41,10,114,113,0,0,0,114, 20,0,0,0,114,64,0,0,0,114,98,0,0,0,114,87, 0,0,0,114,50,0,0,0,114,74,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,14,0,0,0,41,3,114,110,0, 0,0,114,20,0,0,0,218,4,99,111,100,101,114,5,0, 0,0,114,5,0,0,0,114,6,0,0,0,114,163,0,0, - 0,81,3,0,0,115,16,0,0,0,8,2,10,1,10,1, + 0,73,3,0,0,115,16,0,0,0,8,2,10,1,10,1, 2,1,6,255,12,2,16,1,255,128,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, @@ -1303,7 +1304,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 110,115,116,101,97,100,46,10,10,32,32,32,32,32,32,32, 32,78,41,1,114,111,0,0,0,114,186,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,6,0,0,0,114,170,0, - 0,0,90,3,0,0,115,4,0,0,0,10,8,255,128,122, + 0,0,82,3,0,0,115,4,0,0,0,10,8,255,128,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,0,0,0,0,2,0,0,0,3,0,0,0, @@ -1313,7 +1314,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,32,116,104,101,32,102,114,111,122,101,110,32,109,111,100, 117,108,101,46,78,41,2,114,64,0,0,0,114,194,0,0, 0,114,186,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,6,0,0,0,114,187,0,0,0,100,3,0,0,243,4, + 114,6,0,0,0,114,187,0,0,0,92,3,0,0,243,4, 0,0,0,10,4,255,128,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, @@ -1323,7 +1324,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,5,0,0,0,114,186, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,114,189,0,0,0,106,3,0,0,114,188,0,0,0, + 0,0,114,189,0,0,0,98,3,0,0,114,188,0,0,0, 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, @@ -1333,17 +1334,17 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 32,97,32,112,97,99,107,97,103,101,46,78,41,2,114,64, 0,0,0,90,17,105,115,95,102,114,111,122,101,110,95,112, 97,99,107,97,103,101,114,186,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,114,128,0,0,0,112, + 114,5,0,0,0,114,6,0,0,0,114,128,0,0,0,104, 3,0,0,114,198,0,0,0,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,9,0,0, 0,114,8,0,0,0,114,1,0,0,0,114,10,0,0,0, - 114,151,0,0,0,114,190,0,0,0,114,113,0,0,0,114, + 114,151,0,0,0,114,190,0,0,0,114,114,0,0,0,114, 191,0,0,0,114,183,0,0,0,114,184,0,0,0,114,162, 0,0,0,114,163,0,0,0,114,170,0,0,0,114,100,0, 0,0,114,187,0,0,0,114,189,0,0,0,114,128,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,6,0,0,0,114,192,0,0,0,41,3,0,0,115,50, + 114,6,0,0,0,114,192,0,0,0,33,3,0,0,115,50, 0,0,0,8,0,4,2,4,7,2,2,10,1,2,8,12, 1,2,6,12,1,2,8,10,1,2,3,10,1,2,8,10, 1,2,9,2,1,12,1,2,4,2,1,12,1,2,4,2, @@ -1362,7 +1363,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 112,111,114,116,32,108,111,99,107,46,78,41,2,114,64,0, 0,0,114,65,0,0,0,114,52,0,0,0,114,5,0,0, 0,114,5,0,0,0,114,6,0,0,0,114,61,0,0,0, - 125,3,0,0,243,4,0,0,0,12,2,255,128,122,28,95, + 117,3,0,0,243,4,0,0,0,12,2,255,128,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, @@ -1375,13 +1376,13 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 120,99,95,116,121,112,101,218,9,101,120,99,95,118,97,108, 117,101,218,13,101,120,99,95,116,114,97,99,101,98,97,99, 107,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, - 114,63,0,0,0,129,3,0,0,114,201,0,0,0,122,27, + 114,63,0,0,0,121,3,0,0,114,201,0,0,0,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,9, 0,0,0,114,8,0,0,0,114,1,0,0,0,114,10,0, 0,0,114,61,0,0,0,114,63,0,0,0,114,5,0,0, 0,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, - 114,199,0,0,0,121,3,0,0,115,10,0,0,0,8,0, + 114,199,0,0,0,113,3,0,0,115,10,0,0,0,8,0, 4,2,8,2,12,4,255,128,114,199,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, @@ -1402,7 +1403,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,5,0,0,0,114,5,0, 0,0,114,6,0,0,0,218,13,95,114,101,115,111,108,118, - 101,95,110,97,109,101,134,3,0,0,115,12,0,0,0,16, + 101,95,110,97,109,101,126,3,0,0,115,12,0,0,0,16, 2,12,1,8,1,8,1,20,1,255,128,114,210,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, @@ -1412,7 +1413,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,41,4,218,6,102,105,110,100,101,114,114,20,0,0,0, 114,181,0,0,0,114,122,0,0,0,114,5,0,0,0,114, 5,0,0,0,114,6,0,0,0,218,17,95,102,105,110,100, - 95,115,112,101,99,95,108,101,103,97,99,121,143,3,0,0, + 95,115,112,101,99,95,108,101,103,97,99,121,135,3,0,0, 115,10,0,0,0,12,3,8,1,4,1,10,1,255,128,114, 212,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, 0,10,0,0,0,10,0,0,0,67,0,0,0,115,36,1, @@ -1444,13 +1445,13 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 12,114,18,0,0,0,218,9,109,101,116,97,95,112,97,116, 104,114,87,0,0,0,114,101,0,0,0,114,102,0,0,0, 114,169,0,0,0,114,105,0,0,0,114,199,0,0,0,114, - 183,0,0,0,114,2,0,0,0,114,212,0,0,0,114,119, + 183,0,0,0,114,2,0,0,0,114,212,0,0,0,114,113, 0,0,0,41,10,114,20,0,0,0,114,181,0,0,0,114, 182,0,0,0,114,213,0,0,0,90,9,105,115,95,114,101, 108,111,97,100,114,211,0,0,0,114,183,0,0,0,114,109, - 0,0,0,114,110,0,0,0,114,119,0,0,0,114,5,0, + 0,0,0,114,110,0,0,0,114,113,0,0,0,114,5,0, 0,0,114,5,0,0,0,114,6,0,0,0,218,10,95,102, - 105,110,100,95,115,112,101,99,152,3,0,0,115,66,0,0, + 105,110,100,95,115,112,101,99,144,3,0,0,115,66,0,0, 0,6,2,8,1,8,2,4,3,12,1,10,5,8,1,8, 1,2,1,10,1,14,1,12,1,8,1,16,1,4,255,12, 3,30,128,10,1,18,2,10,1,2,1,10,1,14,1,12, @@ -1483,7 +1484,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 87,0,0,0,169,3,114,20,0,0,0,114,208,0,0,0, 114,209,0,0,0,114,5,0,0,0,114,5,0,0,0,114, 6,0,0,0,218,13,95,115,97,110,105,116,121,95,99,104, - 101,99,107,199,3,0,0,115,26,0,0,0,10,2,18,1, + 101,99,107,191,3,0,0,115,26,0,0,0,10,2,18,1, 8,1,8,1,8,1,10,1,8,1,4,1,8,1,12,2, 8,1,8,255,255,128,114,220,0,0,0,122,16,78,111,32, 109,111,100,117,108,101,32,110,97,109,101,100,32,122,4,123, @@ -1525,7 +1526,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,90,5,99,104,105,108,100,114,5,0,0,0,114,5, 0,0,0,114,6,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,218,3,0,0,115,60,0,0,0,4,1,14,1,4,1, + 100,210,3,0,0,115,60,0,0,0,4,1,14,1,4,1, 10,1,10,1,10,2,10,1,10,1,2,1,10,1,14,1, 16,1,14,1,10,1,8,1,18,1,8,2,6,1,10,2, 14,1,2,1,14,1,4,4,14,253,16,1,14,1,8,1, @@ -1551,7 +1552,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 41,4,114,20,0,0,0,114,224,0,0,0,114,110,0,0, 0,114,82,0,0,0,114,5,0,0,0,114,5,0,0,0, 114,6,0,0,0,218,14,95,102,105,110,100,95,97,110,100, - 95,108,111,97,100,253,3,0,0,115,28,0,0,0,10,2, + 95,108,111,97,100,245,3,0,0,115,28,0,0,0,10,2, 14,1,8,1,24,1,14,255,16,128,8,3,2,1,6,1, 2,255,12,2,8,2,4,1,255,128,114,227,0,0,0,114, 25,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, @@ -1582,7 +1583,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,210,0,0,0,114,227,0,0,0,218,11,95,103, 99,100,95,105,109,112,111,114,116,114,219,0,0,0,114,5, 0,0,0,114,5,0,0,0,114,6,0,0,0,114,228,0, - 0,0,13,4,0,0,115,10,0,0,0,12,9,8,1,12, + 0,0,5,4,0,0,115,10,0,0,0,12,9,8,1,12, 1,10,1,255,128,114,228,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, @@ -1630,7 +1631,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,224,0,0,0,114,230,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,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,233,0,0,0,28,4,0,0,115,58,0,0, + 0,0,0,114,233,0,0,0,20,4,0,0,115,58,0,0, 0,8,10,10,1,4,1,12,1,4,2,10,1,8,1,8, 255,8,2,14,1,10,1,2,1,6,255,2,128,10,2,14, 1,2,1,14,1,14,1,10,4,16,1,2,255,12,2,2, @@ -1657,7 +1658,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,158,0,0,0, - 114,119,0,0,0,78,122,32,95,95,112,97,99,107,97,103, + 114,113,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, @@ -1673,7 +1674,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,208, 0,0,0,114,109,0,0,0,114,5,0,0,0,114,5,0, 0,0,114,6,0,0,0,218,17,95,99,97,108,99,95,95, - 95,112,97,99,107,97,103,101,95,95,65,4,0,0,115,44, + 95,112,97,99,107,97,103,101,95,95,57,4,0,0,115,44, 0,0,0,10,7,10,1,8,1,18,1,6,1,2,1,4, 255,4,1,6,255,4,2,6,254,4,3,8,1,6,1,6, 2,4,2,6,254,8,3,8,1,14,1,4,1,255,128,114, @@ -1729,7 +1730,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,114,209,0,0,0,114,110,0,0,0,90,8,103,108,111, 98,97,108,115,95,114,208,0,0,0,90,7,99,117,116,95, 111,102,102,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,218,10,95,95,105,109,112,111,114,116,95,95,92,4, + 0,0,218,10,95,95,105,109,112,111,114,116,95,95,84,4, 0,0,115,32,0,0,0,8,11,10,1,16,2,8,1,12, 1,4,1,8,3,18,1,4,1,4,1,26,4,30,3,10, 1,12,1,4,2,255,128,114,242,0,0,0,99,1,0,0, @@ -1743,7 +1744,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 173,0,0,0,41,2,114,20,0,0,0,114,109,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, 18,95,98,117,105,108,116,105,110,95,102,114,111,109,95,110, - 97,109,101,129,4,0,0,115,10,0,0,0,10,1,8,1, + 97,109,101,121,4,0,0,115,10,0,0,0,10,1,8,1, 12,1,8,1,255,128,114,243,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, @@ -1786,7 +1787,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,5,0,0,0,114,5,0,0,0,114, - 6,0,0,0,218,6,95,115,101,116,117,112,136,4,0,0, + 6,0,0,0,218,6,95,115,101,116,117,112,128,4,0,0, 115,42,0,0,0,4,9,4,1,8,3,18,1,10,1,10, 1,6,1,10,1,6,1,2,2,10,1,10,1,2,128,10, 3,8,1,10,1,10,1,10,2,14,1,4,251,255,128,114, @@ -1802,7 +1803,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,114,175,0,0,0,114,192,0,0,0,41,2,114, 245,0,0,0,114,246,0,0,0,114,5,0,0,0,114,5, 0,0,0,114,6,0,0,0,218,8,95,105,110,115,116,97, - 108,108,171,4,0,0,115,8,0,0,0,10,2,12,2,16, + 108,108,163,4,0,0,115,8,0,0,0,10,2,12,2,16, 1,255,128,114,248,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, @@ -1818,7 +1819,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 41,1,114,249,0,0,0,114,5,0,0,0,114,5,0,0, 0,114,6,0,0,0,218,27,95,105,110,115,116,97,108,108, 95,101,120,116,101,114,110,97,108,95,105,109,112,111,114,116, - 101,114,115,179,4,0,0,115,8,0,0,0,8,3,4,1, + 101,114,115,171,4,0,0,115,8,0,0,0,8,3,4,1, 20,1,255,128,114,250,0,0,0,41,2,78,78,41,1,78, 41,2,78,114,25,0,0,0,41,4,78,78,114,5,0,0, 0,114,25,0,0,0,41,54,114,10,0,0,0,114,7,0, @@ -1830,7 +1831,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,83,0,0,0,114,95,0,0,0,114,100,0,0, 0,114,111,0,0,0,114,124,0,0,0,114,125,0,0,0, 114,104,0,0,0,114,155,0,0,0,114,161,0,0,0,114, - 165,0,0,0,114,120,0,0,0,114,106,0,0,0,114,172, + 165,0,0,0,114,119,0,0,0,114,106,0,0,0,114,172, 0,0,0,114,173,0,0,0,114,107,0,0,0,114,175,0, 0,0,114,192,0,0,0,114,199,0,0,0,114,210,0,0, 0,114,212,0,0,0,114,214,0,0,0,114,220,0,0,0, @@ -1844,7 +1845,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 108,101,62,1,0,0,0,115,106,0,0,0,4,0,8,22, 4,9,4,1,4,1,4,3,8,3,8,8,4,8,4,2, 16,3,14,4,14,77,14,21,8,16,8,37,8,17,14,11, - 8,8,8,11,8,12,8,19,14,36,16,101,10,26,14,45, + 8,8,8,11,8,12,8,19,14,28,16,101,10,26,14,45, 8,72,8,17,8,17,8,30,8,36,8,45,14,15,14,75, 14,80,8,13,8,9,10,9,8,47,4,16,8,1,8,2, 6,32,8,3,10,16,14,15,8,37,10,27,8,37,8,7, diff --git a/Python/pyarena.c b/Python/pyarena.c index aefb787e554f96..ead03370d153c3 100644 --- a/Python/pyarena.c +++ b/Python/pyarena.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_pyarena.h" // PyArena /* A simple arena block structure. @@ -125,7 +126,7 @@ block_alloc(block *b, size_t size) } PyArena * -PyArena_New() +_PyArena_New(void) { PyArena* arena = (PyArena *)PyMem_Malloc(sizeof(PyArena)); if (!arena) @@ -154,7 +155,7 @@ PyArena_New() } void -PyArena_Free(PyArena *arena) +_PyArena_Free(PyArena *arena) { assert(arena); #if defined(Py_DEBUG) @@ -177,7 +178,7 @@ PyArena_Free(PyArena *arena) } void * -PyArena_Malloc(PyArena *arena, size_t size) +_PyArena_Malloc(PyArena *arena, size_t size) { void *p = block_alloc(arena->a_cur, size); if (!p) @@ -200,7 +201,7 @@ PyArena_Malloc(PyArena *arena, size_t size) } int -PyArena_AddPyObject(PyArena *arena, PyObject *obj) +_PyArena_AddPyObject(PyArena *arena, PyObject *obj) { int r = PyList_Append(arena->a_objects, obj); if (r >= 0) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1b8c4357362d27..8309477806f7a3 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2,9 +2,6 @@ #include "Python.h" -#include "Python-ast.h" -#undef Yield /* undefine macro conflicting with */ - #include "pycore_ceval.h" // _PyEval_FiniGIL() #include "pycore_context.h" // _PyContext_Init() #include "pycore_fileutils.h" // _Py_ResetForceASCII() diff --git a/Python/pythonrun.c b/Python/pythonrun.c index adb43e75f9ab72..b562875f8a4fb8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -10,11 +10,13 @@ #include "Python.h" -#include "Python-ast.h" +#include "pycore_ast.h" // PyAST_mod2obj #undef Yield /* undefine macro conflicting with */ +#include "pycore_compile.h" // _PyAST_Compile() #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_object.h" // _PyDebug_PrintTotalRefs() +#include "pycore_parser.h" // _PyParser_ASTFromString() #include "pycore_pyerrors.h" // _PyErr_Fetch #include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt #include "pycore_pystate.h" // _PyInterpreterState_GET() @@ -245,7 +247,7 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } } } - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) { Py_XDECREF(v); Py_XDECREF(w); @@ -253,14 +255,14 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, return -1; } - mod = PyParser_ASTFromFileObject(fp, filename, enc, Py_single_input, - ps1, ps2, flags, &errcode, arena); + mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input, + ps1, ps2, flags, &errcode, arena); Py_XDECREF(v); Py_XDECREF(w); Py_XDECREF(oenc); if (mod == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); if (errcode == E_EOF) { PyErr_Clear(); return E_EOF; @@ -269,12 +271,12 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } m = PyImport_AddModuleObject(mod_name); if (m == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); return -1; } d = PyModule_GetDict(m); v = run_mod(mod, filename, d, d, flags, arena); - PyArena_Free(arena); + _PyArena_Free(arena); if (v == NULL) { return -1; } @@ -1097,15 +1099,15 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, if (filename == NULL) return NULL; - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) return NULL; - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod != NULL) ret = run_mod(mod, filename, globals, locals, flags, arena); - PyArena_Free(arena); + _PyArena_Free(arena); return ret; } @@ -1114,14 +1116,14 @@ static PyObject * pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags) { - PyArena *arena = PyArena_New(); + PyArena *arena = _PyArena_New(); if (arena == NULL) { return NULL; } mod_ty mod; - mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, NULL, NULL, - flags, NULL, arena); + mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL, + flags, NULL, arena); if (closeit) { fclose(fp); @@ -1134,7 +1136,7 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, else { ret = NULL; } - PyArena_Free(arena); + _PyArena_Free(arena); return ret; } @@ -1224,7 +1226,7 @@ run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, PyCompilerFlags *flags, PyArena *arena) { PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *co = PyAST_CompileObject(mod, filename, flags, -1, arena); + PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena); if (co == NULL) return NULL; @@ -1287,22 +1289,22 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start, { PyCodeObject *co; mod_ty mod; - PyArena *arena = PyArena_New(); + PyArena *arena = _PyArena_New(); if (arena == NULL) return NULL; - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); return NULL; } if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { PyObject *result = PyAST_mod2obj(mod); - PyArena_Free(arena); + _PyArena_Free(arena); return result; } - co = PyAST_CompileObject(mod, filename, flags, optimize, arena); - PyArena_Free(arena); + co = _PyAST_Compile(mod, filename, flags, optimize, arena); + _PyArena_Free(arena); return (PyObject *)co; } diff --git a/Python/symtable.c b/Python/symtable.c index 85648f21e68894..68f2c71f18ea86 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1,7 +1,10 @@ #include "Python.h" +#include "pycore_ast.h" // identifier, stmt_ty +#undef Yield /* undefine macro conflicting with */ +#include "pycore_compile.h" // _Py_Mangle() +#include "pycore_parser.h" // _PyParser_ASTFromString() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntryObject -#undef Yield /* undefine macro conflicting with */ #include "structmember.h" // PyMemberDef /* error strings used for warnings */ @@ -1969,16 +1972,16 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, mod_ty mod; PyArena *arena; - arena = PyArena_New(); + arena = _PyArena_New(); if (arena == NULL) return NULL; - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod == NULL) { - PyArena_Free(arena); + _PyArena_Free(arena); return NULL; } st = _PySymtable_Build(mod, filename, 0); - PyArena_Free(arena); + _PyArena_Free(arena); return st; } diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index d4d77952468547..959742677d2f67 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2159,7 +2159,6 @@ def __repr__(self): __mod__ __mul__ __neg__ -__new__ __next__ __or__ __pos__ @@ -4227,6 +4226,9 @@ def state_modulename_name(self, line): module, cls = self.clinic._module_and_class(fields) fields = full_name.split('.') + if fields[-1] in unsupported_special_methods: + fail(f"{fields[-1]} is a special method and cannot be converted to Argument Clinic! (Yet.)") + if fields[-1] == '__new__': if (self.kind != CLASS_METHOD) or (not cls): fail("__new__ must be a class method!") @@ -4237,8 +4239,6 @@ def state_modulename_name(self, line): self.kind = METHOD_INIT if not return_converter: return_converter = init_return_converter() - elif fields[-1] in unsupported_special_methods: - fail(fields[-1] + " is a special method and cannot be converted to Argument Clinic! (Yet.)") if not return_converter: return_converter = CReturnConverter() diff --git a/Tools/peg_generator/peg_extension/peg_extension.c b/Tools/peg_generator/peg_extension/peg_extension.c index 96d3a52b880880..94e729e56d9b9c 100644 --- a/Tools/peg_generator/peg_extension/peg_extension.c +++ b/Tools/peg_generator/peg_extension/peg_extension.c @@ -1,4 +1,6 @@ #include "pegen.h" +#include "pycore_compile.h" // _PyAST_Compile() + PyObject * _build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *arena) @@ -6,7 +8,7 @@ _build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *ar PyObject *result = NULL; if (mode == 2) { - result = (PyObject *)PyAST_CompileObject(module, filename_ob, NULL, -1, arena); + result = (PyObject *)_PyAST_Compile(module, filename_ob, NULL, -1, arena); } else if (mode == 1) { result = PyAST_mod2obj(module); } else { @@ -30,7 +32,7 @@ parse_file(PyObject *self, PyObject *args, PyObject *kwds) return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2"); } - PyArena *arena = PyArena_New(); + PyArena *arena = _PyArena_New(); if (arena == NULL) { return NULL; } @@ -42,8 +44,17 @@ parse_file(PyObject *self, PyObject *args, PyObject *kwds) goto error; } + FILE *fp = fopen(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); + goto error; + } + PyCompilerFlags flags = _PyCompilerFlags_INIT; - mod_ty res = _PyPegen_run_parser_from_file(filename, Py_file_input, filename_ob, &flags, arena); + mod_ty res = _PyPegen_run_parser_from_file_pointer( + fp, Py_file_input, filename_ob, + NULL, NULL, NULL, &flags, NULL, arena); + fclose(fp); if (res == NULL) { goto error; } @@ -52,7 +63,7 @@ parse_file(PyObject *self, PyObject *args, PyObject *kwds) error: Py_XDECREF(filename_ob); - PyArena_Free(arena); + _PyArena_Free(arena); return result; } @@ -69,7 +80,7 @@ parse_string(PyObject *self, PyObject *args, PyObject *kwds) return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2"); } - PyArena *arena = PyArena_New(); + PyArena *arena = _PyArena_New(); if (arena == NULL) { return NULL; } @@ -91,7 +102,7 @@ parse_string(PyObject *self, PyObject *args, PyObject *kwds) error: Py_XDECREF(filename_ob); - PyArena_Free(arena); + _PyArena_Free(arena); return result; } diff --git a/configure b/configure index 2ddca079860625..f9b2aff3b83107 100755 --- a/configure +++ b/configure @@ -2765,7 +2765,7 @@ if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # If we're building out-of-tree, we need to make sure the following # resources get picked up before their $srcdir counterparts. # Objects/ -> typeslots.inc - # Include/ -> Python-ast.h + # Include/ -> Python.h # Python/ -> importlib.h # (A side effect of this is that these resources will automatically be # regenerated when building out-of-tree, regardless of whether or not diff --git a/configure.ac b/configure.ac index 4c3c80f74d215b..e43b7733aed31d 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # If we're building out-of-tree, we need to make sure the following # resources get picked up before their $srcdir counterparts. # Objects/ -> typeslots.inc - # Include/ -> Python-ast.h + # Include/ -> Python.h # Python/ -> importlib.h # (A side effect of this is that these resources will automatically be # regenerated when building out-of-tree, regardless of whether or not