Issue #24400: Introduce a distinct type for 'async def' coroutines.

Summary of changes:

1. Coroutines now have a distinct, separate from generators
   type at the C level: PyGen_Type, and a new typedef PyCoroObject.
   PyCoroObject shares the initial segment of struct layout with
   PyGenObject, making it possible to reuse existing generators
   machinery.  The new type is exposed as 'types.CoroutineType'.

   As a consequence of having a new type, CO_GENERATOR flag is
   no longer applied to coroutines.

2. Having a separate type for coroutines made it possible to add
   an __await__ method to the type.  Although it is not used by the
   interpreter (see details on that below), it makes coroutines
   naturally (without using __instancecheck__) conform to
   collections.abc.Coroutine and collections.abc.Awaitable ABCs.

   [The __instancecheck__ is still used for generator-based
   coroutines, as we don't want to add __await__ for generators.]

3. Add new opcode: GET_YIELD_FROM_ITER.  The opcode is needed to
   allow passing native coroutines to the YIELD_FROM opcode.

   Before this change, 'yield from o' expression was compiled to:

      (o)
      GET_ITER
      LOAD_CONST
      YIELD_FROM

   Now, we use GET_YIELD_FROM_ITER instead of GET_ITER.

   The reason for adding a new opcode is that GET_ITER is used
   in some contexts (such as 'for .. in' loops) where passing
   a coroutine object is invalid.

4. Add two new introspection functions to the inspec module:
   getcoroutinestate(c) and getcoroutinelocals(c).

5. inspect.iscoroutine(o) is updated to test if 'o' is a native
   coroutine object.  Before this commit it used abc.Coroutine,
   and it was requested to update inspect.isgenerator(o) to use
   abc.Generator; it was decided, however, that inspect functions
   should really be tailored for checking for native types.

6. sys.set_coroutine_wrapper(w) API is updated to work with only
   native coroutines.  Since types.coroutine decorator supports
   any type of callables now, it would be confusing that it does
   not work for all types of coroutines.

7. Exceptions logic in generators C implementation was updated
   to raise clearer messages for coroutines:

   Before: TypeError("generator raised StopIteration")
   After: TypeError("coroutine raised StopIteration")
This commit is contained in:
Yury Selivanov 2015-06-22 12:19:30 -04:00
parent cd881b850c
commit 5376ba9630
29 changed files with 1014 additions and 378 deletions

View File

@ -112,5 +112,6 @@ Other Objects
weakref.rst
capsule.rst
gen.rst
coro.rst
datetime.rst

34
Doc/c-api/coro.rst Normal file
View File

@ -0,0 +1,34 @@
.. highlightlang:: c
.. _coro-objects:
Coroutine Objects
-----------------
.. versionadded:: 3.5
Coroutine objects are what functions declared with an ``async`` keyword
return.
.. c:type:: PyCoroObject
The C structure used for coroutine objects.
.. c:var:: PyTypeObject PyCoro_Type
The type object corresponding to coroutine objects.
.. c:function:: int PyCoro_CheckExact(PyObject *ob)
Return true if *ob*'s type is *PyCoro_Type*; *ob* must not be *NULL*.
.. c:function:: PyObject* PyCoro_New(PyFrameObject *frame, PyObject *name, PyObject *qualname)
Create and return a new coroutine object based on the *frame* object,
with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
A reference to *frame* is stolen by this function. The *frame* argument
must not be *NULL*.

View File

@ -7,7 +7,7 @@ Generator Objects
Generator objects are what Python uses to implement generator iterators. They
are normally created by iterating over a function that yields values, rather
than explicitly calling :c:func:`PyGen_New`.
than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`.
.. c:type:: PyGenObject
@ -20,19 +20,25 @@ than explicitly calling :c:func:`PyGen_New`.
The type object corresponding to generator objects
.. c:function:: int PyGen_Check(ob)
.. c:function:: int PyGen_Check(PyObject *ob)
Return true if *ob* is a generator object; *ob* must not be *NULL*.
.. c:function:: int PyGen_CheckExact(ob)
.. c:function:: int PyGen_CheckExact(PyObject *ob)
Return true if *ob*'s type is *PyGen_Type* is a generator object; *ob* must not
be *NULL*.
Return true if *ob*'s type is *PyGen_Type*; *ob* must not be *NULL*.
.. c:function:: PyObject* PyGen_New(PyFrameObject *frame)
Create and return a new generator object based on the *frame* object. A
reference to *frame* is stolen by this function. The parameter must not be
Create and return a new generator object based on the *frame* object.
A reference to *frame* is stolen by this function. The argument must not be
*NULL*.
.. c:function:: PyObject* PyGen_NewWithQualName(PyFrameObject *frame, PyObject *name, PyObject *qualname)
Create and return a new generator object based on the *frame* object,
with ``__name__`` and ``__qualname__`` set to *name* and *qualname*.
A reference to *frame* is stolen by this function. The *frame* argument
must not be *NULL*.

View File

@ -491,6 +491,12 @@ PyFunction_SetDefaults:PyObject*:defaults:+1:
PyGen_New:PyObject*::+1:
PyGen_New:PyFrameObject*:frame:0:
PyGen_NewWithQualName:PyObject*::+1:
PyGen_NewWithQualName:PyFrameObject*:frame:0:
PyCoro_New:PyObject*::+1:
PyCoro_New:PyFrameObject*:frame:0:
Py_InitModule:PyObject*::0:
Py_InitModule:const char*:name::
Py_InitModule:PyMethodDef[]:methods::

View File

@ -333,14 +333,23 @@ Glossary
.. index:: single: generator
generator
A function which returns an iterator. It looks like a normal function
except that it contains :keyword:`yield` statements for producing a series
of values usable in a for-loop or that can be retrieved one at a time with
the :func:`next` function. Each :keyword:`yield` temporarily suspends
processing, remembering the location execution state (including local
variables and pending try-statements). When the generator resumes, it
picks-up where it left-off (in contrast to functions which start fresh on
every invocation).
A function which returns a :term:`generator iterator`. It looks like a
normal function except that it contains :keyword:`yield` expressions
for producing a series of values usable in a for-loop or that can be
retrieved one at a time with the :func:`next` function.
Usually refers to a generator function, but may refer to a
*generator iterator* in some contexts. In cases where the intended
meaning isn't clear, using the full terms avoids ambiguity.
generator iterator
An object created by a :term:`generator` function.
Each :keyword:`yield` temporarily suspends processing, remembering the
location execution state (including local variables and pending
try-statements). When the *generator iterator* resumes, it picks-up where
it left-off (in contrast to functions which start fresh on every
invocation).
.. index:: single: generator expression

View File

@ -346,6 +346,14 @@ result back on the stack.
Implements ``TOS = iter(TOS)``.
.. opcode:: GET_YIELD_FROM_ITER
If ``TOS`` is a :term:`generator iterator` or :term:`coroutine` object
it is left as is. Otherwise, implements ``TOS = iter(TOS)``.
.. versionadded:: 3.5
**Binary operations**
Binary operations remove the top of the stack (TOS) and the second top-most

View File

@ -178,6 +178,16 @@ attributes:
+-----------+-----------------+---------------------------+
| | gi_code | code |
+-----------+-----------------+---------------------------+
| coroutine | __name__ | name |
+-----------+-----------------+---------------------------+
| | __qualname__ | qualified name |
+-----------+-----------------+---------------------------+
| | cr_frame | frame |
+-----------+-----------------+---------------------------+
| | cr_running | is the coroutine running? |
+-----------+-----------------+---------------------------+
| | cr_code | code |
+-----------+-----------------+---------------------------+
| builtin | __doc__ | documentation string |
+-----------+-----------------+---------------------------+
| | __name__ | original name of this |
@ -279,29 +289,16 @@ attributes:
.. function:: iscoroutinefunction(object)
Return true if the object is a :term:`coroutine function`.
Coroutine functions are defined with an ``async def`` syntax,
or are generators decorated with :func:`types.coroutine`
or :func:`asyncio.coroutine`.
The function will return false for plain Python generator
functions.
Return true if the object is a :term:`coroutine function`
(a function defined with an :keyword:`async def` syntax).
.. versionadded:: 3.5
.. function:: iscoroutine(object)
Return true if the object is a :term:`coroutine`.
Coroutines are results of calls of coroutine functions or
generator functions decorated with :func:`types.coroutine`
or :func:`asyncio.coroutine`.
The function will return false for plain python generators.
See also :class:`collections.abc.Coroutine`.
Return true if the object is a :term:`coroutine` created by an
:keyword:`async def` function.
.. versionadded:: 3.5
@ -1116,8 +1113,8 @@ code execution::
pass
Current State of a Generator
----------------------------
Current State of Generators and Coroutines
------------------------------------------
When implementing coroutine schedulers and for other advanced uses of
generators, it is useful to determine whether a generator is currently
@ -1137,6 +1134,21 @@ generator to be determined easily.
.. versionadded:: 3.2
.. function:: getcoroutinestate(coroutine)
Get current state of a coroutine object. The function is intended to be
used with coroutine objects created by :keyword:`async def` functions, but
will accept any coroutine-like object that has ``cr_running`` and
``cr_frame`` attributes.
Possible states are:
* CORO_CREATED: Waiting to start execution.
* CORO_RUNNING: Currently being executed by the interpreter.
* CORO_SUSPENDED: Currently suspended at an await expression.
* CORO_CLOSED: Execution has completed.
.. versionadded:: 3.5
The current internal state of the generator can also be queried. This is
mostly useful for testing purposes, to ensure that internal state is being
updated as expected:
@ -1161,6 +1173,13 @@ updated as expected:
.. versionadded:: 3.3
.. function:: getcoroutinelocals(coroutine)
This function is analogous to :func:`~inspect.getgeneratorlocals`, but
works for coroutine objects created by :keyword:`async def` functions.
.. versionadded:: 3.5
.. _inspect-module-cli:

View File

@ -1075,7 +1075,10 @@ always available.
.. function:: set_coroutine_wrapper(wrapper)
Allows to intercept creation of :term:`coroutine` objects.
Allows intercepting creation of :term:`coroutine` objects (only ones that
are created by an :keyword:`async def` function; generators decorated with
:func:`types.coroutine` or :func:`asyncio.coroutine` will not be
intercepted).
*wrapper* must be either:

View File

@ -90,6 +90,14 @@ Standard names are defined for the following types:
generator function.
.. data:: CoroutineType
The type of :term:`coroutine` objects, produced by calling a
function defined with an :keyword:`async def` statement.
.. versionadded:: 3.5
.. data:: CodeType
.. index:: builtin: compile

View File

@ -666,6 +666,15 @@ can be used to create instance variables with different implementation details.
Coroutines
==========
.. index::
statement: async def
statement: async for
statement: async with
keyword: async
keyword: await
.. versionadded:: 3.5
.. _`async def`:
Coroutine function definition
@ -683,7 +692,11 @@ even if they do not contain ``await`` or ``async`` keywords.
It is a :exc:`SyntaxError` to use :keyword:`yield` expressions in coroutines.
.. versionadded:: 3.5
An example of a coroutine function::
async def func(param1, param2):
do_stuff()
await some_coroutine()
.. _`async for`:
@ -725,7 +738,8 @@ Is semantically equivalent to::
See also :meth:`__aiter__` and :meth:`__anext__` for details.
.. versionadded:: 3.5
It is a :exc:`SyntaxError` to use ``async for`` statement outside of an
:keyword:`async def` function.
.. _`async with`:
@ -762,7 +776,8 @@ Is semantically equivalent to::
See also :meth:`__aenter__` and :meth:`__aexit__` for details.
.. versionadded:: 3.5
It is a :exc:`SyntaxError` to use ``async with`` statement outside of an
:keyword:`async def` function.
.. seealso::

View File

@ -531,6 +531,9 @@ inspect
and :func:`~inspect.isawaitable` functions. (Contributed by Yury Selivanov
in :issue:`24017`.)
* New :func:`~inspect.getcoroutinelocals` and :func:`~inspect.getcoroutinestate`
functions. (Contributed by Yury Selivanov in :issue:`24400`.)
ipaddress
---------
@ -734,6 +737,9 @@ types
* New :func:`~types.coroutine` function. (Contributed by Yury Selivanov
in :issue:`24017`.)
* New :class:`~types.CoroutineType`. (Contributed by Yury Selivanov
in :issue:`24400`.)
urllib
------
@ -1101,6 +1107,7 @@ Changes in the C API
the :attr:`__module__` attribute. Would be an AttributeError in future.
(:issue:`20204`)
* As part of PEP 492 implementation, ``tp_reserved`` slot of
* As part of :pep:`492` implementation, ``tp_reserved`` slot of
:c:type:`PyTypeObject` was replaced with a
:c:member:`PyTypeObject.tp_as_async` slot.
:c:member:`PyTypeObject.tp_as_async` slot. Refer to :ref:`coro-objects` for
new types, structures and functions.

View File

@ -10,27 +10,26 @@ extern "C" {
struct _frame; /* Avoid including frameobject.h */
/* _PyGenObject_HEAD defines the initial segment of generator
and coroutine objects. */
#define _PyGenObject_HEAD(prefix) \
PyObject_HEAD \
/* Note: gi_frame can be NULL if the generator is "finished" */ \
struct _frame *prefix##_frame; \
/* True if generator is being executed. */ \
char prefix##_running; \
/* The code object backing the generator */ \
PyObject *prefix##_code; \
/* List of weak reference. */ \
PyObject *prefix##_weakreflist; \
/* Name of the generator. */ \
PyObject *prefix##_name; \
/* Qualified name of the generator. */ \
PyObject *prefix##_qualname;
typedef struct {
PyObject_HEAD
/* The gi_ prefix is intended to remind of generator-iterator. */
/* Note: gi_frame can be NULL if the generator is "finished" */
struct _frame *gi_frame;
/* True if generator is being executed. */
char gi_running;
/* The code object backing the generator */
PyObject *gi_code;
/* List of weak reference. */
PyObject *gi_weakreflist;
/* Name of the generator. */
PyObject *gi_name;
/* Qualified name of the generator. */
PyObject *gi_qualname;
_PyGenObject_HEAD(gi)
} PyGenObject;
PyAPI_DATA(PyTypeObject) PyGen_Type;
@ -38,12 +37,6 @@ PyAPI_DATA(PyTypeObject) PyGen_Type;
#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type)
#define PyGen_CheckCoroutineExact(op) (PyGen_CheckExact(op) && \
(((PyCodeObject*) \
((PyGenObject*)op)->gi_code) \
->co_flags & (CO_ITERABLE_COROUTINE | \
CO_COROUTINE)))
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *,
PyObject *name, PyObject *qualname);
@ -52,7 +45,21 @@ PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
PyObject *_PyGen_Send(PyGenObject *, PyObject *);
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
PyObject *_PyGen_GetAwaitableIter(PyObject *o);
#ifndef Py_LIMITED_API
typedef struct {
_PyGenObject_HEAD(cr)
} PyCoroObject;
PyAPI_DATA(PyTypeObject) PyCoro_Type;
PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type;
#define PyCoro_CheckExact(op) (Py_TYPE(op) == &PyCoro_Type)
PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *,
PyObject *name, PyObject *qualname);
#endif
#undef _PyGenObject_HEAD
#ifdef __cplusplus
}

View File

@ -45,6 +45,7 @@ extern "C" {
#define BINARY_OR 66
#define INPLACE_POWER 67
#define GET_ITER 68
#define GET_YIELD_FROM_ITER 69
#define PRINT_EXPR 70
#define LOAD_BUILD_CLASS 71
#define YIELD_FROM 72

View File

@ -52,6 +52,12 @@ dict_items = type({}.items())
## misc ##
mappingproxy = type(type.__dict__)
generator = type((lambda: (yield))())
## coroutine ##
async def _coro(): pass
_coro = _coro()
coroutine = type(_coro)
_coro.close() # Prevent ResourceWarning
del _coro
### ONE-TRICK PONIES ###
@ -78,17 +84,15 @@ class Hashable(metaclass=ABCMeta):
class _AwaitableMeta(ABCMeta):
def __instancecheck__(cls, instance):
# 0x80 = CO_COROUTINE
# 0x100 = CO_ITERABLE_COROUTINE
# We don't want to import 'inspect' module, as
# a dependency for 'collections.abc'.
CO_COROUTINES = 0x80 | 0x100
if (isinstance(instance, generator) and
instance.gi_code.co_flags & CO_COROUTINES):
# This hook is needed because we can't add
# '__await__' method to generator objects, and
# we can't register GeneratorType on Awaitable.
# NB: 0x100 = CO_ITERABLE_COROUTINE
# (We don't want to import 'inspect' module, as
# a dependency for 'collections.abc')
if (instance.__class__ is generator and
instance.gi_code.co_flags & 0x100):
return True
return super().__instancecheck__(instance)
@ -159,6 +163,9 @@ class Coroutine(Awaitable):
return NotImplemented
Coroutine.register(coroutine)
class AsyncIterable(metaclass=ABCMeta):
__slots__ = ()

View File

@ -34,30 +34,20 @@ _DEBUG = (not sys.flags.ignore_environment
try:
types.coroutine
_types_coroutine = types.coroutine
except AttributeError:
native_coroutine_support = False
else:
native_coroutine_support = True
_types_coroutine = None
try:
_iscoroutinefunction = inspect.iscoroutinefunction
_inspect_iscoroutinefunction = inspect.iscoroutinefunction
except AttributeError:
_iscoroutinefunction = lambda func: False
_inspect_iscoroutinefunction = lambda func: False
try:
inspect.CO_COROUTINE
except AttributeError:
_is_native_coro_code = lambda code: False
else:
_is_native_coro_code = lambda code: (code.co_flags &
inspect.CO_COROUTINE)
try:
from collections.abc import Coroutine as CoroutineABC, \
Awaitable as AwaitableABC
from collections.abc import Coroutine as _CoroutineABC, \
Awaitable as _AwaitableABC
except ImportError:
CoroutineABC = AwaitableABC = None
_CoroutineABC = _AwaitableABC = None
# Check for CPython issue #21209
@ -89,10 +79,7 @@ def debug_wrapper(gen):
# We only wrap here coroutines defined via 'async def' syntax.
# Generator-based coroutines are wrapped in @coroutine
# decorator.
if _is_native_coro_code(gen.gi_code):
return CoroWrapper(gen, None)
else:
return gen
return CoroWrapper(gen, None)
class CoroWrapper:
@ -177,8 +164,7 @@ def coroutine(func):
If the coroutine is not yielded from before it is destroyed,
an error message is logged.
"""
is_coroutine = _iscoroutinefunction(func)
if is_coroutine and _is_native_coro_code(func.__code__):
if _inspect_iscoroutinefunction(func):
# In Python 3.5 that's all we need to do for coroutines
# defiend with "async def".
# Wrapping in CoroWrapper will happen via
@ -193,7 +179,7 @@ def coroutine(func):
res = func(*args, **kw)
if isinstance(res, futures.Future) or inspect.isgenerator(res):
res = yield from res
elif AwaitableABC is not None:
elif _AwaitableABC is not None:
# If 'func' returns an Awaitable (new in 3.5) we
# want to run it.
try:
@ -201,15 +187,15 @@ def coroutine(func):
except AttributeError:
pass
else:
if isinstance(res, AwaitableABC):
if isinstance(res, _AwaitableABC):
res = yield from await_meth()
return res
if not _DEBUG:
if native_coroutine_support:
wrapper = types.coroutine(coro)
else:
if _types_coroutine is None:
wrapper = coro
else:
wrapper = _types_coroutine(coro)
else:
@functools.wraps(func)
def wrapper(*args, **kwds):
@ -231,12 +217,12 @@ def coroutine(func):
def iscoroutinefunction(func):
"""Return True if func is a decorated coroutine function."""
return (getattr(func, '_is_coroutine', False) or
_iscoroutinefunction(func))
_inspect_iscoroutinefunction(func))
_COROUTINE_TYPES = (types.GeneratorType, CoroWrapper)
if CoroutineABC is not None:
_COROUTINE_TYPES += (CoroutineABC,)
if _CoroutineABC is not None:
_COROUTINE_TYPES += (_CoroutineABC,)
def iscoroutine(obj):

View File

@ -222,12 +222,13 @@ _code_type = type(_write_atomic.__code__)
# Python 3.5a0 3320 (matrix multiplication operator)
# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations)
# Python 3.5b2 3340 (fix dictionary display evaluation order #11205)
# Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
# due to the addition of new opcodes).
MAGIC_NUMBER = (3340).to_bytes(2, 'little') + b'\r\n'
MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'

View File

@ -175,8 +175,7 @@ def isgeneratorfunction(object):
See help(isfunction) for attributes listing."""
return bool((isfunction(object) or ismethod(object)) and
object.__code__.co_flags & CO_GENERATOR and
not object.__code__.co_flags & CO_COROUTINE)
object.__code__.co_flags & CO_GENERATOR)
def iscoroutinefunction(object):
"""Return true if the object is a coroutine function.
@ -185,8 +184,7 @@ def iscoroutinefunction(object):
or generators decorated with "types.coroutine".
"""
return bool((isfunction(object) or ismethod(object)) and
object.__code__.co_flags & (CO_ITERABLE_COROUTINE |
CO_COROUTINE))
object.__code__.co_flags & CO_COROUTINE)
def isawaitable(object):
"""Return true if the object can be used in "await" expression."""
@ -207,12 +205,11 @@ def isgenerator(object):
send resumes the generator and "sends" a value that becomes
the result of the current yield-expression
throw used to raise an exception inside the generator"""
return (isinstance(object, types.GeneratorType) and
not object.gi_code.co_flags & CO_COROUTINE)
return isinstance(object, types.GeneratorType)
def iscoroutine(object):
"""Return true if the object is a coroutine."""
return isinstance(object, collections.abc.Coroutine)
return isinstance(object, types.CoroutineType)
def istraceback(object):
"""Return true if the object is a traceback.
@ -1598,6 +1595,45 @@ def getgeneratorlocals(generator):
else:
return {}
# ------------------------------------------------ coroutine introspection
CORO_CREATED = 'CORO_CREATED'
CORO_RUNNING = 'CORO_RUNNING'
CORO_SUSPENDED = 'CORO_SUSPENDED'
CORO_CLOSED = 'CORO_CLOSED'
def getcoroutinestate(coroutine):
"""Get current state of a coroutine object.
Possible states are:
CORO_CREATED: Waiting to start execution.
CORO_RUNNING: Currently being executed by the interpreter.
CORO_SUSPENDED: Currently suspended at an await expression.
CORO_CLOSED: Execution has completed.
"""
if coroutine.cr_running:
return CORO_RUNNING
if coroutine.cr_frame is None:
return CORO_CLOSED
if coroutine.cr_frame.f_lasti == -1:
return CORO_CREATED
return CORO_SUSPENDED
def getcoroutinelocals(coroutine):
"""
Get the mapping of coroutine local variables to their current values.
A dict is returned, with the keys the local variable names and values the
bound values."""
frame = getattr(coroutine, "cr_frame", None)
if frame is not None:
return frame.f_locals
else:
return {}
###############################################################################
### Function Signature Object (PEP 362)
###############################################################################

View File

@ -103,6 +103,7 @@ def_op('BINARY_XOR', 65)
def_op('BINARY_OR', 66)
def_op('INPLACE_POWER', 67)
def_op('GET_ITER', 68)
def_op('GET_YIELD_FROM_ITER', 69)
def_op('PRINT_EXPR', 70)
def_op('LOAD_BUILD_CLASS', 71)

View File

@ -24,7 +24,7 @@ class AsyncYield:
def run_async(coro):
assert coro.__class__ is types.GeneratorType
assert coro.__class__ in {types.GeneratorType, types.CoroutineType}
buffer = []
result = None
@ -37,6 +37,25 @@ def run_async(coro):
return buffer, result
def run_async__await__(coro):
assert coro.__class__ is types.CoroutineType
aw = coro.__await__()
buffer = []
result = None
i = 0
while True:
try:
if i % 2:
buffer.append(next(aw))
else:
buffer.append(aw.send(None))
i += 1
except StopIteration as ex:
result = ex.args[0] if ex.args else None
break
return buffer, result
@contextlib.contextmanager
def silence_coro_gc():
with warnings.catch_warnings():
@ -121,22 +140,24 @@ class CoroutineTest(unittest.TestCase):
return 10
f = foo()
self.assertIsInstance(f, types.GeneratorType)
self.assertTrue(bool(foo.__code__.co_flags & 0x80))
self.assertTrue(bool(foo.__code__.co_flags & 0x20))
self.assertTrue(bool(f.gi_code.co_flags & 0x80))
self.assertTrue(bool(f.gi_code.co_flags & 0x20))
self.assertIsInstance(f, types.CoroutineType)
self.assertTrue(bool(foo.__code__.co_flags & inspect.CO_COROUTINE))
self.assertFalse(bool(foo.__code__.co_flags & inspect.CO_GENERATOR))
self.assertTrue(bool(f.cr_code.co_flags & inspect.CO_COROUTINE))
self.assertFalse(bool(f.cr_code.co_flags & inspect.CO_GENERATOR))
self.assertEqual(run_async(f), ([], 10))
self.assertEqual(run_async__await__(foo()), ([], 10))
def bar(): pass
self.assertFalse(bool(bar.__code__.co_flags & 0x80))
self.assertFalse(bool(bar.__code__.co_flags & inspect.CO_COROUTINE))
def test_func_2(self):
async def foo():
raise StopIteration
with self.assertRaisesRegex(
RuntimeError, "generator raised StopIteration"):
RuntimeError, "coroutine raised StopIteration"):
run_async(foo())
@ -152,7 +173,7 @@ class CoroutineTest(unittest.TestCase):
raise StopIteration
check = lambda: self.assertRaisesRegex(
TypeError, "coroutine-objects do not support iteration")
TypeError, "'coroutine' object is not iterable")
with check():
list(foo())
@ -166,9 +187,6 @@ class CoroutineTest(unittest.TestCase):
with check():
iter(foo())
with check():
next(foo())
with silence_coro_gc(), check():
for i in foo():
pass
@ -185,7 +203,7 @@ class CoroutineTest(unittest.TestCase):
await bar()
check = lambda: self.assertRaisesRegex(
TypeError, "coroutine-objects do not support iteration")
TypeError, "'coroutine' object is not iterable")
with check():
for el in foo(): pass
@ -221,7 +239,7 @@ class CoroutineTest(unittest.TestCase):
with silence_coro_gc(), self.assertRaisesRegex(
TypeError,
"cannot 'yield from' a coroutine object from a generator"):
"cannot 'yield from' a coroutine object in a non-coroutine generator"):
list(foo())
@ -244,6 +262,98 @@ class CoroutineTest(unittest.TestCase):
foo()
support.gc_collect()
def test_func_10(self):
N = 0
@types.coroutine
def gen():
nonlocal N
try:
a = yield
yield (a ** 2)
except ZeroDivisionError:
N += 100
raise
finally:
N += 1
async def foo():
await gen()
coro = foo()
aw = coro.__await__()
self.assertIs(aw, iter(aw))
next(aw)
self.assertEqual(aw.send(10), 100)
self.assertEqual(N, 0)
aw.close()
self.assertEqual(N, 1)
coro = foo()
aw = coro.__await__()
next(aw)
with self.assertRaises(ZeroDivisionError):
aw.throw(ZeroDivisionError, None, None)
self.assertEqual(N, 102)
def test_func_11(self):
async def func(): pass
coro = func()
# Test that PyCoro_Type and _PyCoroWrapper_Type types were properly
# initialized
self.assertIn('__await__', dir(coro))
self.assertIn('__iter__', dir(coro.__await__()))
self.assertIn('coroutine_wrapper', repr(coro.__await__()))
coro.close() # avoid RuntimeWarning
def test_func_12(self):
async def g():
i = me.send(None)
await foo
me = g()
with self.assertRaisesRegex(ValueError,
"coroutine already executing"):
me.send(None)
def test_func_13(self):
async def g():
pass
with self.assertRaisesRegex(
TypeError,
"can't send non-None value to a just-started coroutine"):
g().send('spam')
def test_func_14(self):
@types.coroutine
def gen():
yield
async def coro():
try:
await gen()
except GeneratorExit:
await gen()
c = coro()
c.send(None)
with self.assertRaisesRegex(RuntimeError,
"coroutine ignored GeneratorExit"):
c.close()
def test_corotype_1(self):
ct = types.CoroutineType
self.assertIn('into coroutine', ct.send.__doc__)
self.assertIn('inside coroutine', ct.close.__doc__)
self.assertIn('in coroutine', ct.throw.__doc__)
self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__)
self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__)
self.assertEqual(ct.__name__, 'coroutine')
async def f(): pass
c = f()
self.assertIn('coroutine object', repr(c))
c.close()
def test_await_1(self):
async def foo():
@ -262,6 +372,7 @@ class CoroutineTest(unittest.TestCase):
await AsyncYieldFrom([1, 2, 3])
self.assertEqual(run_async(foo()), ([1, 2, 3], None))
self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None))
def test_await_4(self):
async def bar():
@ -1015,6 +1126,27 @@ class SysSetCoroWrapperTest(unittest.TestCase):
finally:
sys.set_coroutine_wrapper(None)
def test_set_wrapper_4(self):
@types.coroutine
def foo():
return 'spam'
wrapped = None
def wrap(gen):
nonlocal wrapped
wrapped = gen
return gen
sys.set_coroutine_wrapper(wrap)
try:
foo()
self.assertIs(
wrapped, None,
"generator-based coroutine was wrapped via "
"sys.set_coroutine_wrapper")
finally:
sys.set_coroutine_wrapper(None)
class CAPITest(unittest.TestCase):

View File

@ -141,9 +141,9 @@ class TestPredicates(IsTestBase):
gen_coro = gen_coroutine_function_example(1)
coro = coroutine_function_example(1)
self.assertTrue(
self.assertFalse(
inspect.iscoroutinefunction(gen_coroutine_function_example))
self.assertTrue(inspect.iscoroutine(gen_coro))
self.assertFalse(inspect.iscoroutine(gen_coro))
self.assertTrue(
inspect.isgeneratorfunction(gen_coroutine_function_example))
@ -1737,6 +1737,70 @@ class TestGetGeneratorState(unittest.TestCase):
self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
class TestGetCoroutineState(unittest.TestCase):
def setUp(self):
@types.coroutine
def number_coroutine():
for number in range(5):
yield number
async def coroutine():
await number_coroutine()
self.coroutine = coroutine()
def tearDown(self):
self.coroutine.close()
def _coroutinestate(self):
return inspect.getcoroutinestate(self.coroutine)
def test_created(self):
self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
def test_suspended(self):
self.coroutine.send(None)
self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
def test_closed_after_exhaustion(self):
while True:
try:
self.coroutine.send(None)
except StopIteration:
break
self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
def test_closed_after_immediate_exception(self):
with self.assertRaises(RuntimeError):
self.coroutine.throw(RuntimeError)
self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
def test_easy_debugging(self):
# repr() and str() of a coroutine state should contain the state name
names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
for name in names:
state = getattr(inspect, name)
self.assertIn(name, repr(state))
self.assertIn(name, str(state))
def test_getcoroutinelocals(self):
@types.coroutine
def gencoro():
yield
gencoro = gencoro()
async def func(a=None):
b = 'spam'
await gencoro
coro = func()
self.assertEqual(inspect.getcoroutinelocals(coro),
{'a': None, 'gencoro': gencoro})
coro.send(None)
self.assertEqual(inspect.getcoroutinelocals(coro),
{'a': None, 'gencoro': gencoro, 'b': 'spam'})
class MySignature(inspect.Signature):
# Top-level to make it picklable;
# used in test_signature_object_pickle
@ -3494,7 +3558,8 @@ def test_main():
TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject,
TestBoundArguments, TestSignaturePrivateHelpers,
TestSignatureDefinitions,
TestGetClosureVars, TestUnwrap, TestMain, TestReload
TestGetClosureVars, TestUnwrap, TestMain, TestReload,
TestGetCoroutineState
)
if __name__ == "__main__":

View File

@ -1205,10 +1205,28 @@ class CoroutineTests(unittest.TestCase):
def test_wrong_func(self):
@types.coroutine
def foo():
pass
with self.assertRaisesRegex(TypeError,
'callable wrapped .* non-coroutine'):
foo()
return 'spam'
self.assertEqual(foo(), 'spam')
def test_async_def(self):
# Test that types.coroutine passes 'async def' coroutines
# without modification
async def foo(): pass
foo_code = foo.__code__
foo_flags = foo.__code__.co_flags
decorated_foo = types.coroutine(foo)
self.assertIs(foo, decorated_foo)
self.assertEqual(foo.__code__.co_flags, foo_flags)
self.assertIs(decorated_foo.__code__, foo_code)
foo_coro = foo()
@types.coroutine
def bar(): return foo_coro
coro = bar()
self.assertIs(foo_coro, coro)
self.assertEqual(coro.cr_code.co_flags, foo_flags)
coro.close()
def test_duck_coro(self):
class CoroLike:
@ -1221,6 +1239,23 @@ class CoroutineTests(unittest.TestCase):
@types.coroutine
def foo():
return coro
self.assertIs(foo(), coro)
self.assertIs(foo().__await__(), coro)
def test_duck_corogen(self):
class CoroGenLike:
def send(self): pass
def throw(self): pass
def close(self): pass
def __await__(self): return self
def __iter__(self): return self
def __next__(self): pass
coro = CoroGenLike()
@types.coroutine
def foo():
return coro
self.assertIs(foo(), coro)
self.assertIs(foo().__await__(), coro)
def test_duck_gen(self):
@ -1236,7 +1271,7 @@ class CoroutineTests(unittest.TestCase):
def foo():
return gen
self.assertIs(foo().__await__(), gen)
self.assertTrue(isinstance(foo(), collections.abc.Coroutine))
with self.assertRaises(AttributeError):
foo().gi_code
@ -1251,6 +1286,7 @@ class CoroutineTests(unittest.TestCase):
'gi_running', 'gi_frame'):
self.assertIs(getattr(foo(), name),
getattr(gen, name))
self.assertIs(foo().cr_code, gen.gi_code)
def test_genfunc(self):
def gen():
@ -1259,7 +1295,13 @@ class CoroutineTests(unittest.TestCase):
self.assertFalse(isinstance(gen(), collections.abc.Coroutine))
self.assertFalse(isinstance(gen(), collections.abc.Awaitable))
self.assertIs(types.coroutine(gen), gen)
gen_code = gen.__code__
decorated_gen = types.coroutine(gen)
self.assertIs(decorated_gen, gen)
self.assertIsNot(decorated_gen.__code__, gen_code)
decorated_gen2 = types.coroutine(decorated_gen)
self.assertIs(decorated_gen2.__code__, decorated_gen.__code__)
self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)

View File

@ -19,6 +19,11 @@ def _g():
yield 1
GeneratorType = type(_g())
async def _c(): pass
_c = _c()
CoroutineType = type(_c)
_c.close() # Prevent ResourceWarning
class _C:
def _m(self): pass
MethodType = type(_C()._m)
@ -40,7 +45,7 @@ except TypeError:
GetSetDescriptorType = type(FunctionType.__code__)
MemberDescriptorType = type(FunctionType.__globals__)
del sys, _f, _g, _C, # Not for export
del sys, _f, _g, _C, _c, # Not for export
# Provide a PEP 3115 compliant mechanism for class creation
@ -164,29 +169,33 @@ import collections.abc as _collections_abc
def coroutine(func):
"""Convert regular generator function to a coroutine."""
# We don't want to import 'dis' or 'inspect' just for
# these constants.
CO_GENERATOR = 0x20
CO_ITERABLE_COROUTINE = 0x100
if not callable(func):
raise TypeError('types.coroutine() expects a callable')
if (isinstance(func, FunctionType) and
isinstance(getattr(func, '__code__', None), CodeType) and
(func.__code__.co_flags & CO_GENERATOR)):
if (func.__class__ is FunctionType and
getattr(func, '__code__', None).__class__ is CodeType):
# TODO: Implement this in C.
co = func.__code__
func.__code__ = CodeType(
co.co_argcount, co.co_kwonlyargcount, co.co_nlocals,
co.co_stacksize,
co.co_flags | CO_ITERABLE_COROUTINE,
co.co_code,
co.co_consts, co.co_names, co.co_varnames, co.co_filename,
co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars,
co.co_cellvars)
return func
co_flags = func.__code__.co_flags
# Check if 'func' is a coroutine function.
# (0x180 == CO_COROUTINE | CO_ITERABLE_COROUTINE)
if co_flags & 0x180:
return func
# Check if 'func' is a generator function.
# (0x20 == CO_GENERATOR)
if co_flags & 0x20:
# TODO: Implement this in C.
co = func.__code__
func.__code__ = CodeType(
co.co_argcount, co.co_kwonlyargcount, co.co_nlocals,
co.co_stacksize,
co.co_flags | 0x100, # 0x100 == CO_ITERABLE_COROUTINE
co.co_code,
co.co_consts, co.co_names, co.co_varnames, co.co_filename,
co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars,
co.co_cellvars)
return func
# The following code is primarily to support functions that
# return generator-like objects (for instance generators
@ -195,11 +204,14 @@ def coroutine(func):
class GeneratorWrapper:
def __init__(self, gen):
self.__wrapped__ = gen
self.send = gen.send
self.throw = gen.throw
self.close = gen.close
self.__name__ = getattr(gen, '__name__', None)
self.__qualname__ = getattr(gen, '__qualname__', None)
def send(self, val):
return self.__wrapped__.send(val)
def throw(self, *args):
return self.__wrapped__.throw(*args)
def close(self):
return self.__wrapped__.close()
@property
def gi_code(self):
return self.__wrapped__.gi_code
@ -209,24 +221,31 @@ def coroutine(func):
@property
def gi_running(self):
return self.__wrapped__.gi_running
cr_code = gi_code
cr_frame = gi_frame
cr_running = gi_running
def __next__(self):
return next(self.__wrapped__)
def __iter__(self):
return self.__wrapped__
__await__ = __iter__
def __await__(self):
return self.__wrapped__
@_functools.wraps(func)
def wrapped(*args, **kwargs):
coro = func(*args, **kwargs)
if coro.__class__ is GeneratorType:
if coro.__class__ is CoroutineType:
# 'coro' is a native coroutine object.
return coro
if (coro.__class__ is GeneratorType or
(isinstance(coro, _collections_abc.Generator) and
not isinstance(coro, _collections_abc.Coroutine))):
# 'coro' is either a pure Python generator iterator, or it
# implements collections.abc.Generator (and does not implement
# collections.abc.Coroutine).
return GeneratorWrapper(coro)
# slow checks
if not isinstance(coro, _collections_abc.Coroutine):
if isinstance(coro, _collections_abc.Generator):
return GeneratorWrapper(coro)
raise TypeError(
'callable wrapped with types.coroutine() returned '
'non-coroutine: {!r}'.format(coro))
# 'coro' is either an instance of collections.abc.Coroutine or
# some other object -- pass it through.
return coro
return wrapped

View File

@ -12,6 +12,15 @@ Core and Builtins
- Issue #24345: Add Py_tp_finalize slot for the stable ABI.
- Issue #24400: Introduce a distinct type for PEP 492 coroutines; add
types.CoroutineType, inspect.getcoroutinestate, inspect.getcoroutinelocals;
coroutines no longer use CO_GENERATOR flag; sys.set_coroutine_wrapper
works only for 'async def' coroutines; inspect.iscoroutine no longer
uses collections.abc.Coroutine, it's intended to test for pure 'async def'
coroutines only; add new opcode: GET_YIELD_FROM_ITER; fix generators wrapper
used in types.coroutine to be instance of collections.abc.Generator.
Library
-------

View File

@ -27,8 +27,7 @@ _PyGen_Finalize(PyObject *self)
/* If `gen` is a coroutine, and if it was never awaited on,
issue a RuntimeWarning. */
if (gen->gi_code != NULL
&& ((PyCodeObject *)gen->gi_code)->co_flags & (CO_COROUTINE
| CO_ITERABLE_COROUTINE)
&& ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE
&& gen->gi_frame != NULL
&& gen->gi_frame->f_lasti == -1
&& !PyErr_Occurred()
@ -86,8 +85,10 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
PyObject *result;
if (gen->gi_running) {
PyErr_SetString(PyExc_ValueError,
"generator already executing");
char *msg = "generator already executing";
if (PyCoro_CheckExact(gen))
msg = "coroutine already executing";
PyErr_SetString(PyExc_ValueError, msg);
return NULL;
}
if (f == NULL || f->f_stacktop == NULL) {
@ -99,9 +100,12 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
if (f->f_lasti == -1) {
if (arg && arg != Py_None) {
PyErr_SetString(PyExc_TypeError,
"can't send non-None value to a "
"just-started generator");
char *msg = "can't send non-None value to a "
"just-started generator";
if (PyCoro_CheckExact(gen))
msg = "can't send non-None value to a "
"just-started coroutine";
PyErr_SetString(PyExc_TypeError, msg);
return NULL;
}
} else {
@ -151,14 +155,16 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
(CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
{
PyObject *exc, *val, *val2, *tb;
char *msg = "generator raised StopIteration";
if (PyCoro_CheckExact(gen))
msg = "coroutine raised StopIteration";
PyErr_Fetch(&exc, &val, &tb);
PyErr_NormalizeException(&exc, &val, &tb);
if (tb != NULL)
PyException_SetTraceback(val, tb);
Py_DECREF(exc);
Py_XDECREF(tb);
PyErr_SetString(PyExc_RuntimeError,
"generator raised StopIteration");
PyErr_SetString(PyExc_RuntimeError, msg);
PyErr_Fetch(&exc, &val2, &tb);
PyErr_NormalizeException(&exc, &val2, &tb);
Py_INCREF(val);
@ -288,9 +294,11 @@ gen_close(PyGenObject *gen, PyObject *args)
PyErr_SetNone(PyExc_GeneratorExit);
retval = gen_send_ex(gen, Py_None, 1);
if (retval) {
char *msg = "generator ignored GeneratorExit";
if (PyCoro_CheckExact(gen))
msg = "coroutine ignored GeneratorExit";
Py_DECREF(retval);
PyErr_SetString(PyExc_RuntimeError,
"generator ignored GeneratorExit");
PyErr_SetString(PyExc_RuntimeError, msg);
return NULL;
}
if (PyErr_ExceptionMatches(PyExc_StopIteration)
@ -432,12 +440,6 @@ failed_throw:
static PyObject *
gen_iternext(PyGenObject *gen)
{
if (((PyCodeObject*)gen->gi_code)->co_flags & CO_COROUTINE) {
PyErr_SetString(PyExc_TypeError,
"coroutine-objects do not support iteration");
return NULL;
}
return gen_send_ex(gen, NULL, 0);
}
@ -494,14 +496,8 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) {
static PyObject *
gen_repr(PyGenObject *gen)
{
if (PyGen_CheckCoroutineExact(gen)) {
return PyUnicode_FromFormat("<coroutine object %S at %p>",
gen->gi_qualname, gen);
}
else {
return PyUnicode_FromFormat("<generator object %S at %p>",
gen->gi_qualname, gen);
}
return PyUnicode_FromFormat("<generator object %S at %p>",
gen->gi_qualname, gen);
}
static PyObject *
@ -537,19 +533,6 @@ gen_get_qualname(PyGenObject *op)
return op->gi_qualname;
}
static PyObject *
gen_get_iter(PyGenObject *gen)
{
if (((PyCodeObject*)gen->gi_code)->co_flags & CO_COROUTINE) {
PyErr_SetString(PyExc_TypeError,
"coroutine-objects do not support iteration");
return NULL;
}
Py_INCREF(gen);
return (PyObject *)gen;
}
static int
gen_set_qualname(PyGenObject *op, PyObject *value)
{
@ -619,7 +602,7 @@ PyTypeObject PyGen_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
(getiterfunc)gen_get_iter, /* tp_iter */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)gen_iternext, /* tp_iternext */
gen_methods, /* tp_methods */
gen_memberlist, /* tp_members */
@ -645,10 +628,11 @@ PyTypeObject PyGen_Type = {
_PyGen_Finalize, /* tp_finalize */
};
PyObject *
PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
static PyObject *
gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f,
PyObject *name, PyObject *qualname)
{
PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
PyGenObject *gen = PyObject_GC_New(PyGenObject, type);
if (gen == NULL) {
Py_DECREF(f);
return NULL;
@ -673,10 +657,16 @@ PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
return (PyObject *)gen;
}
PyObject *
PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname)
{
return gen_new_with_qualname(&PyGen_Type, f, name, qualname);
}
PyObject *
PyGen_New(PyFrameObject *f)
{
return PyGen_NewWithQualName(f, NULL, NULL);
return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL);
}
int
@ -697,6 +687,25 @@ PyGen_NeedsFinalizing(PyGenObject *gen)
return 0;
}
/* Coroutine Object */
typedef struct {
PyObject_HEAD
PyCoroObject *cw_coroutine;
} PyCoroWrapper;
static int
gen_is_coroutine(PyObject *o)
{
if (PyGen_CheckExact(o)) {
PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
if (code->co_flags & CO_ITERABLE_COROUTINE) {
return 1;
}
}
return 0;
}
/*
* This helper function returns an awaitable for `o`:
* - `o` if `o` is a coroutine-object;
@ -706,13 +715,13 @@ PyGen_NeedsFinalizing(PyGenObject *gen)
* an awaitable and returns NULL.
*/
PyObject *
_PyGen_GetAwaitableIter(PyObject *o)
_PyCoro_GetAwaitableIter(PyObject *o)
{
unaryfunc getter = NULL;
PyTypeObject *ot;
if (PyGen_CheckCoroutineExact(o)) {
/* Fast path. It's a central function for 'await'. */
if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
/* 'o' is a coroutine. */
Py_INCREF(o);
return o;
}
@ -724,22 +733,19 @@ _PyGen_GetAwaitableIter(PyObject *o)
if (getter != NULL) {
PyObject *res = (*getter)(o);
if (res != NULL) {
if (!PyIter_Check(res)) {
if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
/* __await__ must return an *iterator*, not
a coroutine or another awaitable (see PEP 492) */
PyErr_SetString(PyExc_TypeError,
"__await__() returned a coroutine");
Py_CLEAR(res);
} else if (!PyIter_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__await__() returned non-iterator "
"of type '%.100s'",
Py_TYPE(res)->tp_name);
Py_CLEAR(res);
}
else {
if (PyGen_CheckCoroutineExact(res)) {
/* __await__ must return an *iterator*, not
a coroutine or another awaitable (see PEP 492) */
PyErr_SetString(PyExc_TypeError,
"__await__() returned a coroutine");
Py_CLEAR(res);
}
}
}
return res;
}
@ -747,6 +753,211 @@ _PyGen_GetAwaitableIter(PyObject *o)
PyErr_Format(PyExc_TypeError,
"object %.100s can't be used in 'await' expression",
ot->tp_name);
return NULL;
}
static PyObject *
coro_repr(PyCoroObject *coro)
{
return PyUnicode_FromFormat("<coroutine object %S at %p>",
coro->cr_qualname, coro);
}
static PyObject *
coro_await(PyCoroObject *coro)
{
PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type);
if (cw == NULL) {
return NULL;
}
Py_INCREF(coro);
cw->cw_coroutine = coro;
_PyObject_GC_TRACK(cw);
return (PyObject *)cw;
}
static PyGetSetDef coro_getsetlist[] = {
{"__name__", (getter)gen_get_name, (setter)gen_set_name,
PyDoc_STR("name of the coroutine")},
{"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname,
PyDoc_STR("qualified name of the coroutine")},
{NULL} /* Sentinel */
};
static PyMemberDef coro_memberlist[] = {
{"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
{"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY},
{"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
{NULL} /* Sentinel */
};
PyDoc_STRVAR(coro_send_doc,
"send(arg) -> send 'arg' into coroutine,\n\
return next yielded value or raise StopIteration.");
PyDoc_STRVAR(coro_throw_doc,
"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\
return next yielded value or raise StopIteration.");
PyDoc_STRVAR(coro_close_doc,
"close() -> raise GeneratorExit inside coroutine.");
static PyMethodDef coro_methods[] = {
{"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc},
{"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
{"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
{NULL, NULL} /* Sentinel */
};
static PyAsyncMethods coro_as_async = {
(unaryfunc)coro_await, /* am_await */
0, /* am_aiter */
0 /* am_anext */
};
PyTypeObject PyCoro_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"coroutine", /* tp_name */
sizeof(PyCoroObject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)gen_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
&coro_as_async, /* tp_as_async */
(reprfunc)coro_repr, /* 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 |
Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
coro_methods, /* tp_methods */
coro_memberlist, /* tp_members */
coro_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0, /* tp_del */
0, /* tp_version_tag */
_PyGen_Finalize, /* tp_finalize */
};
static void
coro_wrapper_dealloc(PyCoroWrapper *cw)
{
_PyObject_GC_UNTRACK((PyObject *)cw);
Py_CLEAR(cw->cw_coroutine);
PyObject_GC_Del(cw);
}
static PyObject *
coro_wrapper_iternext(PyCoroWrapper *cw)
{
return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0);
}
static PyObject *
coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
{
return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0);
}
static PyObject *
coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
{
return gen_throw((PyGenObject *)cw->cw_coroutine, args);
}
static PyObject *
coro_wrapper_close(PyCoroWrapper *cw, PyObject *args)
{
return gen_close((PyGenObject *)cw->cw_coroutine, args);
}
static int
coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
{
Py_VISIT((PyObject *)cw->cw_coroutine);
return 0;
}
static PyMethodDef coro_wrapper_methods[] = {
{"send",(PyCFunction)coro_wrapper_send, METH_O, send_doc},
{"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, throw_doc},
{"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, close_doc},
{NULL, NULL} /* Sentinel */
};
PyTypeObject _PyCoroWrapper_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"coroutine_wrapper",
sizeof(PyCoroWrapper), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* 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 */
"A wrapper object implementing __await__ for coroutines.",
(traverseproc)coro_wrapper_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)coro_wrapper_iternext, /* tp_iternext */
coro_wrapper_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
PyObject_Del, /* tp_free */
};
PyObject *
PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
{
return gen_new_with_qualname(&PyCoro_Type, f, name, qualname);
}

View File

@ -1726,6 +1726,12 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PySeqIter_Type) < 0)
Py_FatalError("Can't initialize sequence iterator type");
if (PyType_Ready(&PyCoro_Type) < 0)
Py_FatalError("Can't initialize coroutine type");
if (PyType_Ready(&_PyCoroWrapper_Type) < 0)
Py_FatalError("Can't initialize coroutine wrapper type");
}

View File

@ -1191,7 +1191,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
f->f_executing = 1;
if (co->co_flags & CO_GENERATOR) {
if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) {
if (!throwflag && f->f_exc_type != NULL && f->f_exc_type != Py_None) {
/* We were in an except handler when we left,
restore the exception state which was put aside
@ -1955,7 +1955,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
goto error;
}
awaitable = _PyGen_GetAwaitableIter(iter);
awaitable = _PyCoro_GetAwaitableIter(iter);
if (awaitable == NULL) {
SET_TOP(NULL);
PyErr_Format(
@ -1998,7 +1998,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
goto error;
}
awaitable = _PyGen_GetAwaitableIter(next_iter);
awaitable = _PyCoro_GetAwaitableIter(next_iter);
if (awaitable == NULL) {
PyErr_Format(
PyExc_TypeError,
@ -2017,7 +2017,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
TARGET(GET_AWAITABLE) {
PyObject *iterable = TOP();
PyObject *iter = _PyGen_GetAwaitableIter(iterable);
PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
Py_DECREF(iterable);
@ -2034,25 +2034,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
PyObject *v = POP();
PyObject *reciever = TOP();
int err;
if (PyGen_CheckExact(reciever)) {
if (
(((PyCodeObject*) \
((PyGenObject*)reciever)->gi_code)->co_flags &
CO_COROUTINE)
&& !(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE)))
{
/* If we're yielding-from a coroutine object from a regular
generator object - raise an error. */
Py_CLEAR(v);
Py_CLEAR(reciever);
SET_TOP(NULL);
PyErr_SetString(PyExc_TypeError,
"cannot 'yield from' a coroutine object "
"from a generator");
goto error;
}
if (PyGen_CheckExact(reciever) || PyCoro_CheckExact(reciever)) {
retval = _PyGen_Send((PyGenObject *)reciever, v);
} else {
_Py_IDENTIFIER(send);
@ -2927,21 +2909,35 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}
TARGET(GET_ITER) {
/* before: [obj]; after [getiter(obj)] */
PyObject *iterable = TOP();
PyObject *iter = PyObject_GetIter(iterable);
Py_DECREF(iterable);
SET_TOP(iter);
if (iter == NULL)
goto error;
PREDICT(FOR_ITER);
DISPATCH();
}
TARGET(GET_YIELD_FROM_ITER) {
/* before: [obj]; after [getiter(obj)] */
PyObject *iterable = TOP();
PyObject *iter;
/* If we have a generator object on top -- keep it there,
it's already an iterator.
This is needed to allow use of 'async def' coroutines
in 'yield from' expression from generator-based coroutines
(decorated with types.coroutine()).
'yield from' is compiled to GET_ITER..YIELD_FROM combination,
but since coroutines raise TypeError in their 'tp_iter' we
need a way for them to "pass through" the GET_ITER.
*/
if (!PyGen_CheckExact(iterable)) {
if (PyCoro_CheckExact(iterable)) {
/* `iterable` is a coroutine */
if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
/* and it is used in a 'yield from' expression of a
regular generator. */
Py_DECREF(iterable);
SET_TOP(NULL);
PyErr_SetString(PyExc_TypeError,
"cannot 'yield from' a coroutine object "
"in a non-coroutine generator");
goto error;
}
}
else if (!PyGen_CheckExact(iterable)) {
/* `iterable` is not a generator. */
iter = PyObject_GetIter(iterable);
Py_DECREF(iterable);
@ -2949,7 +2945,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
if (iter == NULL)
goto error;
}
PREDICT(FOR_ITER);
DISPATCH();
}
@ -3517,7 +3512,7 @@ fast_block_end:
assert((retval != NULL) ^ (PyErr_Occurred() != NULL));
fast_yield:
if (co->co_flags & CO_GENERATOR) {
if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) {
/* The purpose of this block is to put aside the generator's exception
state and restore that of the calling frame. If the current
@ -3919,10 +3914,10 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
}
if (co->co_flags & CO_GENERATOR) {
if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) {
PyObject *gen;
PyObject *coro_wrapper = tstate->coroutine_wrapper;
int is_coro = co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE);
int is_coro = co->co_flags & CO_COROUTINE;
if (is_coro && tstate->in_coroutine_wrapper) {
assert(coro_wrapper != NULL);
@ -3942,7 +3937,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
/* Create a new generator that owns the ready to run frame
* and return that as the value. */
gen = PyGen_NewWithQualName(f, name, qualname);
if (is_coro) {
gen = PyCoro_New(f, name, qualname);
} else {
gen = PyGen_NewWithQualName(f, name, qualname);
}
if (gen == NULL)
return NULL;

View File

@ -1064,6 +1064,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
return 0;
case GET_ANEXT:
return 1;
case GET_YIELD_FROM_ITER:
return 0;
default:
return PY_INVALID_STACK_EFFECT;
}
@ -1751,12 +1753,8 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
Py_DECREF(qualname);
Py_DECREF(co);
if (is_async) {
if (is_async)
co->co_flags |= CO_COROUTINE;
/* An async function is always a generator, even
if there is no 'yield' expressions in it. */
co->co_flags |= CO_GENERATOR;
}
/* decorators */
for (i = 0; i < asdl_seq_LEN(decos); i++) {
@ -3850,7 +3848,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
return compiler_error(c, "'yield from' inside async function");
VISIT(c, expr, e->v.YieldFrom.value);
ADDOP(c, GET_ITER);
ADDOP(c, GET_YIELD_FROM_ITER);
ADDOP_O(c, LOAD_CONST, Py_None, consts);
ADDOP(c, YIELD_FROM);
break;

View File

@ -259,7 +259,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,5,0,0,0,218,13,95,119,114,105,116,101,95,
97,116,111,109,105,99,99,0,0,0,115,26,0,0,0,0,
5,24,1,9,1,33,1,3,3,21,1,20,1,20,1,13,
1,3,1,17,1,13,1,5,1,114,55,0,0,0,105,12,
1,3,1,17,1,13,1,5,1,114,55,0,0,0,105,22,
13,0,0,233,2,0,0,0,114,13,0,0,0,115,2,0,
0,0,13,10,90,11,95,95,112,121,99,97,99,104,101,95,
95,122,4,111,112,116,45,122,3,46,112,121,122,4,46,112,
@ -369,7 +369,7 @@ const unsigned char _Py_M__importlib_external[] = {
116,97,103,90,15,97,108,109,111,115,116,95,102,105,108,101,
110,97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,218,17,99,97,99,104,101,95,102,114,111,109,95,
115,111,117,114,99,101,242,0,0,0,115,46,0,0,0,0,
115,111,117,114,99,101,243,0,0,0,115,46,0,0,0,0,
18,12,1,9,1,7,1,12,1,6,1,12,1,18,1,18,
1,24,1,12,1,12,1,12,1,36,1,12,1,18,1,9,
2,12,1,12,1,12,1,12,1,21,1,21,1,114,79,0,
@ -448,7 +448,7 @@ const unsigned char _Py_M__importlib_external[] = {
95,108,101,118,101,108,90,13,98,97,115,101,95,102,105,108,
101,110,97,109,101,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,17,115,111,117,114,99,101,95,102,114,111,
109,95,99,97,99,104,101,30,1,0,0,115,44,0,0,0,
109,95,99,97,99,104,101,31,1,0,0,115,44,0,0,0,
0,9,18,1,12,1,18,1,18,1,12,1,9,1,15,1,
15,1,12,1,9,1,15,1,12,1,22,1,15,1,9,1,
12,1,22,1,12,1,9,1,12,1,19,1,114,85,0,0,
@ -486,7 +486,7 @@ const unsigned char _Py_M__importlib_external[] = {
115,105,111,110,218,11,115,111,117,114,99,101,95,112,97,116,
104,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
218,15,95,103,101,116,95,115,111,117,114,99,101,102,105,108,
101,63,1,0,0,115,20,0,0,0,0,7,18,1,4,1,
101,64,1,0,0,115,20,0,0,0,0,7,18,1,4,1,
24,1,35,1,4,1,3,1,16,1,19,1,21,1,114,91,
0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0,
11,0,0,0,67,0,0,0,115,92,0,0,0,124,0,0,
@ -500,7 +500,7 @@ const unsigned char _Py_M__importlib_external[] = {
84,0,0,0,114,79,0,0,0,114,66,0,0,0,114,74,
0,0,0,41,1,218,8,102,105,108,101,110,97,109,101,114,
4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,11,
95,103,101,116,95,99,97,99,104,101,100,82,1,0,0,115,
95,103,101,116,95,99,97,99,104,101,100,83,1,0,0,115,
16,0,0,0,0,1,21,1,3,1,14,1,13,1,8,1,
21,1,4,2,114,95,0,0,0,99,1,0,0,0,0,0,
0,0,2,0,0,0,11,0,0,0,67,0,0,0,115,60,
@ -515,7 +515,7 @@ const unsigned char _Py_M__importlib_external[] = {
41,3,114,39,0,0,0,114,41,0,0,0,114,40,0,0,
0,41,2,114,35,0,0,0,114,42,0,0,0,114,4,0,
0,0,114,4,0,0,0,114,5,0,0,0,218,10,95,99,
97,108,99,95,109,111,100,101,94,1,0,0,115,12,0,0,
97,108,99,95,109,111,100,101,95,1,0,0,115,12,0,0,
0,0,2,3,1,19,1,13,1,11,3,10,1,114,97,0,
0,0,218,9,118,101,114,98,111,115,105,116,121,114,29,0,
0,0,99,1,0,0,0,1,0,0,0,3,0,0,0,4,
@ -536,7 +536,7 @@ const unsigned char _Py_M__importlib_external[] = {
218,6,115,116,100,101,114,114,41,3,114,75,0,0,0,114,
98,0,0,0,218,4,97,114,103,115,114,4,0,0,0,114,
4,0,0,0,114,5,0,0,0,218,16,95,118,101,114,98,
111,115,101,95,109,101,115,115,97,103,101,106,1,0,0,115,
111,115,101,95,109,101,115,115,97,103,101,107,1,0,0,115,
8,0,0,0,0,2,18,1,15,1,10,1,114,105,0,0,
0,99,1,0,0,0,0,0,0,0,3,0,0,0,11,0,
0,0,3,0,0,0,115,84,0,0,0,100,1,0,135,0,
@ -576,7 +576,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,90,6,107,119,97,114,103,115,41,1,218,6,109,101,
116,104,111,100,114,4,0,0,0,114,5,0,0,0,218,19,
95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,
112,101,114,122,1,0,0,115,12,0,0,0,0,1,12,1,
112,101,114,123,1,0,0,115,12,0,0,0,0,1,12,1,
12,1,15,1,6,1,25,1,122,40,95,99,104,101,99,107,
95,110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,
99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,112,
@ -595,7 +595,7 @@ const unsigned char _Py_M__importlib_external[] = {
116,97,116,116,114,218,8,95,95,100,105,99,116,95,95,218,
6,117,112,100,97,116,101,41,3,90,3,110,101,119,90,3,
111,108,100,114,52,0,0,0,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,218,5,95,119,114,97,112,133,1,
0,0,114,5,0,0,0,218,5,95,119,114,97,112,134,1,
0,0,115,8,0,0,0,0,1,25,1,15,1,29,1,122,
26,95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,
99,97,108,115,62,46,95,119,114,97,112,41,3,218,10,95,
@ -603,7 +603,7 @@ const unsigned char _Py_M__importlib_external[] = {
78,97,109,101,69,114,114,111,114,41,3,114,109,0,0,0,
114,110,0,0,0,114,120,0,0,0,114,4,0,0,0,41,
1,114,109,0,0,0,114,5,0,0,0,218,11,95,99,104,
101,99,107,95,110,97,109,101,114,1,0,0,115,14,0,0,
101,99,107,95,110,97,109,101,115,1,0,0,115,14,0,0,
0,0,8,21,7,3,1,13,1,13,2,17,5,13,1,114,
123,0,0,0,99,2,0,0,0,0,0,0,0,5,0,0,
0,4,0,0,0,67,0,0,0,115,84,0,0,0,124,0,
@ -633,7 +633,7 @@ const unsigned char _Py_M__importlib_external[] = {
218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114,
4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,17,
95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105,
109,142,1,0,0,115,10,0,0,0,0,10,21,1,24,1,
109,143,1,0,0,115,10,0,0,0,0,10,21,1,24,1,
6,1,29,1,114,130,0,0,0,99,4,0,0,0,0,0,
0,0,11,0,0,0,19,0,0,0,67,0,0,0,115,228,
1,0,0,105,0,0,125,4,0,124,2,0,100,1,0,107,
@ -717,7 +717,7 @@ const unsigned char _Py_M__importlib_external[] = {
109,101,218,11,115,111,117,114,99,101,95,115,105,122,101,114,
4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,25,
95,118,97,108,105,100,97,116,101,95,98,121,116,101,99,111,
100,101,95,104,101,97,100,101,114,159,1,0,0,115,76,0,
100,101,95,104,101,97,100,101,114,160,1,0,0,115,76,0,
0,0,0,11,6,1,12,1,13,3,6,1,12,1,10,1,
16,1,16,1,16,1,12,1,18,1,10,1,18,1,18,1,
15,1,10,1,15,1,18,1,15,1,10,1,12,1,12,1,
@ -748,7 +748,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,106,0,0,0,114,89,0,0,0,114,90,0,0,0,218,
4,99,111,100,101,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,17,95,99,111,109,112,105,108,101,95,98,
121,116,101,99,111,100,101,214,1,0,0,115,16,0,0,0,
121,116,101,99,111,100,101,215,1,0,0,115,16,0,0,0,
0,2,15,1,15,1,13,1,12,1,16,1,4,2,18,1,
114,147,0,0,0,114,59,0,0,0,99,3,0,0,0,0,
0,0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,
@ -768,7 +768,7 @@ const unsigned char _Py_M__importlib_external[] = {
4,114,146,0,0,0,114,133,0,0,0,114,140,0,0,0,
114,53,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,17,95,99,111,100,101,95,116,111,95,98,
121,116,101,99,111,100,101,226,1,0,0,115,10,0,0,0,
121,116,101,99,111,100,101,227,1,0,0,115,10,0,0,0,
0,3,12,1,19,1,19,1,22,1,114,150,0,0,0,99,
1,0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,
67,0,0,0,115,89,0,0,0,100,1,0,100,2,0,108,
@ -797,7 +797,7 @@ const unsigned char _Py_M__importlib_external[] = {
100,105,110,103,90,15,110,101,119,108,105,110,101,95,100,101,
99,111,100,101,114,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,13,100,101,99,111,100,101,95,115,111,117,
114,99,101,236,1,0,0,115,10,0,0,0,0,5,12,1,
114,99,101,237,1,0,0,115,10,0,0,0,0,5,12,1,
18,1,15,1,18,1,114,155,0,0,0,114,127,0,0,0,
218,26,115,117,98,109,111,100,117,108,101,95,115,101,97,114,
99,104,95,108,111,99,97,116,105,111,110,115,99,2,0,0,
@ -862,7 +862,7 @@ const unsigned char _Py_M__importlib_external[] = {
159,0,0,0,90,7,100,105,114,110,97,109,101,114,4,0,
0,0,114,4,0,0,0,114,5,0,0,0,218,23,115,112,
101,99,95,102,114,111,109,95,102,105,108,101,95,108,111,99,
97,116,105,111,110,253,1,0,0,115,60,0,0,0,0,12,
97,116,105,111,110,254,1,0,0,115,60,0,0,0,0,12,
12,4,6,1,15,2,3,1,19,1,13,1,5,8,24,1,
9,3,12,1,22,1,21,1,15,1,9,1,5,2,4,3,
12,2,15,1,3,1,19,1,13,1,5,2,6,1,12,2,
@ -902,7 +902,7 @@ const unsigned char _Py_M__importlib_external[] = {
79,67,65,76,95,77,65,67,72,73,78,69,41,2,218,3,
99,108,115,218,3,107,101,121,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,218,14,95,111,112,101,110,95,114,
101,103,105,115,116,114,121,75,2,0,0,115,8,0,0,0,
101,103,105,115,116,114,121,76,2,0,0,115,8,0,0,0,
0,2,3,1,23,1,13,1,122,36,87,105,110,100,111,119,
115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,
95,111,112,101,110,95,114,101,103,105,115,116,114,121,99,2,
@ -929,7 +929,7 @@ const unsigned char _Py_M__importlib_external[] = {
171,0,0,0,90,4,104,107,101,121,218,8,102,105,108,101,
112,97,116,104,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,218,16,95,115,101,97,114,99,104,95,114,101,103,
105,115,116,114,121,82,2,0,0,115,22,0,0,0,0,2,
105,115,116,114,121,83,2,0,0,115,22,0,0,0,0,2,
9,1,12,2,9,1,15,1,22,1,3,1,18,1,29,1,
13,1,9,1,122,38,87,105,110,100,111,119,115,82,101,103,
105,115,116,114,121,70,105,110,100,101,114,46,95,115,101,97,
@ -953,7 +953,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,35,0,0,0,218,6,116,97,114,103,101,116,114,177,0,
0,0,114,127,0,0,0,114,166,0,0,0,114,164,0,0,
0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
218,9,102,105,110,100,95,115,112,101,99,97,2,0,0,115,
218,9,102,105,110,100,95,115,112,101,99,98,2,0,0,115,
26,0,0,0,0,2,15,1,12,1,4,1,3,1,14,1,
13,1,9,1,22,1,21,1,9,1,15,1,9,1,122,31,
87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,
@ -973,7 +973,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,0,41,4,114,170,0,0,0,114,126,0,0,0,114,
35,0,0,0,114,164,0,0,0,114,4,0,0,0,114,4,
0,0,0,114,5,0,0,0,218,11,102,105,110,100,95,109,
111,100,117,108,101,113,2,0,0,115,8,0,0,0,0,7,
111,100,117,108,101,114,2,0,0,115,8,0,0,0,0,7,
18,1,12,1,7,2,122,33,87,105,110,100,111,119,115,82,
101,103,105,115,116,114,121,70,105,110,100,101,114,46,102,105,
110,100,95,109,111,100,117,108,101,41,12,114,112,0,0,0,
@ -982,7 +982,7 @@ const unsigned char _Py_M__importlib_external[] = {
99,108,97,115,115,109,101,116,104,111,100,114,172,0,0,0,
114,178,0,0,0,114,181,0,0,0,114,182,0,0,0,114,
4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,114,168,0,0,0,63,2,0,0,115,20,0,0,
0,0,0,114,168,0,0,0,64,2,0,0,115,20,0,0,
0,12,2,6,3,6,3,6,2,6,2,18,7,18,15,3,
1,21,15,3,1,114,168,0,0,0,99,0,0,0,0,0,
0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,
@ -1020,7 +1020,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,0,114,94,0,0,0,90,13,102,105,108,101,110,97,
109,101,95,98,97,115,101,90,9,116,97,105,108,95,110,97,
109,101,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
0,114,159,0,0,0,132,2,0,0,115,8,0,0,0,0,
0,114,159,0,0,0,133,2,0,0,115,8,0,0,0,0,
3,25,1,22,1,19,1,122,24,95,76,111,97,100,101,114,
66,97,115,105,99,115,46,105,115,95,112,97,99,107,97,103,
101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,
@ -1030,7 +1030,7 @@ const unsigned char _Py_M__importlib_external[] = {
117,108,101,32,99,114,101,97,116,105,111,110,46,78,114,4,
0,0,0,41,2,114,108,0,0,0,114,164,0,0,0,114,
4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,13,
99,114,101,97,116,101,95,109,111,100,117,108,101,140,2,0,
99,114,101,97,116,101,95,109,111,100,117,108,101,141,2,0,
0,115,0,0,0,0,122,27,95,76,111,97,100,101,114,66,
97,115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,
117,108,101,99,2,0,0,0,0,0,0,0,3,0,0,0,
@ -1052,7 +1052,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,41,3,114,108,0,0,0,218,6,109,111,100,117,108,101,
114,146,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,11,101,120,101,99,95,109,111,100,117,108,
101,143,2,0,0,115,10,0,0,0,0,2,18,1,12,1,
101,144,2,0,0,115,10,0,0,0,0,2,18,1,12,1,
9,1,15,1,122,25,95,76,111,97,100,101,114,66,97,115,
105,99,115,46,101,120,101,99,95,109,111,100,117,108,101,99,
2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
@ -1061,14 +1061,14 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,0,218,17,95,108,111,97,100,95,109,111,100,117,108,
101,95,115,104,105,109,41,2,114,108,0,0,0,114,126,0,
0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
0,218,11,108,111,97,100,95,109,111,100,117,108,101,151,2,
0,218,11,108,111,97,100,95,109,111,100,117,108,101,152,2,
0,0,115,2,0,0,0,0,1,122,25,95,76,111,97,100,
101,114,66,97,115,105,99,115,46,108,111,97,100,95,109,111,
100,117,108,101,78,41,8,114,112,0,0,0,114,111,0,0,
0,114,113,0,0,0,114,114,0,0,0,114,159,0,0,0,
114,186,0,0,0,114,191,0,0,0,114,193,0,0,0,114,
4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,114,184,0,0,0,127,2,0,0,115,10,0,0,
0,0,0,114,184,0,0,0,128,2,0,0,115,10,0,0,
0,12,3,6,2,12,8,12,3,12,8,114,184,0,0,0,
99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
0,64,0,0,0,115,106,0,0,0,101,0,0,90,1,0,
@ -1096,7 +1096,7 @@ const unsigned char _Py_M__importlib_external[] = {
1,218,7,73,79,69,114,114,111,114,41,2,114,108,0,0,
0,114,35,0,0,0,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,10,112,97,116,104,95,109,116,105,109,
101,157,2,0,0,115,2,0,0,0,0,6,122,23,83,111,
101,158,2,0,0,115,2,0,0,0,0,6,122,23,83,111,
117,114,99,101,76,111,97,100,101,114,46,112,97,116,104,95,
109,116,105,109,101,99,2,0,0,0,0,0,0,0,2,0,
0,0,3,0,0,0,67,0,0,0,115,19,0,0,0,100,
@ -1131,7 +1131,7 @@ const unsigned char _Py_M__importlib_external[] = {
32,32,32,114,133,0,0,0,41,1,114,196,0,0,0,41,
2,114,108,0,0,0,114,35,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,5,0,0,0,218,10,112,97,116,104,
95,115,116,97,116,115,165,2,0,0,115,2,0,0,0,0,
95,115,116,97,116,115,166,2,0,0,115,2,0,0,0,0,
11,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46,
112,97,116,104,95,115,116,97,116,115,99,4,0,0,0,0,
0,0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,
@ -1155,7 +1155,7 @@ const unsigned char _Py_M__importlib_external[] = {
90,0,0,0,90,10,99,97,99,104,101,95,112,97,116,104,
114,53,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,15,95,99,97,99,104,101,95,98,121,116,
101,99,111,100,101,178,2,0,0,115,2,0,0,0,0,8,
101,99,111,100,101,179,2,0,0,115,2,0,0,0,0,8,
122,28,83,111,117,114,99,101,76,111,97,100,101,114,46,95,
99,97,99,104,101,95,98,121,116,101,99,111,100,101,99,3,
0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,67,
@ -1172,7 +1172,7 @@ const unsigned char _Py_M__importlib_external[] = {
32,32,32,32,32,32,78,114,4,0,0,0,41,3,114,108,
0,0,0,114,35,0,0,0,114,53,0,0,0,114,4,0,
0,0,114,4,0,0,0,114,5,0,0,0,114,198,0,0,
0,188,2,0,0,115,0,0,0,0,122,21,83,111,117,114,
0,189,2,0,0,115,0,0,0,0,122,21,83,111,117,114,
99,101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,
97,99,2,0,0,0,0,0,0,0,5,0,0,0,16,0,
0,0,67,0,0,0,115,105,0,0,0,124,0,0,106,0,
@ -1194,7 +1194,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,126,0,0,0,114,35,0,0,0,114,153,0,0,
0,218,3,101,120,99,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,10,103,101,116,95,115,111,117,114,99,
101,195,2,0,0,115,14,0,0,0,0,2,15,1,3,1,
101,196,2,0,0,115,14,0,0,0,0,2,15,1,3,1,
19,1,18,1,9,1,31,1,122,23,83,111,117,114,99,101,
76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99,
101,218,9,95,111,112,116,105,109,105,122,101,114,29,0,0,
@ -1216,7 +1216,7 @@ const unsigned char _Py_M__importlib_external[] = {
101,41,4,114,108,0,0,0,114,53,0,0,0,114,35,0,
0,0,114,203,0,0,0,114,4,0,0,0,114,4,0,0,
0,114,5,0,0,0,218,14,115,111,117,114,99,101,95,116,
111,95,99,111,100,101,205,2,0,0,115,4,0,0,0,0,
111,95,99,111,100,101,206,2,0,0,115,4,0,0,0,0,
5,21,1,122,27,83,111,117,114,99,101,76,111,97,100,101,
114,46,115,111,117,114,99,101,95,116,111,95,99,111,100,101,
99,2,0,0,0,0,0,0,0,10,0,0,0,43,0,0,
@ -1277,7 +1277,7 @@ const unsigned char _Py_M__importlib_external[] = {
98,121,116,101,115,95,100,97,116,97,114,153,0,0,0,90,
11,99,111,100,101,95,111,98,106,101,99,116,114,4,0,0,
0,114,4,0,0,0,114,5,0,0,0,114,187,0,0,0,
213,2,0,0,115,78,0,0,0,0,7,15,1,6,1,3,
214,2,0,0,115,78,0,0,0,0,7,15,1,6,1,3,
1,16,1,13,1,11,2,3,1,19,1,13,1,5,2,16,
1,3,1,19,1,13,1,5,2,3,1,9,1,12,1,13,
1,19,1,5,2,9,1,7,1,15,1,6,1,7,1,15,
@ -1289,7 +1289,7 @@ const unsigned char _Py_M__importlib_external[] = {
199,0,0,0,114,198,0,0,0,114,202,0,0,0,114,206,
0,0,0,114,187,0,0,0,114,4,0,0,0,114,4,0,
0,0,114,4,0,0,0,114,5,0,0,0,114,194,0,0,
0,155,2,0,0,115,14,0,0,0,12,2,12,8,12,13,
0,156,2,0,0,115,14,0,0,0,12,2,12,8,12,13,
12,10,12,7,12,10,18,8,114,194,0,0,0,99,0,0,
0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,
0,0,115,112,0,0,0,101,0,0,90,1,0,100,0,0,
@ -1317,7 +1317,7 @@ const unsigned char _Py_M__importlib_external[] = {
32,32,32,32,32,32,102,105,110,100,101,114,46,78,41,2,
114,106,0,0,0,114,35,0,0,0,41,3,114,108,0,0,
0,114,126,0,0,0,114,35,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,5,0,0,0,114,185,0,0,0,14,
114,4,0,0,0,114,5,0,0,0,114,185,0,0,0,15,
3,0,0,115,4,0,0,0,0,3,9,1,122,19,70,105,
108,101,76,111,97,100,101,114,46,95,95,105,110,105,116,95,
95,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0,
@ -1327,7 +1327,7 @@ const unsigned char _Py_M__importlib_external[] = {
41,2,218,9,95,95,99,108,97,115,115,95,95,114,118,0,
0,0,41,2,114,108,0,0,0,218,5,111,116,104,101,114,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,
6,95,95,101,113,95,95,20,3,0,0,115,4,0,0,0,
6,95,95,101,113,95,95,21,3,0,0,115,4,0,0,0,
0,1,18,1,122,17,70,105,108,101,76,111,97,100,101,114,
46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,0,
1,0,0,0,3,0,0,0,67,0,0,0,115,26,0,0,
@ -1336,7 +1336,7 @@ const unsigned char _Py_M__importlib_external[] = {
218,4,104,97,115,104,114,106,0,0,0,114,35,0,0,0,
41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,0,
0,114,5,0,0,0,218,8,95,95,104,97,115,104,95,95,
24,3,0,0,115,2,0,0,0,0,1,122,19,70,105,108,
25,3,0,0,115,2,0,0,0,0,1,122,19,70,105,108,
101,76,111,97,100,101,114,46,95,95,104,97,115,104,95,95,
99,2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,
0,3,0,0,0,115,22,0,0,0,116,0,0,116,1,0,
@ -1350,7 +1350,7 @@ const unsigned char _Py_M__importlib_external[] = {
32,32,32,32,32,32,32,32,41,3,218,5,115,117,112,101,
114,114,210,0,0,0,114,193,0,0,0,41,2,114,108,0,
0,0,114,126,0,0,0,41,1,114,211,0,0,0,114,4,
0,0,0,114,5,0,0,0,114,193,0,0,0,27,3,0,
0,0,0,114,5,0,0,0,114,193,0,0,0,28,3,0,
0,115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,
97,100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,
99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,
@ -1361,7 +1361,7 @@ const unsigned char _Py_M__importlib_external[] = {
32,98,121,32,116,104,101,32,102,105,110,100,101,114,46,41,
1,114,35,0,0,0,41,2,114,108,0,0,0,114,126,0,
0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
0,114,157,0,0,0,39,3,0,0,115,2,0,0,0,0,
0,114,157,0,0,0,40,3,0,0,115,2,0,0,0,0,
3,122,23,70,105,108,101,76,111,97,100,101,114,46,103,101,
116,95,102,105,108,101,110,97,109,101,99,2,0,0,0,0,
0,0,0,3,0,0,0,9,0,0,0,67,0,0,0,115,
@ -1374,14 +1374,14 @@ const unsigned char _Py_M__importlib_external[] = {
49,0,0,0,114,50,0,0,0,90,4,114,101,97,100,41,
3,114,108,0,0,0,114,35,0,0,0,114,54,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
200,0,0,0,44,3,0,0,115,4,0,0,0,0,2,21,
200,0,0,0,45,3,0,0,115,4,0,0,0,0,2,21,
1,122,19,70,105,108,101,76,111,97,100,101,114,46,103,101,
116,95,100,97,116,97,41,11,114,112,0,0,0,114,111,0,
0,0,114,113,0,0,0,114,114,0,0,0,114,185,0,0,
0,114,213,0,0,0,114,215,0,0,0,114,123,0,0,0,
114,193,0,0,0,114,157,0,0,0,114,200,0,0,0,114,
4,0,0,0,114,4,0,0,0,41,1,114,211,0,0,0,
114,5,0,0,0,114,210,0,0,0,9,3,0,0,115,14,
114,5,0,0,0,114,210,0,0,0,10,3,0,0,115,14,
0,0,0,12,3,6,2,12,6,12,4,12,3,24,12,18,
5,114,210,0,0,0,99,0,0,0,0,0,0,0,0,0,
0,0,0,4,0,0,0,64,0,0,0,115,64,0,0,0,
@ -1404,7 +1404,7 @@ const unsigned char _Py_M__importlib_external[] = {
3,114,39,0,0,0,218,8,115,116,95,109,116,105,109,101,
90,7,115,116,95,115,105,122,101,41,3,114,108,0,0,0,
114,35,0,0,0,114,208,0,0,0,114,4,0,0,0,114,
4,0,0,0,114,5,0,0,0,114,197,0,0,0,54,3,
4,0,0,0,114,5,0,0,0,114,197,0,0,0,55,3,
0,0,115,4,0,0,0,0,2,12,1,122,27,83,111,117,
114,99,101,70,105,108,101,76,111,97,100,101,114,46,112,97,
116,104,95,115,116,97,116,115,99,4,0,0,0,0,0,0,
@ -1415,7 +1415,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,97,0,0,0,114,198,0,0,0,41,5,114,108,0,0,
0,114,90,0,0,0,114,89,0,0,0,114,53,0,0,0,
114,42,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,199,0,0,0,59,3,0,0,115,4,0,
5,0,0,0,114,199,0,0,0,60,3,0,0,115,4,0,
0,0,0,2,12,1,122,32,83,111,117,114,99,101,70,105,
108,101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,
98,121,116,101,99,111,100,101,114,220,0,0,0,105,182,1,
@ -1453,7 +1453,7 @@ const unsigned char _Py_M__importlib_external[] = {
53,0,0,0,114,220,0,0,0,218,6,112,97,114,101,110,
116,114,94,0,0,0,114,27,0,0,0,114,23,0,0,0,
114,201,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,198,0,0,0,64,3,0,0,115,38,0,
5,0,0,0,114,198,0,0,0,65,3,0,0,115,38,0,
0,0,0,2,18,1,6,2,22,1,18,1,17,2,19,1,
15,1,3,1,17,1,13,2,7,1,18,3,16,1,27,1,
3,1,16,1,17,1,18,2,122,25,83,111,117,114,99,101,
@ -1462,7 +1462,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,113,0,0,0,114,114,0,0,0,114,197,0,0,0,114,
199,0,0,0,114,198,0,0,0,114,4,0,0,0,114,4,
0,0,0,114,4,0,0,0,114,5,0,0,0,114,218,0,
0,0,50,3,0,0,115,8,0,0,0,12,2,6,2,12,
0,0,51,3,0,0,115,8,0,0,0,12,2,6,2,12,
5,12,5,114,218,0,0,0,99,0,0,0,0,0,0,0,
0,0,0,0,0,2,0,0,0,64,0,0,0,115,46,0,
0,0,101,0,0,90,1,0,100,0,0,90,2,0,100,1,
@ -1484,7 +1484,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,147,0,0,0,41,5,114,108,0,0,0,114,126,0,0,
0,114,35,0,0,0,114,53,0,0,0,114,209,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
187,0,0,0,97,3,0,0,115,8,0,0,0,0,1,15,
187,0,0,0,98,3,0,0,115,8,0,0,0,0,1,15,
1,15,1,24,1,122,29,83,111,117,114,99,101,108,101,115,
115,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,
99,111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,
@ -1494,13 +1494,13 @@ const unsigned char _Py_M__importlib_external[] = {
32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,4,
0,0,0,41,2,114,108,0,0,0,114,126,0,0,0,114,
4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,202,
0,0,0,103,3,0,0,115,2,0,0,0,0,2,122,31,
0,0,0,104,3,0,0,115,2,0,0,0,0,2,122,31,
83,111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,
97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,78,
41,6,114,112,0,0,0,114,111,0,0,0,114,113,0,0,
0,114,114,0,0,0,114,187,0,0,0,114,202,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,223,0,0,0,93,3,0,0,115,6,0,
5,0,0,0,114,223,0,0,0,94,3,0,0,115,6,0,
0,0,12,2,6,2,12,6,114,223,0,0,0,99,0,0,
0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,
0,0,115,136,0,0,0,101,0,0,90,1,0,100,0,0,
@ -1525,7 +1525,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,100,0,0,83,41,1,78,41,2,114,106,0,0,0,114,
35,0,0,0,41,3,114,108,0,0,0,114,106,0,0,0,
114,35,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,185,0,0,0,120,3,0,0,115,4,0,
5,0,0,0,114,185,0,0,0,121,3,0,0,115,4,0,
0,0,0,1,9,1,122,28,69,120,116,101,110,115,105,111,
110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110,
105,116,95,95,99,2,0,0,0,0,0,0,0,2,0,0,
@ -1534,7 +1534,7 @@ const unsigned char _Py_M__importlib_external[] = {
124,0,0,106,1,0,124,1,0,106,1,0,107,2,0,83,
41,1,78,41,2,114,211,0,0,0,114,118,0,0,0,41,
2,114,108,0,0,0,114,212,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,5,0,0,0,114,213,0,0,0,124,
114,4,0,0,0,114,5,0,0,0,114,213,0,0,0,125,
3,0,0,115,4,0,0,0,0,1,18,1,122,26,69,120,
116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,
114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0,
@ -1543,7 +1543,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,124,0,0,106,2,0,131,1,0,65,83,41,1,78,41,
3,114,214,0,0,0,114,106,0,0,0,114,35,0,0,0,
41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,0,
0,114,5,0,0,0,114,215,0,0,0,128,3,0,0,115,
0,114,5,0,0,0,114,215,0,0,0,129,3,0,0,115,
2,0,0,0,0,1,122,28,69,120,116,101,110,115,105,111,
110,70,105,108,101,76,111,97,100,101,114,46,95,95,104,97,
115,104,95,95,99,2,0,0,0,0,0,0,0,3,0,0,
@ -1561,7 +1561,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,105,0,0,0,114,106,0,0,0,114,35,0,0,0,41,
3,114,108,0,0,0,114,164,0,0,0,114,190,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
186,0,0,0,131,3,0,0,115,10,0,0,0,0,2,6,
186,0,0,0,132,3,0,0,115,10,0,0,0,0,2,6,
1,15,1,6,1,16,1,122,33,69,120,116,101,110,115,105,
111,110,70,105,108,101,76,111,97,100,101,114,46,99,114,101,
97,116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,
@ -1578,7 +1578,7 @@ const unsigned char _Py_M__importlib_external[] = {
12,101,120,101,99,95,100,121,110,97,109,105,99,114,105,0,
0,0,114,106,0,0,0,114,35,0,0,0,41,2,114,108,
0,0,0,114,190,0,0,0,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,114,191,0,0,0,139,3,0,0,
0,0,114,5,0,0,0,114,191,0,0,0,140,3,0,0,
115,6,0,0,0,0,2,19,1,6,1,122,31,69,120,116,
101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,
46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,
@ -1597,7 +1597,7 @@ const unsigned char _Py_M__importlib_external[] = {
78,114,4,0,0,0,41,2,114,22,0,0,0,218,6,115,
117,102,102,105,120,41,1,218,9,102,105,108,101,95,110,97,
109,101,114,4,0,0,0,114,5,0,0,0,250,9,60,103,
101,110,101,120,112,114,62,148,3,0,0,115,2,0,0,0,
101,110,101,120,112,114,62,149,3,0,0,115,2,0,0,0,
6,1,122,49,69,120,116,101,110,115,105,111,110,70,105,108,
101,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,
103,101,46,60,108,111,99,97,108,115,62,46,60,103,101,110,
@ -1605,7 +1605,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,218,3,97,110,121,218,18,69,88,84,69,78,83,73,79,
78,95,83,85,70,70,73,88,69,83,41,2,114,108,0,0,
0,114,126,0,0,0,114,4,0,0,0,41,1,114,226,0,
0,0,114,5,0,0,0,114,159,0,0,0,145,3,0,0,
0,0,114,5,0,0,0,114,159,0,0,0,146,3,0,0,
115,6,0,0,0,0,2,19,1,18,1,122,30,69,120,116,
101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,
46,105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,
@ -1617,7 +1617,7 @@ const unsigned char _Py_M__importlib_external[] = {
99,111,100,101,32,111,98,106,101,99,116,46,78,114,4,0,
0,0,41,2,114,108,0,0,0,114,126,0,0,0,114,4,
0,0,0,114,4,0,0,0,114,5,0,0,0,114,187,0,
0,0,151,3,0,0,115,2,0,0,0,0,2,122,28,69,
0,0,152,3,0,0,115,2,0,0,0,0,2,122,28,69,
120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,
101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,
0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,
@ -1627,7 +1627,7 @@ const unsigned char _Py_M__importlib_external[] = {
118,101,32,110,111,32,115,111,117,114,99,101,32,99,111,100,
101,46,78,114,4,0,0,0,41,2,114,108,0,0,0,114,
126,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,114,202,0,0,0,155,3,0,0,115,2,0,0,
0,0,0,114,202,0,0,0,156,3,0,0,115,2,0,0,
0,0,2,122,30,69,120,116,101,110,115,105,111,110,70,105,
108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,
114,99,101,99,2,0,0,0,0,0,0,0,2,0,0,0,
@ -1638,7 +1638,7 @@ const unsigned char _Py_M__importlib_external[] = {
117,110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,
114,46,41,1,114,35,0,0,0,41,2,114,108,0,0,0,
114,126,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,157,0,0,0,159,3,0,0,115,2,0,
5,0,0,0,114,157,0,0,0,160,3,0,0,115,2,0,
0,0,0,3,122,32,69,120,116,101,110,115,105,111,110,70,
105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105,
108,101,110,97,109,101,78,41,14,114,112,0,0,0,114,111,
@ -1647,7 +1647,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,114,191,0,0,0,114,159,0,0,0,114,187,0,0,0,
114,202,0,0,0,114,123,0,0,0,114,157,0,0,0,114,
4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,114,224,0,0,0,112,3,0,0,115,20,0,0,
0,0,0,114,224,0,0,0,113,3,0,0,115,20,0,0,
0,12,6,6,2,12,4,12,4,12,3,12,8,12,6,12,
6,12,4,12,4,114,224,0,0,0,99,0,0,0,0,0,
0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,
@ -1691,7 +1691,7 @@ const unsigned char _Py_M__importlib_external[] = {
95,112,97,116,104,95,102,105,110,100,101,114,41,4,114,108,
0,0,0,114,106,0,0,0,114,35,0,0,0,218,11,112,
97,116,104,95,102,105,110,100,101,114,114,4,0,0,0,114,
4,0,0,0,114,5,0,0,0,114,185,0,0,0,172,3,
4,0,0,0,114,5,0,0,0,114,185,0,0,0,173,3,
0,0,115,8,0,0,0,0,1,9,1,9,1,21,1,122,
23,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,
95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,
@ -1710,7 +1710,7 @@ const unsigned char _Py_M__importlib_external[] = {
41,4,114,108,0,0,0,114,222,0,0,0,218,3,100,111,
116,90,2,109,101,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,218,23,95,102,105,110,100,95,112,97,114,101,
110,116,95,112,97,116,104,95,110,97,109,101,115,178,3,0,
110,116,95,112,97,116,104,95,110,97,109,101,115,179,3,0,
0,115,8,0,0,0,0,2,27,1,12,2,4,3,122,38,
95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
102,105,110,100,95,112,97,114,101,110,116,95,112,97,116,104,
@ -1724,7 +1724,7 @@ const unsigned char _Py_M__importlib_external[] = {
110,116,95,109,111,100,117,108,101,95,110,97,109,101,90,14,
112,97,116,104,95,97,116,116,114,95,110,97,109,101,114,4,
0,0,0,114,4,0,0,0,114,5,0,0,0,114,233,0,
0,0,188,3,0,0,115,4,0,0,0,0,1,18,1,122,
0,0,189,3,0,0,115,4,0,0,0,0,1,18,1,122,
31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,
95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104,
99,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,
@ -1742,7 +1742,7 @@ const unsigned char _Py_M__importlib_external[] = {
108,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116,
104,114,164,0,0,0,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,12,95,114,101,99,97,108,99,117,108,
97,116,101,192,3,0,0,115,16,0,0,0,0,2,18,1,
97,116,101,193,3,0,0,115,16,0,0,0,0,2,18,1,
15,1,21,3,27,1,9,1,12,1,9,1,122,27,95,78,
97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101,
99,97,108,99,117,108,97,116,101,99,1,0,0,0,0,0,
@ -1751,14 +1751,14 @@ const unsigned char _Py_M__importlib_external[] = {
1,0,83,41,1,78,41,2,218,4,105,116,101,114,114,240,
0,0,0,41,1,114,108,0,0,0,114,4,0,0,0,114,
4,0,0,0,114,5,0,0,0,218,8,95,95,105,116,101,
114,95,95,205,3,0,0,115,2,0,0,0,0,1,122,23,
114,95,95,206,3,0,0,115,2,0,0,0,0,1,122,23,
95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
95,105,116,101,114,95,95,99,1,0,0,0,0,0,0,0,
1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,
0,116,0,0,124,0,0,106,1,0,131,0,0,131,1,0,
83,41,1,78,41,2,114,31,0,0,0,114,240,0,0,0,
41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,0,
0,114,5,0,0,0,218,7,95,95,108,101,110,95,95,208,
0,114,5,0,0,0,218,7,95,95,108,101,110,95,95,209,
3,0,0,115,2,0,0,0,0,1,122,22,95,78,97,109,
101,115,112,97,99,101,80,97,116,104,46,95,95,108,101,110,
95,95,99,1,0,0,0,0,0,0,0,1,0,0,0,2,
@ -1768,7 +1768,7 @@ const unsigned char _Py_M__importlib_external[] = {
123,33,114,125,41,41,2,114,47,0,0,0,114,232,0,0,
0,41,1,114,108,0,0,0,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,218,8,95,95,114,101,112,114,95,
95,211,3,0,0,115,2,0,0,0,0,1,122,23,95,78,
95,212,3,0,0,115,2,0,0,0,0,1,122,23,95,78,
97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114,
101,112,114,95,95,99,2,0,0,0,0,0,0,0,2,0,
0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124,
@ -1776,7 +1776,7 @@ const unsigned char _Py_M__importlib_external[] = {
1,78,41,1,114,240,0,0,0,41,2,114,108,0,0,0,
218,4,105,116,101,109,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,12,95,95,99,111,110,116,97,105,110,
115,95,95,214,3,0,0,115,2,0,0,0,0,1,122,27,
115,95,95,215,3,0,0,115,2,0,0,0,0,1,122,27,
95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,
95,99,111,110,116,97,105,110,115,95,95,99,2,0,0,0,
0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,
@ -1784,7 +1784,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,131,1,0,1,100,0,0,83,41,1,78,41,2,114,232,
0,0,0,114,163,0,0,0,41,2,114,108,0,0,0,114,
245,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,114,163,0,0,0,217,3,0,0,115,2,0,0,
0,0,0,114,163,0,0,0,218,3,0,0,115,2,0,0,
0,0,1,122,21,95,78,97,109,101,115,112,97,99,101,80,
97,116,104,46,97,112,112,101,110,100,78,41,13,114,112,0,
0,0,114,111,0,0,0,114,113,0,0,0,114,114,0,0,
@ -1792,7 +1792,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,240,0,0,0,114,242,0,0,0,114,243,0,0,0,114,
244,0,0,0,114,246,0,0,0,114,163,0,0,0,114,4,
0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,
0,0,114,230,0,0,0,165,3,0,0,115,20,0,0,0,
0,0,114,230,0,0,0,166,3,0,0,115,20,0,0,0,
12,5,6,2,12,6,12,10,12,4,12,13,12,3,12,3,
12,3,12,3,114,230,0,0,0,99,0,0,0,0,0,0,
0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,118,
@ -1811,7 +1811,7 @@ const unsigned char _Py_M__importlib_external[] = {
41,1,78,41,2,114,230,0,0,0,114,232,0,0,0,41,
4,114,108,0,0,0,114,106,0,0,0,114,35,0,0,0,
114,236,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,185,0,0,0,223,3,0,0,115,2,0,
5,0,0,0,114,185,0,0,0,224,3,0,0,115,2,0,
0,0,0,1,122,25,95,78,97,109,101,115,112,97,99,101,
76,111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,
2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,
@ -1828,14 +1828,14 @@ const unsigned char _Py_M__importlib_external[] = {
110,97,109,101,115,112,97,99,101,41,62,41,2,114,47,0,
0,0,114,112,0,0,0,41,2,114,170,0,0,0,114,190,
0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,
0,0,218,11,109,111,100,117,108,101,95,114,101,112,114,226,
0,0,218,11,109,111,100,117,108,101,95,114,101,112,114,227,
3,0,0,115,2,0,0,0,0,7,122,28,95,78,97,109,
101,115,112,97,99,101,76,111,97,100,101,114,46,109,111,100,
117,108,101,95,114,101,112,114,99,2,0,0,0,0,0,0,
0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,
0,0,100,1,0,83,41,2,78,84,114,4,0,0,0,41,
2,114,108,0,0,0,114,126,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,5,0,0,0,114,159,0,0,0,235,
114,4,0,0,0,114,5,0,0,0,114,159,0,0,0,236,
3,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109,
101,115,112,97,99,101,76,111,97,100,101,114,46,105,115,95,
112,97,99,107,97,103,101,99,2,0,0,0,0,0,0,0,
@ -1843,7 +1843,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,100,1,0,83,41,2,78,114,30,0,0,0,114,4,0,
0,0,41,2,114,108,0,0,0,114,126,0,0,0,114,4,
0,0,0,114,4,0,0,0,114,5,0,0,0,114,202,0,
0,0,238,3,0,0,115,2,0,0,0,0,1,122,27,95,
0,0,239,3,0,0,115,2,0,0,0,0,1,122,27,95,
78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,
103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,
0,0,0,2,0,0,0,6,0,0,0,67,0,0,0,115,
@ -1852,7 +1852,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,122,8,60,115,116,114,105,110,103,62,114,189,0,0,
0,114,204,0,0,0,84,41,1,114,205,0,0,0,41,2,
114,108,0,0,0,114,126,0,0,0,114,4,0,0,0,114,
4,0,0,0,114,5,0,0,0,114,187,0,0,0,241,3,
4,0,0,0,114,5,0,0,0,114,187,0,0,0,242,3,
0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101,
115,112,97,99,101,76,111,97,100,101,114,46,103,101,116,95,
99,111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,
@ -1862,14 +1862,14 @@ const unsigned char _Py_M__importlib_external[] = {
109,111,100,117,108,101,32,99,114,101,97,116,105,111,110,46,
78,114,4,0,0,0,41,2,114,108,0,0,0,114,164,0,
0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
0,114,186,0,0,0,244,3,0,0,115,0,0,0,0,122,
0,114,186,0,0,0,245,3,0,0,115,0,0,0,0,122,
30,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,
114,46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,
2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,
67,0,0,0,115,4,0,0,0,100,0,0,83,41,1,78,
114,4,0,0,0,41,2,114,108,0,0,0,114,190,0,0,
0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
114,191,0,0,0,247,3,0,0,115,2,0,0,0,0,1,
114,191,0,0,0,248,3,0,0,115,2,0,0,0,0,1,
122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,
101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,
0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,
@ -1887,7 +1887,7 @@ const unsigned char _Py_M__importlib_external[] = {
104,32,123,33,114,125,41,4,114,105,0,0,0,114,232,0,
0,0,114,121,0,0,0,114,192,0,0,0,41,2,114,108,
0,0,0,114,126,0,0,0,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,114,193,0,0,0,250,3,0,0,
0,0,114,5,0,0,0,114,193,0,0,0,251,3,0,0,
115,4,0,0,0,0,7,16,1,122,28,95,78,97,109,101,
115,112,97,99,101,76,111,97,100,101,114,46,108,111,97,100,
95,109,111,100,117,108,101,78,41,12,114,112,0,0,0,114,
@ -1895,7 +1895,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,0,114,248,0,0,0,114,159,0,0,0,114,202,0,
0,0,114,187,0,0,0,114,186,0,0,0,114,191,0,0,
0,114,193,0,0,0,114,4,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,5,0,0,0,114,247,0,0,0,222,
114,4,0,0,0,114,5,0,0,0,114,247,0,0,0,223,
3,0,0,115,16,0,0,0,12,1,12,3,18,9,12,3,
12,3,12,3,12,3,12,3,114,247,0,0,0,99,0,0,
0,0,0,0,0,0,0,0,0,0,5,0,0,0,64,0,
@ -1933,7 +1933,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,95,99,97,99,104,101,218,6,118,97,108,117,101,115,114,
115,0,0,0,114,250,0,0,0,41,2,114,170,0,0,0,
218,6,102,105,110,100,101,114,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,114,250,0,0,0,11,4,0,0,
0,0,114,5,0,0,0,114,250,0,0,0,12,4,0,0,
115,6,0,0,0,0,4,22,1,15,1,122,28,80,97,116,
104,70,105,110,100,101,114,46,105,110,118,97,108,105,100,97,
116,101,95,99,97,99,104,101,115,99,2,0,0,0,0,0,
@ -1959,7 +1959,7 @@ const unsigned char _Py_M__importlib_external[] = {
107,0,0,0,41,3,114,170,0,0,0,114,35,0,0,0,
90,4,104,111,111,107,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,11,95,112,97,116,104,95,104,111,111,
107,115,19,4,0,0,115,16,0,0,0,0,7,25,1,16,
107,115,20,4,0,0,115,16,0,0,0,0,7,25,1,16,
1,16,1,3,1,14,1,13,1,12,2,122,22,80,97,116,
104,70,105,110,100,101,114,46,95,112,97,116,104,95,104,111,
111,107,115,99,2,0,0,0,0,0,0,0,3,0,0,0,
@ -1991,7 +1991,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,255,0,0,0,41,3,114,170,0,0,0,114,35,
0,0,0,114,253,0,0,0,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,218,20,95,112,97,116,104,95,105,
109,112,111,114,116,101,114,95,99,97,99,104,101,36,4,0,
109,112,111,114,116,101,114,95,99,97,99,104,101,37,4,0,
0,115,22,0,0,0,0,8,12,1,3,1,16,1,13,3,
9,1,3,1,17,1,13,1,15,1,18,1,122,31,80,97,
116,104,70,105,110,100,101,114,46,95,112,97,116,104,95,105,
@ -2011,7 +2011,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,126,0,0,0,114,253,0,0,0,114,127,0,0,
0,114,128,0,0,0,114,164,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,5,0,0,0,218,16,95,108,101,103,
97,99,121,95,103,101,116,95,115,112,101,99,58,4,0,0,
97,99,121,95,103,101,116,95,115,112,101,99,59,4,0,0,
115,18,0,0,0,0,4,15,1,24,2,15,1,6,1,12,
1,16,1,18,1,9,1,122,27,80,97,116,104,70,105,110,
100,101,114,46,95,108,101,103,97,99,121,95,103,101,116,95,
@ -2047,7 +2047,7 @@ const unsigned char _Py_M__importlib_external[] = {
101,115,112,97,99,101,95,112,97,116,104,90,5,101,110,116,
114,121,114,253,0,0,0,114,164,0,0,0,114,128,0,0,
0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
218,9,95,103,101,116,95,115,112,101,99,73,4,0,0,115,
218,9,95,103,101,116,95,115,112,101,99,74,4,0,0,115,
40,0,0,0,0,5,6,1,13,1,21,1,3,1,15,1,
12,1,15,1,21,2,18,1,12,1,3,1,15,1,4,1,
9,1,12,1,12,5,17,2,18,1,9,1,122,20,80,97,
@ -2075,7 +2075,7 @@ const unsigned char _Py_M__importlib_external[] = {
6,114,170,0,0,0,114,126,0,0,0,114,35,0,0,0,
114,180,0,0,0,114,164,0,0,0,114,4,1,0,0,114,
4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,181,
0,0,0,105,4,0,0,115,26,0,0,0,0,4,12,1,
0,0,0,106,4,0,0,115,26,0,0,0,0,4,12,1,
9,1,21,1,12,1,4,1,15,1,9,1,6,3,9,1,
24,1,4,2,7,2,122,20,80,97,116,104,70,105,110,100,
101,114,46,102,105,110,100,95,115,112,101,99,99,3,0,0,
@ -2097,7 +2097,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,181,0,0,0,114,127,0,0,0,41,4,114,170,0,0,
0,114,126,0,0,0,114,35,0,0,0,114,164,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
182,0,0,0,127,4,0,0,115,8,0,0,0,0,8,18,
182,0,0,0,128,4,0,0,115,8,0,0,0,0,8,18,
1,12,1,4,1,122,22,80,97,116,104,70,105,110,100,101,
114,46,102,105,110,100,95,109,111,100,117,108,101,41,12,114,
112,0,0,0,114,111,0,0,0,114,113,0,0,0,114,114,
@ -2105,7 +2105,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,1,1,0,0,114,2,1,0,0,114,5,1,0,
0,114,181,0,0,0,114,182,0,0,0,114,4,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
249,0,0,0,7,4,0,0,115,22,0,0,0,12,2,6,
249,0,0,0,8,4,0,0,115,22,0,0,0,12,2,6,
2,18,8,18,17,18,22,18,15,3,1,18,31,3,1,21,
21,3,1,114,249,0,0,0,99,0,0,0,0,0,0,0,
0,0,0,0,0,3,0,0,0,64,0,0,0,115,133,0,
@ -2154,7 +2154,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,86,1,113,3,0,100,0,0,83,41,1,78,114,4,0,
0,0,41,2,114,22,0,0,0,114,225,0,0,0,41,1,
114,127,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
227,0,0,0,156,4,0,0,115,2,0,0,0,6,0,122,
227,0,0,0,157,4,0,0,115,2,0,0,0,6,0,122,
38,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110,
105,116,95,95,46,60,108,111,99,97,108,115,62,46,60,103,
101,110,101,120,112,114,62,114,58,0,0,0,114,29,0,0,
@ -2167,7 +2167,7 @@ const unsigned char _Py_M__importlib_external[] = {
111,97,100,101,114,95,100,101,116,97,105,108,115,90,7,108,
111,97,100,101,114,115,114,166,0,0,0,114,4,0,0,0,
41,1,114,127,0,0,0,114,5,0,0,0,114,185,0,0,
0,150,4,0,0,115,16,0,0,0,0,4,6,1,19,1,
0,151,4,0,0,115,16,0,0,0,0,4,6,1,19,1,
36,1,9,2,15,1,9,1,12,1,122,19,70,105,108,101,
70,105,110,100,101,114,46,95,95,105,110,105,116,95,95,99,
1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,
@ -2177,7 +2177,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,121,32,109,116,105,109,101,46,114,29,0,0,0,78,114,
87,0,0,0,41,1,114,8,1,0,0,41,1,114,108,0,
0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,
0,114,250,0,0,0,164,4,0,0,115,2,0,0,0,0,
0,114,250,0,0,0,165,4,0,0,115,2,0,0,0,0,
2,122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,
118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,
2,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,
@ -2201,7 +2201,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,181,0,0,0,114,127,0,0,0,114,156,0,0,0,41,
3,114,108,0,0,0,114,126,0,0,0,114,164,0,0,0,
114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,
124,0,0,0,170,4,0,0,115,8,0,0,0,0,7,15,
124,0,0,0,171,4,0,0,115,8,0,0,0,0,7,15,
1,12,1,10,1,122,22,70,105,108,101,70,105,110,100,101,
114,46,102,105,110,100,95,108,111,97,100,101,114,99,6,0,
0,0,0,0,0,0,7,0,0,0,7,0,0,0,67,0,
@ -2212,7 +2212,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,0,41,7,114,108,0,0,0,114,165,0,0,0,114,
126,0,0,0,114,35,0,0,0,90,4,115,109,115,108,114,
180,0,0,0,114,127,0,0,0,114,4,0,0,0,114,4,
0,0,0,114,5,0,0,0,114,5,1,0,0,182,4,0,
0,0,0,114,5,0,0,0,114,5,1,0,0,183,4,0,
0,115,6,0,0,0,0,1,15,1,18,1,122,20,70,105,
108,101,70,105,110,100,101,114,46,95,103,101,116,95,115,112,
101,99,78,99,3,0,0,0,0,0,0,0,14,0,0,0,
@ -2276,7 +2276,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,114,165,0,0,0,90,13,105,110,105,116,95,102,105,108,
101,110,97,109,101,90,9,102,117,108,108,95,112,97,116,104,
114,164,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
5,0,0,0,114,181,0,0,0,187,4,0,0,115,68,0,
5,0,0,0,114,181,0,0,0,188,4,0,0,115,68,0,
0,0,0,3,6,1,19,1,3,1,34,1,13,1,11,1,
15,1,10,1,9,2,9,1,9,1,15,2,9,1,6,2,
12,1,18,1,22,1,10,1,15,1,12,1,32,4,12,2,
@ -2313,7 +2313,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,4,0,0,0,41,1,114,88,0,0,0,41,2,114,22,
0,0,0,90,2,102,110,114,4,0,0,0,114,4,0,0,
0,114,5,0,0,0,250,9,60,115,101,116,99,111,109,112,
62,5,5,0,0,115,2,0,0,0,9,0,122,41,70,105,
62,6,5,0,0,115,2,0,0,0,9,0,122,41,70,105,
108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,
97,99,104,101,46,60,108,111,99,97,108,115,62,46,60,115,
101,116,99,111,109,112,62,78,41,18,114,35,0,0,0,114,
@ -2330,7 +2330,7 @@ const unsigned char _Py_M__importlib_external[] = {
114,245,0,0,0,114,106,0,0,0,114,237,0,0,0,114,
225,0,0,0,90,8,110,101,119,95,110,97,109,101,114,4,
0,0,0,114,4,0,0,0,114,5,0,0,0,114,13,1,
0,0,232,4,0,0,115,34,0,0,0,0,2,9,1,3,
0,0,233,4,0,0,115,34,0,0,0,0,2,9,1,3,
1,31,1,22,3,11,3,18,1,18,7,9,1,13,1,24,
1,6,1,27,2,6,1,17,1,9,1,18,1,122,22,70,
105,108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,
@ -2369,14 +2369,14 @@ const unsigned char _Py_M__importlib_external[] = {
0,41,2,114,170,0,0,0,114,12,1,0,0,114,4,0,
0,0,114,5,0,0,0,218,24,112,97,116,104,95,104,111,
111,107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,
114,17,5,0,0,115,6,0,0,0,0,2,12,1,18,1,
114,18,5,0,0,115,6,0,0,0,0,2,12,1,18,1,
122,54,70,105,108,101,70,105,110,100,101,114,46,112,97,116,
104,95,104,111,111,107,46,60,108,111,99,97,108,115,62,46,
112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105,
108,101,70,105,110,100,101,114,114,4,0,0,0,41,3,114,
170,0,0,0,114,12,1,0,0,114,18,1,0,0,114,4,
0,0,0,41,2,114,170,0,0,0,114,12,1,0,0,114,
5,0,0,0,218,9,112,97,116,104,95,104,111,111,107,7,
5,0,0,0,218,9,112,97,116,104,95,104,111,111,107,8,
5,0,0,115,4,0,0,0,0,10,21,6,122,20,70,105,
108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,
111,107,99,1,0,0,0,0,0,0,0,1,0,0,0,2,
@ -2385,7 +2385,7 @@ const unsigned char _Py_M__importlib_external[] = {
16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125,
41,41,2,114,47,0,0,0,114,35,0,0,0,41,1,114,
108,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,
0,0,0,114,244,0,0,0,25,5,0,0,115,2,0,0,
0,0,0,114,244,0,0,0,26,5,0,0,115,2,0,0,
0,0,1,122,19,70,105,108,101,70,105,110,100,101,114,46,
95,95,114,101,112,114,95,95,41,15,114,112,0,0,0,114,
111,0,0,0,114,113,0,0,0,114,114,0,0,0,114,185,
@ -2393,7 +2393,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,124,0,0,0,114,5,1,0,0,114,181,0,0,
0,114,13,1,0,0,114,183,0,0,0,114,19,1,0,0,
114,244,0,0,0,114,4,0,0,0,114,4,0,0,0,114,
4,0,0,0,114,5,0,0,0,114,6,1,0,0,141,4,
4,0,0,0,114,5,0,0,0,114,6,1,0,0,142,4,
0,0,115,20,0,0,0,12,7,6,2,12,14,12,4,6,
2,12,12,12,5,15,45,12,31,18,18,114,6,1,0,0,
99,4,0,0,0,0,0,0,0,6,0,0,0,11,0,0,
@ -2420,7 +2420,7 @@ const unsigned char _Py_M__importlib_external[] = {
97,116,104,110,97,109,101,114,127,0,0,0,114,164,0,0,
0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,
218,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,
31,5,0,0,115,34,0,0,0,0,2,15,1,15,1,6,
32,5,0,0,115,34,0,0,0,0,2,15,1,15,1,6,
1,6,1,12,1,12,1,18,2,15,1,6,1,21,1,3,
1,10,1,10,1,10,1,14,1,13,2,114,24,1,0,0,
99,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,
@ -2440,7 +2440,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,0,114,74,0,0,0,41,3,90,10,101,120,116,101,
110,115,105,111,110,115,90,6,115,111,117,114,99,101,90,8,
98,121,116,101,99,111,100,101,114,4,0,0,0,114,4,0,
0,0,114,5,0,0,0,114,161,0,0,0,54,5,0,0,
0,0,114,5,0,0,0,114,161,0,0,0,55,5,0,0,
115,8,0,0,0,0,5,18,1,12,1,12,1,114,161,0,
0,0,99,1,0,0,0,0,0,0,0,12,0,0,0,12,
0,0,0,67,0,0,0,115,70,2,0,0,124,0,0,97,
@ -2502,7 +2502,7 @@ const unsigned char _Py_M__importlib_external[] = {
1,113,3,0,100,1,0,83,41,2,114,29,0,0,0,78,
41,1,114,31,0,0,0,41,2,114,22,0,0,0,114,77,
0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,
0,0,114,227,0,0,0,90,5,0,0,115,2,0,0,0,
0,0,114,227,0,0,0,91,5,0,0,115,2,0,0,0,
6,0,122,25,95,115,101,116,117,112,46,60,108,111,99,97,
108,115,62,46,60,103,101,110,101,120,112,114,62,114,59,0,
0,0,122,30,105,109,112,111,114,116,108,105,98,32,114,101,
@ -2532,7 +2532,7 @@ const unsigned char _Py_M__importlib_external[] = {
95,109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,
95,109,111,100,117,108,101,90,13,119,105,110,114,101,103,95,
109,111,100,117,108,101,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,6,95,115,101,116,117,112,65,5,0,
114,5,0,0,0,218,6,95,115,101,116,117,112,66,5,0,
0,115,82,0,0,0,0,8,6,1,9,1,9,3,13,1,
13,1,15,1,18,2,13,1,20,3,33,1,19,2,31,1,
10,1,15,1,13,1,4,2,3,1,15,1,5,1,13,1,
@ -2558,7 +2558,7 @@ const unsigned char _Py_M__importlib_external[] = {
0,0,114,249,0,0,0,114,218,0,0,0,41,2,114,32,
1,0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,
111,97,100,101,114,115,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,218,8,95,105,110,115,116,97,108,108,133,
114,5,0,0,0,218,8,95,105,110,115,116,97,108,108,134,
5,0,0,115,16,0,0,0,0,2,10,1,9,1,28,1,
15,1,16,1,16,4,9,1,114,35,1,0,0,41,3,122,
3,119,105,110,114,1,0,0,0,114,2,0,0,0,41,57,
@ -2588,7 +2588,7 @@ const unsigned char _Py_M__importlib_external[] = {
5,0,0,0,218,8,60,109,111,100,117,108,101,62,8,0,
0,0,115,100,0,0,0,6,17,6,3,12,12,12,5,12,
5,12,6,12,12,12,10,12,9,12,5,12,7,15,22,15,
109,22,1,18,2,6,1,6,2,9,2,9,2,10,2,21,
110,22,1,18,2,6,1,6,2,9,2,9,2,10,2,21,
44,12,33,12,19,12,12,12,12,18,8,12,28,12,17,21,
55,21,12,18,10,12,14,9,3,12,1,15,65,19,64,19,
28,22,110,19,41,25,43,25,16,6,3,25,53,19,57,19,

View File

@ -68,7 +68,7 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_OR,
&&TARGET_INPLACE_POWER,
&&TARGET_GET_ITER,
&&_unknown_opcode,
&&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_PRINT_EXPR,
&&TARGET_LOAD_BUILD_CLASS,
&&TARGET_YIELD_FROM,