Implement PEP 380 - 'yield from' (closes #11682)
This commit is contained in:
parent
e51757f6de
commit
1f7ce62bd6
|
@ -431,6 +431,13 @@ the stack so that it is available for further iterations of the loop.
|
||||||
Pops ``TOS`` and yields it from a :term:`generator`.
|
Pops ``TOS`` and yields it from a :term:`generator`.
|
||||||
|
|
||||||
|
|
||||||
|
.. opcode:: YIELD_FROM
|
||||||
|
|
||||||
|
Pops ``TOS`` and delegates to it as a subiterator from a :term:`generator`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. opcode:: IMPORT_STAR
|
.. opcode:: IMPORT_STAR
|
||||||
|
|
||||||
Loads all symbols not starting with ``'_'`` directly from the module TOS to the
|
Loads all symbols not starting with ``'_'`` directly from the module TOS to the
|
||||||
|
|
|
@ -250,7 +250,16 @@ The following exceptions are the exceptions that are usually raised.
|
||||||
.. exception:: StopIteration
|
.. exception:: StopIteration
|
||||||
|
|
||||||
Raised by built-in function :func:`next` and an :term:`iterator`\'s
|
Raised by built-in function :func:`next` and an :term:`iterator`\'s
|
||||||
:meth:`__next__` method to signal that there are no further values.
|
:meth:`__next__` method to signal that there are no further items to be
|
||||||
|
produced by the iterator.
|
||||||
|
|
||||||
|
The exception object has a single attribute :attr:`value`, which is
|
||||||
|
given as an argument when constructing the exception, and defaults
|
||||||
|
to :const:`None`.
|
||||||
|
|
||||||
|
When a generator function returns, a new :exc:`StopIteration` instance is
|
||||||
|
raised, and the value returned by the function is used as the
|
||||||
|
:attr:`value` parameter to the constructor of the exception.
|
||||||
|
|
||||||
|
|
||||||
.. exception:: SyntaxError
|
.. exception:: SyntaxError
|
||||||
|
|
|
@ -318,7 +318,7 @@ Yield expressions
|
||||||
|
|
||||||
.. productionlist::
|
.. productionlist::
|
||||||
yield_atom: "(" `yield_expression` ")"
|
yield_atom: "(" `yield_expression` ")"
|
||||||
yield_expression: "yield" [`expression_list`]
|
yield_expression: "yield" [`expression_list` | "from" `expression`]
|
||||||
|
|
||||||
The :keyword:`yield` expression is only used when defining a generator function,
|
The :keyword:`yield` expression is only used when defining a generator function,
|
||||||
and can only be used in the body of a function definition. Using a
|
and can only be used in the body of a function definition. Using a
|
||||||
|
@ -336,7 +336,10 @@ the internal evaluation stack. When the execution is resumed by calling one of
|
||||||
the generator's methods, the function can proceed exactly as if the
|
the generator's methods, the function can proceed exactly as if the
|
||||||
:keyword:`yield` expression was just another external call. The value of the
|
:keyword:`yield` expression was just another external call. The value of the
|
||||||
:keyword:`yield` expression after resuming depends on the method which resumed
|
:keyword:`yield` expression after resuming depends on the method which resumed
|
||||||
the execution.
|
the execution. If :meth:`__next__` is used (typically via either a
|
||||||
|
:keyword:`for` or the :func:`next` builtin) then the result is :const:`None`,
|
||||||
|
otherwise, if :meth:`send` is used, then the result will be the value passed
|
||||||
|
in to that method.
|
||||||
|
|
||||||
.. index:: single: coroutine
|
.. index:: single: coroutine
|
||||||
|
|
||||||
|
@ -346,12 +349,29 @@ suspended. The only difference is that a generator function cannot control
|
||||||
where should the execution continue after it yields; the control is always
|
where should the execution continue after it yields; the control is always
|
||||||
transferred to the generator's caller.
|
transferred to the generator's caller.
|
||||||
|
|
||||||
The :keyword:`yield` statement is allowed in the :keyword:`try` clause of a
|
:keyword:`yield` expressions are allowed in the :keyword:`try` clause of a
|
||||||
:keyword:`try` ... :keyword:`finally` construct. If the generator is not
|
:keyword:`try` ... :keyword:`finally` construct. If the generator is not
|
||||||
resumed before it is finalized (by reaching a zero reference count or by being
|
resumed before it is finalized (by reaching a zero reference count or by being
|
||||||
garbage collected), the generator-iterator's :meth:`close` method will be
|
garbage collected), the generator-iterator's :meth:`close` method will be
|
||||||
called, allowing any pending :keyword:`finally` clauses to execute.
|
called, allowing any pending :keyword:`finally` clauses to execute.
|
||||||
|
|
||||||
|
When ``yield from expression`` is used, it treats the supplied expression as
|
||||||
|
a subiterator. All values produced by that subiterator are passed directly
|
||||||
|
to the caller of the current generator's methods. Any values passed in with
|
||||||
|
:meth:`send` and any exceptions passed in with :meth:`throw` are passed to
|
||||||
|
the underlying iterator if it has the appropriate methods. If this is not the
|
||||||
|
case, then :meth:`send` will raise :exc:`AttributeError` or :exc:`TypeError`,
|
||||||
|
while :meth:`throw` will just raise the passed in exception immediately.
|
||||||
|
|
||||||
|
When the underlying iterator is complete, the :attr:`~StopIteration.value`
|
||||||
|
attribute of the raised :exc:`StopIteration` instance becomes the value of
|
||||||
|
the yield expression. It can be either set explicitly when raising
|
||||||
|
:exc:`StopIteration`, or automatically when the sub-iterator is a generator
|
||||||
|
(by returning a value from the sub-generator).
|
||||||
|
|
||||||
|
The parentheses can be omitted when the :keyword:`yield` expression is the
|
||||||
|
sole expression on the right hand side of an assignment statement.
|
||||||
|
|
||||||
.. index:: object: generator
|
.. index:: object: generator
|
||||||
|
|
||||||
The following generator's methods can be used to control the execution of a
|
The following generator's methods can be used to control the execution of a
|
||||||
|
@ -444,6 +464,10 @@ generator functions::
|
||||||
The proposal to enhance the API and syntax of generators, making them
|
The proposal to enhance the API and syntax of generators, making them
|
||||||
usable as simple coroutines.
|
usable as simple coroutines.
|
||||||
|
|
||||||
|
:pep:`0380` - Syntax for Delegating to a Subgenerator
|
||||||
|
The proposal to introduce the :token:`yield_from` syntax, making delegation
|
||||||
|
to sub-generators easy.
|
||||||
|
|
||||||
|
|
||||||
.. _primaries:
|
.. _primaries:
|
||||||
|
|
||||||
|
|
|
@ -425,10 +425,10 @@ When :keyword:`return` passes control out of a :keyword:`try` statement with a
|
||||||
:keyword:`finally` clause, that :keyword:`finally` clause is executed before
|
:keyword:`finally` clause, that :keyword:`finally` clause is executed before
|
||||||
really leaving the function.
|
really leaving the function.
|
||||||
|
|
||||||
In a generator function, the :keyword:`return` statement is not allowed to
|
In a generator function, the :keyword:`return` statement indicates that the
|
||||||
include an :token:`expression_list`. In that context, a bare :keyword:`return`
|
generator is done and will cause :exc:`StopIteration` to be raised. The returned
|
||||||
indicates that the generator is done and will cause :exc:`StopIteration` to be
|
value (if any) is used as an argument to construct :exc:`StopIteration` and
|
||||||
raised.
|
becomes the :attr:`StopIteration.value` attribute.
|
||||||
|
|
||||||
|
|
||||||
.. _yield:
|
.. _yield:
|
||||||
|
@ -450,6 +450,7 @@ The :keyword:`yield` statement is only used when defining a generator function,
|
||||||
and is only used in the body of the generator function. Using a :keyword:`yield`
|
and is only used in the body of the generator function. Using a :keyword:`yield`
|
||||||
statement in a function definition is sufficient to cause that definition to
|
statement in a function definition is sufficient to cause that definition to
|
||||||
create a generator function instead of a normal function.
|
create a generator function instead of a normal function.
|
||||||
|
|
||||||
When a generator function is called, it returns an iterator known as a generator
|
When a generator function is called, it returns an iterator known as a generator
|
||||||
iterator, or more commonly, a generator. The body of the generator function is
|
iterator, or more commonly, a generator. The body of the generator function is
|
||||||
executed by calling the :func:`next` function on the generator repeatedly until
|
executed by calling the :func:`next` function on the generator repeatedly until
|
||||||
|
@ -469,14 +470,25 @@ resumed before it is finalized (by reaching a zero reference count or by being
|
||||||
garbage collected), the generator-iterator's :meth:`close` method will be
|
garbage collected), the generator-iterator's :meth:`close` method will be
|
||||||
called, allowing any pending :keyword:`finally` clauses to execute.
|
called, allowing any pending :keyword:`finally` clauses to execute.
|
||||||
|
|
||||||
|
When ``yield from expression`` is used, it treats the supplied expression as
|
||||||
|
a subiterator, producing values from it until the underlying iterator is
|
||||||
|
exhausted.
|
||||||
|
|
||||||
|
For full details of :keyword:`yield` semantics, refer to the :ref:`yieldexpr`
|
||||||
|
section.
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
:pep:`0255` - Simple Generators
|
:pep:`0255` - Simple Generators
|
||||||
The proposal for adding generators and the :keyword:`yield` statement to Python.
|
The proposal for adding generators and the :keyword:`yield` statement to Python.
|
||||||
|
|
||||||
:pep:`0342` - Coroutines via Enhanced Generators
|
:pep:`0342` - Coroutines via Enhanced Generators
|
||||||
The proposal that, among other generator enhancements, proposed allowing
|
The proposal to enhance the API and syntax of generators, making them
|
||||||
:keyword:`yield` to appear inside a :keyword:`try` ... :keyword:`finally` block.
|
usable as simple coroutines.
|
||||||
|
|
||||||
|
:pep:`0380` - Syntax for Delegating to a Subgenerator
|
||||||
|
The proposal to introduce the :token:`yield_from` syntax, making delegation
|
||||||
|
to sub-generators easy.
|
||||||
|
|
||||||
|
|
||||||
.. _raise:
|
.. _raise:
|
||||||
|
|
|
@ -195,6 +195,22 @@ inspection of exception attributes::
|
||||||
print("You are not allowed to read document.txt")
|
print("You are not allowed to read document.txt")
|
||||||
|
|
||||||
|
|
||||||
|
PEP 380: Syntax for Delegating to a Subgenerator
|
||||||
|
================================================
|
||||||
|
|
||||||
|
PEP 380 adds the ``yield from`` expression, allowing a generator to delegate
|
||||||
|
part of its operations to another generator. This allows a section of code
|
||||||
|
containing 'yield' to be factored out and placed in another generator.
|
||||||
|
Additionally, the subgenerator is allowed to return with a value, and the
|
||||||
|
value is made available to the delegating generator.
|
||||||
|
While designed primarily for use in delegating to a subgenerator, the ``yield
|
||||||
|
from`` expression actually allows delegation to arbitrary subiterators.
|
||||||
|
|
||||||
|
(Implementation by Greg Ewing, integrated into 3.3 by Renaud Blanch, Ryan
|
||||||
|
Kelly and Nick Coghlan, documentation by Zbigniew Jędrzejewski-Szmek and
|
||||||
|
Nick Coghlan)
|
||||||
|
|
||||||
|
|
||||||
PEP 3155: Qualified name for classes and functions
|
PEP 3155: Qualified name for classes and functions
|
||||||
==================================================
|
==================================================
|
||||||
|
|
||||||
|
@ -208,7 +224,6 @@ it provides better information about where they were actually defined, and
|
||||||
how they might be accessible from the global scope.
|
how they might be accessible from the global scope.
|
||||||
|
|
||||||
Example with (non-bound) methods::
|
Example with (non-bound) methods::
|
||||||
|
|
||||||
>>> class C:
|
>>> class C:
|
||||||
... def meth(self):
|
... def meth(self):
|
||||||
... pass
|
... pass
|
||||||
|
|
|
@ -121,7 +121,7 @@ arglist: (argument ',')* (argument [',']
|
||||||
|'**' test)
|
|'**' test)
|
||||||
# The reason that keywords are test nodes instead of NAME is that using NAME
|
# The reason that keywords are test nodes instead of NAME is that using NAME
|
||||||
# results in an ambiguity. ast.c makes sure it's a NAME.
|
# results in an ambiguity. ast.c makes sure it's a NAME.
|
||||||
argument: test [comp_for] | test '=' test # Really [keyword '='] test
|
argument: (test) [comp_for] | test '=' test # Really [keyword '='] test
|
||||||
comp_iter: comp_for | comp_if
|
comp_iter: comp_for | comp_if
|
||||||
comp_for: 'for' exprlist 'in' or_test [comp_iter]
|
comp_for: 'for' exprlist 'in' or_test [comp_iter]
|
||||||
comp_if: 'if' test_nocond [comp_iter]
|
comp_if: 'if' test_nocond [comp_iter]
|
||||||
|
@ -129,4 +129,5 @@ comp_if: 'if' test_nocond [comp_iter]
|
||||||
# not used in grammar, but may appear in "node" passed from Parser to Compiler
|
# not used in grammar, but may appear in "node" passed from Parser to Compiler
|
||||||
encoding_decl: NAME
|
encoding_decl: NAME
|
||||||
|
|
||||||
yield_expr: 'yield' [testlist]
|
yield_expr: 'yield' [yield_arg]
|
||||||
|
yield_arg: 'from' test | testlist
|
||||||
|
|
|
@ -245,6 +245,7 @@ struct _expr {
|
||||||
} GeneratorExp;
|
} GeneratorExp;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
int is_from;
|
||||||
expr_ty value;
|
expr_ty value;
|
||||||
} Yield;
|
} Yield;
|
||||||
|
|
||||||
|
@ -487,8 +488,9 @@ expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int
|
||||||
#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4)
|
#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4)
|
||||||
expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
|
expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
|
||||||
col_offset, PyArena *arena);
|
col_offset, PyArena *arena);
|
||||||
#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3)
|
#define Yield(a0, a1, a2, a3, a4) _Py_Yield(a0, a1, a2, a3, a4)
|
||||||
expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena);
|
expr_ty _Py_Yield(int is_from, expr_ty value, int lineno, int col_offset,
|
||||||
|
PyArena *arena);
|
||||||
#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5)
|
#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5)
|
||||||
expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators,
|
expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators,
|
||||||
int lineno, int col_offset, PyArena *arena);
|
int lineno, int col_offset, PyArena *arena);
|
||||||
|
|
|
@ -9,45 +9,46 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int b_type; /* what kind of block this is */
|
int b_type; /* what kind of block this is */
|
||||||
int b_handler; /* where to jump to find handler */
|
int b_handler; /* where to jump to find handler */
|
||||||
int b_level; /* value stack level to pop to */
|
int b_level; /* value stack level to pop to */
|
||||||
} PyTryBlock;
|
} PyTryBlock;
|
||||||
|
|
||||||
typedef struct _frame {
|
typedef struct _frame {
|
||||||
PyObject_VAR_HEAD
|
PyObject_VAR_HEAD
|
||||||
struct _frame *f_back; /* previous frame, or NULL */
|
struct _frame *f_back; /* previous frame, or NULL */
|
||||||
PyCodeObject *f_code; /* code segment */
|
PyCodeObject *f_code; /* code segment */
|
||||||
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
|
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
|
||||||
PyObject *f_globals; /* global symbol table (PyDictObject) */
|
PyObject *f_globals; /* global symbol table (PyDictObject) */
|
||||||
PyObject *f_locals; /* local symbol table (any mapping) */
|
PyObject *f_locals; /* local symbol table (any mapping) */
|
||||||
PyObject **f_valuestack; /* points after the last local */
|
PyObject **f_valuestack; /* points after the last local */
|
||||||
/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
|
/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
|
||||||
Frame evaluation usually NULLs it, but a frame that yields sets it
|
Frame evaluation usually NULLs it, but a frame that yields sets it
|
||||||
to the current stack top. */
|
to the current stack top. */
|
||||||
PyObject **f_stacktop;
|
PyObject **f_stacktop;
|
||||||
PyObject *f_trace; /* Trace function */
|
PyObject *f_trace; /* Trace function */
|
||||||
|
PyObject *f_yieldfrom; /* Iterator being delegated to by yield from */
|
||||||
|
|
||||||
/* In a generator, we need to be able to swap between the exception
|
/* In a generator, we need to be able to swap between the exception
|
||||||
state inside the generator and the exception state of the calling
|
state inside the generator and the exception state of the calling
|
||||||
frame (which shouldn't be impacted when the generator "yields"
|
frame (which shouldn't be impacted when the generator "yields"
|
||||||
from an except handler).
|
from an except handler).
|
||||||
These three fields exist exactly for that, and are unused for
|
These three fields exist exactly for that, and are unused for
|
||||||
non-generator frames. See the SAVE_EXC_STATE and SWAP_EXC_STATE
|
non-generator frames. See the SAVE_EXC_STATE and SWAP_EXC_STATE
|
||||||
macros in ceval.c for details of their use. */
|
macros in ceval.c for details of their use. */
|
||||||
PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
|
PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
|
||||||
|
|
||||||
PyThreadState *f_tstate;
|
PyThreadState *f_tstate;
|
||||||
int f_lasti; /* Last instruction if called */
|
int f_lasti; /* Last instruction if called */
|
||||||
/* Call PyFrame_GetLineNumber() instead of reading this field
|
/* Call PyFrame_GetLineNumber() instead of reading this field
|
||||||
directly. As of 2.3 f_lineno is only valid when tracing is
|
directly. As of 2.3 f_lineno is only valid when tracing is
|
||||||
active (i.e. when f_trace is set). At other times we use
|
active (i.e. when f_trace is set). At other times we use
|
||||||
PyCode_Addr2Line to calculate the line from the current
|
PyCode_Addr2Line to calculate the line from the current
|
||||||
bytecode index. */
|
bytecode index. */
|
||||||
int f_lineno; /* Current line number */
|
int f_lineno; /* Current line number */
|
||||||
int f_iblock; /* index in f_blockstack */
|
int f_iblock; /* index in f_blockstack */
|
||||||
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
|
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
|
||||||
PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
|
PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
|
||||||
} PyFrameObject;
|
} PyFrameObject;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,20 +11,20 @@ extern "C" {
|
||||||
struct _frame; /* Avoid including frameobject.h */
|
struct _frame; /* Avoid including frameobject.h */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
/* The gi_ prefix is intended to remind of generator-iterator. */
|
/* The gi_ prefix is intended to remind of generator-iterator. */
|
||||||
|
|
||||||
/* Note: gi_frame can be NULL if the generator is "finished" */
|
/* Note: gi_frame can be NULL if the generator is "finished" */
|
||||||
struct _frame *gi_frame;
|
struct _frame *gi_frame;
|
||||||
|
|
||||||
/* True if generator is being executed. */
|
/* True if generator is being executed. */
|
||||||
int gi_running;
|
int gi_running;
|
||||||
|
|
||||||
/* The code object backing the generator */
|
/* The code object backing the generator */
|
||||||
PyObject *gi_code;
|
PyObject *gi_code;
|
||||||
|
|
||||||
/* List of weak reference. */
|
/* List of weak reference. */
|
||||||
PyObject *gi_weakreflist;
|
PyObject *gi_weakreflist;
|
||||||
} PyGenObject;
|
} PyGenObject;
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyGen_Type;
|
PyAPI_DATA(PyTypeObject) PyGen_Type;
|
||||||
|
@ -34,6 +34,7 @@ PyAPI_DATA(PyTypeObject) PyGen_Type;
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
|
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
|
||||||
PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
|
PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
|
||||||
|
PyAPI_FUNC(int) PyGen_FetchStopIterationValue(PyObject **);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,3 +81,4 @@
|
||||||
#define comp_if 334
|
#define comp_if 334
|
||||||
#define encoding_decl 335
|
#define encoding_decl 335
|
||||||
#define yield_expr 336
|
#define yield_expr 336
|
||||||
|
#define yield_arg 337
|
||||||
|
|
169
Include/opcode.h
169
Include/opcode.h
|
@ -7,116 +7,117 @@ extern "C" {
|
||||||
|
|
||||||
/* Instruction opcodes for compiled code */
|
/* Instruction opcodes for compiled code */
|
||||||
|
|
||||||
#define POP_TOP 1
|
#define POP_TOP 1
|
||||||
#define ROT_TWO 2
|
#define ROT_TWO 2
|
||||||
#define ROT_THREE 3
|
#define ROT_THREE 3
|
||||||
#define DUP_TOP 4
|
#define DUP_TOP 4
|
||||||
#define DUP_TOP_TWO 5
|
#define DUP_TOP_TWO 5
|
||||||
#define NOP 9
|
#define NOP 9
|
||||||
|
|
||||||
#define UNARY_POSITIVE 10
|
#define UNARY_POSITIVE 10
|
||||||
#define UNARY_NEGATIVE 11
|
#define UNARY_NEGATIVE 11
|
||||||
#define UNARY_NOT 12
|
#define UNARY_NOT 12
|
||||||
|
|
||||||
#define UNARY_INVERT 15
|
#define UNARY_INVERT 15
|
||||||
|
|
||||||
#define BINARY_POWER 19
|
#define BINARY_POWER 19
|
||||||
|
|
||||||
#define BINARY_MULTIPLY 20
|
#define BINARY_MULTIPLY 20
|
||||||
|
|
||||||
#define BINARY_MODULO 22
|
#define BINARY_MODULO 22
|
||||||
#define BINARY_ADD 23
|
#define BINARY_ADD 23
|
||||||
#define BINARY_SUBTRACT 24
|
#define BINARY_SUBTRACT 24
|
||||||
#define BINARY_SUBSCR 25
|
#define BINARY_SUBSCR 25
|
||||||
#define BINARY_FLOOR_DIVIDE 26
|
#define BINARY_FLOOR_DIVIDE 26
|
||||||
#define BINARY_TRUE_DIVIDE 27
|
#define BINARY_TRUE_DIVIDE 27
|
||||||
#define INPLACE_FLOOR_DIVIDE 28
|
#define INPLACE_FLOOR_DIVIDE 28
|
||||||
#define INPLACE_TRUE_DIVIDE 29
|
#define INPLACE_TRUE_DIVIDE 29
|
||||||
|
|
||||||
#define STORE_MAP 54
|
#define STORE_MAP 54
|
||||||
#define INPLACE_ADD 55
|
#define INPLACE_ADD 55
|
||||||
#define INPLACE_SUBTRACT 56
|
#define INPLACE_SUBTRACT 56
|
||||||
#define INPLACE_MULTIPLY 57
|
#define INPLACE_MULTIPLY 57
|
||||||
|
|
||||||
#define INPLACE_MODULO 59
|
#define INPLACE_MODULO 59
|
||||||
#define STORE_SUBSCR 60
|
#define STORE_SUBSCR 60
|
||||||
#define DELETE_SUBSCR 61
|
#define DELETE_SUBSCR 61
|
||||||
|
|
||||||
#define BINARY_LSHIFT 62
|
#define BINARY_LSHIFT 62
|
||||||
#define BINARY_RSHIFT 63
|
#define BINARY_RSHIFT 63
|
||||||
#define BINARY_AND 64
|
#define BINARY_AND 64
|
||||||
#define BINARY_XOR 65
|
#define BINARY_XOR 65
|
||||||
#define BINARY_OR 66
|
#define BINARY_OR 66
|
||||||
#define INPLACE_POWER 67
|
#define INPLACE_POWER 67
|
||||||
#define GET_ITER 68
|
#define GET_ITER 68
|
||||||
#define STORE_LOCALS 69
|
#define STORE_LOCALS 69
|
||||||
#define PRINT_EXPR 70
|
#define PRINT_EXPR 70
|
||||||
#define LOAD_BUILD_CLASS 71
|
#define LOAD_BUILD_CLASS 71
|
||||||
|
#define YIELD_FROM 72
|
||||||
|
|
||||||
#define INPLACE_LSHIFT 75
|
#define INPLACE_LSHIFT 75
|
||||||
#define INPLACE_RSHIFT 76
|
#define INPLACE_RSHIFT 76
|
||||||
#define INPLACE_AND 77
|
#define INPLACE_AND 77
|
||||||
#define INPLACE_XOR 78
|
#define INPLACE_XOR 78
|
||||||
#define INPLACE_OR 79
|
#define INPLACE_OR 79
|
||||||
#define BREAK_LOOP 80
|
#define BREAK_LOOP 80
|
||||||
#define WITH_CLEANUP 81
|
#define WITH_CLEANUP 81
|
||||||
|
|
||||||
#define RETURN_VALUE 83
|
#define RETURN_VALUE 83
|
||||||
#define IMPORT_STAR 84
|
#define IMPORT_STAR 84
|
||||||
|
|
||||||
#define YIELD_VALUE 86
|
#define YIELD_VALUE 86
|
||||||
#define POP_BLOCK 87
|
#define POP_BLOCK 87
|
||||||
#define END_FINALLY 88
|
#define END_FINALLY 88
|
||||||
#define POP_EXCEPT 89
|
#define POP_EXCEPT 89
|
||||||
|
|
||||||
#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */
|
#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */
|
||||||
|
|
||||||
#define STORE_NAME 90 /* Index in name list */
|
#define STORE_NAME 90 /* Index in name list */
|
||||||
#define DELETE_NAME 91 /* "" */
|
#define DELETE_NAME 91 /* "" */
|
||||||
#define UNPACK_SEQUENCE 92 /* Number of sequence items */
|
#define UNPACK_SEQUENCE 92 /* Number of sequence items */
|
||||||
#define FOR_ITER 93
|
#define FOR_ITER 93
|
||||||
#define UNPACK_EX 94 /* Num items before variable part +
|
#define UNPACK_EX 94 /* Num items before variable part +
|
||||||
(Num items after variable part << 8) */
|
(Num items after variable part << 8) */
|
||||||
|
|
||||||
#define STORE_ATTR 95 /* Index in name list */
|
#define STORE_ATTR 95 /* Index in name list */
|
||||||
#define DELETE_ATTR 96 /* "" */
|
#define DELETE_ATTR 96 /* "" */
|
||||||
#define STORE_GLOBAL 97 /* "" */
|
#define STORE_GLOBAL 97 /* "" */
|
||||||
#define DELETE_GLOBAL 98 /* "" */
|
#define DELETE_GLOBAL 98 /* "" */
|
||||||
|
|
||||||
#define LOAD_CONST 100 /* Index in const list */
|
#define LOAD_CONST 100 /* Index in const list */
|
||||||
#define LOAD_NAME 101 /* Index in name list */
|
#define LOAD_NAME 101 /* Index in name list */
|
||||||
#define BUILD_TUPLE 102 /* Number of tuple items */
|
#define BUILD_TUPLE 102 /* Number of tuple items */
|
||||||
#define BUILD_LIST 103 /* Number of list items */
|
#define BUILD_LIST 103 /* Number of list items */
|
||||||
#define BUILD_SET 104 /* Number of set items */
|
#define BUILD_SET 104 /* Number of set items */
|
||||||
#define BUILD_MAP 105 /* Always zero for now */
|
#define BUILD_MAP 105 /* Always zero for now */
|
||||||
#define LOAD_ATTR 106 /* Index in name list */
|
#define LOAD_ATTR 106 /* Index in name list */
|
||||||
#define COMPARE_OP 107 /* Comparison operator */
|
#define COMPARE_OP 107 /* Comparison operator */
|
||||||
#define IMPORT_NAME 108 /* Index in name list */
|
#define IMPORT_NAME 108 /* Index in name list */
|
||||||
#define IMPORT_FROM 109 /* Index in name list */
|
#define IMPORT_FROM 109 /* Index in name list */
|
||||||
|
|
||||||
#define JUMP_FORWARD 110 /* Number of bytes to skip */
|
#define JUMP_FORWARD 110 /* Number of bytes to skip */
|
||||||
#define JUMP_IF_FALSE_OR_POP 111 /* Target byte offset from beginning of code */
|
#define JUMP_IF_FALSE_OR_POP 111 /* Target byte offset from beginning of code */
|
||||||
#define JUMP_IF_TRUE_OR_POP 112 /* "" */
|
#define JUMP_IF_TRUE_OR_POP 112 /* "" */
|
||||||
#define JUMP_ABSOLUTE 113 /* "" */
|
#define JUMP_ABSOLUTE 113 /* "" */
|
||||||
#define POP_JUMP_IF_FALSE 114 /* "" */
|
#define POP_JUMP_IF_FALSE 114 /* "" */
|
||||||
#define POP_JUMP_IF_TRUE 115 /* "" */
|
#define POP_JUMP_IF_TRUE 115 /* "" */
|
||||||
|
|
||||||
#define LOAD_GLOBAL 116 /* Index in name list */
|
#define LOAD_GLOBAL 116 /* Index in name list */
|
||||||
|
|
||||||
#define CONTINUE_LOOP 119 /* Start of loop (absolute) */
|
#define CONTINUE_LOOP 119 /* Start of loop (absolute) */
|
||||||
#define SETUP_LOOP 120 /* Target address (relative) */
|
#define SETUP_LOOP 120 /* Target address (relative) */
|
||||||
#define SETUP_EXCEPT 121 /* "" */
|
#define SETUP_EXCEPT 121 /* "" */
|
||||||
#define SETUP_FINALLY 122 /* "" */
|
#define SETUP_FINALLY 122 /* "" */
|
||||||
|
|
||||||
#define LOAD_FAST 124 /* Local variable number */
|
#define LOAD_FAST 124 /* Local variable number */
|
||||||
#define STORE_FAST 125 /* Local variable number */
|
#define STORE_FAST 125 /* Local variable number */
|
||||||
#define DELETE_FAST 126 /* Local variable number */
|
#define DELETE_FAST 126 /* Local variable number */
|
||||||
|
|
||||||
#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */
|
#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */
|
||||||
/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
|
/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
|
||||||
#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */
|
#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */
|
||||||
#define MAKE_FUNCTION 132 /* #defaults + #kwdefaults<<8 + #annotations<<16 */
|
#define MAKE_FUNCTION 132 /* #defaults + #kwdefaults<<8 + #annotations<<16 */
|
||||||
#define BUILD_SLICE 133 /* Number of items */
|
#define BUILD_SLICE 133 /* Number of items */
|
||||||
|
|
||||||
#define MAKE_CLOSURE 134 /* same as MAKE_FUNCTION */
|
#define MAKE_CLOSURE 134 /* same as MAKE_FUNCTION */
|
||||||
#define LOAD_CLOSURE 135 /* Load free variable from closure */
|
#define LOAD_CLOSURE 135 /* Load free variable from closure */
|
||||||
|
@ -126,9 +127,9 @@ extern "C" {
|
||||||
|
|
||||||
/* The next 3 opcodes must be contiguous and satisfy
|
/* The next 3 opcodes must be contiguous and satisfy
|
||||||
(CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */
|
(CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */
|
||||||
#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */
|
#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */
|
||||||
#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */
|
#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */
|
||||||
#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */
|
#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */
|
||||||
|
|
||||||
#define SETUP_WITH 143
|
#define SETUP_WITH 143
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ extern "C" {
|
||||||
|
|
||||||
|
|
||||||
enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE,
|
enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE,
|
||||||
PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD};
|
PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD};
|
||||||
|
|
||||||
#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT)
|
#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT)
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,11 @@ typedef struct {
|
||||||
Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
|
Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
|
||||||
} PyOSErrorObject;
|
} PyOSErrorObject;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyException_HEAD
|
||||||
|
PyObject *value;
|
||||||
|
} PyStopIterationObject;
|
||||||
|
|
||||||
/* Compatibility typedefs */
|
/* Compatibility typedefs */
|
||||||
typedef PyOSErrorObject PyEnvironmentErrorObject;
|
typedef PyOSErrorObject PyEnvironmentErrorObject;
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
|
@ -380,6 +385,8 @@ PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason(
|
||||||
const char *reason /* UTF-8 encoded string */
|
const char *reason /* UTF-8 encoded string */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* create a StopIteration exception with the given value */
|
||||||
|
PyAPI_FUNC(PyObject *) PyStopIteration_Create(PyObject *);
|
||||||
|
|
||||||
/* These APIs aren't really part of the error implementation, but
|
/* These APIs aren't really part of the error implementation, but
|
||||||
often needed to format error messages; the native C lib APIs are
|
often needed to format error messages; the native C lib APIs are
|
||||||
|
|
|
@ -87,6 +87,7 @@ def_op('STORE_LOCALS', 69)
|
||||||
|
|
||||||
def_op('PRINT_EXPR', 70)
|
def_op('PRINT_EXPR', 70)
|
||||||
def_op('LOAD_BUILD_CLASS', 71)
|
def_op('LOAD_BUILD_CLASS', 71)
|
||||||
|
def_op('YIELD_FROM', 72)
|
||||||
|
|
||||||
def_op('INPLACE_LSHIFT', 75)
|
def_op('INPLACE_LSHIFT', 75)
|
||||||
def_op('INPLACE_RSHIFT', 76)
|
def_op('INPLACE_RSHIFT', 76)
|
||||||
|
|
|
@ -813,7 +813,8 @@ class ASTValidatorTests(unittest.TestCase):
|
||||||
self._check_comprehension(factory)
|
self._check_comprehension(factory)
|
||||||
|
|
||||||
def test_yield(self):
|
def test_yield(self):
|
||||||
self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
|
self.expr(ast.Yield(0, ast.Name("x", ast.Store())), "must have Load")
|
||||||
|
self.expr(ast.Yield(1, ast.Name("x", ast.Store())), "must have Load")
|
||||||
|
|
||||||
def test_compare(self):
|
def test_compare(self):
|
||||||
left = ast.Name("x", ast.Load())
|
left = ast.Name("x", ast.Load())
|
||||||
|
|
|
@ -728,29 +728,6 @@ Ye olde Fibonacci generator, tee style.
|
||||||
|
|
||||||
syntax_tests = """
|
syntax_tests = """
|
||||||
|
|
||||||
>>> def f():
|
|
||||||
... return 22
|
|
||||||
... yield 1
|
|
||||||
Traceback (most recent call last):
|
|
||||||
..
|
|
||||||
SyntaxError: 'return' with argument inside generator
|
|
||||||
|
|
||||||
>>> def f():
|
|
||||||
... yield 1
|
|
||||||
... return 22
|
|
||||||
Traceback (most recent call last):
|
|
||||||
..
|
|
||||||
SyntaxError: 'return' with argument inside generator
|
|
||||||
|
|
||||||
"return None" is not the same as "return" in a generator:
|
|
||||||
|
|
||||||
>>> def f():
|
|
||||||
... yield 1
|
|
||||||
... return None
|
|
||||||
Traceback (most recent call last):
|
|
||||||
..
|
|
||||||
SyntaxError: 'return' with argument inside generator
|
|
||||||
|
|
||||||
These are fine:
|
These are fine:
|
||||||
|
|
||||||
>>> def f():
|
>>> def f():
|
||||||
|
@ -866,20 +843,6 @@ These are fine:
|
||||||
>>> type(f())
|
>>> type(f())
|
||||||
<class 'generator'>
|
<class 'generator'>
|
||||||
|
|
||||||
|
|
||||||
>>> def f():
|
|
||||||
... if 0:
|
|
||||||
... lambda x: x # shouldn't trigger here
|
|
||||||
... return # or here
|
|
||||||
... def f(i):
|
|
||||||
... return 2*i # or here
|
|
||||||
... if 0:
|
|
||||||
... return 3 # but *this* sucks (line 8)
|
|
||||||
... if 0:
|
|
||||||
... yield 2 # because it's a generator (line 10)
|
|
||||||
Traceback (most recent call last):
|
|
||||||
SyntaxError: 'return' with argument inside generator
|
|
||||||
|
|
||||||
This one caused a crash (see SF bug 567538):
|
This one caused a crash (see SF bug 567538):
|
||||||
|
|
||||||
>>> def f():
|
>>> def f():
|
||||||
|
@ -1566,11 +1529,6 @@ Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
SyntaxError: 'yield' outside function
|
SyntaxError: 'yield' outside function
|
||||||
|
|
||||||
>>> def f(): return lambda x=(yield): 1
|
|
||||||
Traceback (most recent call last):
|
|
||||||
...
|
|
||||||
SyntaxError: 'return' with argument inside generator
|
|
||||||
|
|
||||||
>>> def f(): x = yield = y
|
>>> def f(): x = yield = y
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
|
|
|
@ -458,7 +458,39 @@ class GrammarTests(unittest.TestCase):
|
||||||
check_syntax_error(self, "class foo:return 1")
|
check_syntax_error(self, "class foo:return 1")
|
||||||
|
|
||||||
def test_yield(self):
|
def test_yield(self):
|
||||||
|
# Allowed as standalone statement
|
||||||
|
def g(): yield 1
|
||||||
|
def g(): yield from ()
|
||||||
|
# Allowed as RHS of assignment
|
||||||
|
def g(): x = yield 1
|
||||||
|
def g(): x = yield from ()
|
||||||
|
# Ordinary yield accepts implicit tuples
|
||||||
|
def g(): yield 1, 1
|
||||||
|
def g(): x = yield 1, 1
|
||||||
|
# 'yield from' does not
|
||||||
|
check_syntax_error(self, "def g(): yield from (), 1")
|
||||||
|
check_syntax_error(self, "def g(): x = yield from (), 1")
|
||||||
|
# Requires parentheses as subexpression
|
||||||
|
def g(): 1, (yield 1)
|
||||||
|
def g(): 1, (yield from ())
|
||||||
|
check_syntax_error(self, "def g(): 1, yield 1")
|
||||||
|
check_syntax_error(self, "def g(): 1, yield from ()")
|
||||||
|
# Requires parentheses as call argument
|
||||||
|
def g(): f((yield 1))
|
||||||
|
def g(): f((yield 1), 1)
|
||||||
|
def g(): f((yield from ()))
|
||||||
|
def g(): f((yield from ()), 1)
|
||||||
|
check_syntax_error(self, "def g(): f(yield 1)")
|
||||||
|
check_syntax_error(self, "def g(): f(yield 1, 1)")
|
||||||
|
check_syntax_error(self, "def g(): f(yield from ())")
|
||||||
|
check_syntax_error(self, "def g(): f(yield from (), 1)")
|
||||||
|
# Not allowed at top level
|
||||||
|
check_syntax_error(self, "yield")
|
||||||
|
check_syntax_error(self, "yield from")
|
||||||
|
# Not allowed at class scope
|
||||||
check_syntax_error(self, "class foo:yield 1")
|
check_syntax_error(self, "class foo:yield 1")
|
||||||
|
check_syntax_error(self, "class foo:yield from ()")
|
||||||
|
|
||||||
|
|
||||||
def test_raise(self):
|
def test_raise(self):
|
||||||
# 'raise' test [',' test]
|
# 'raise' test [',' test]
|
||||||
|
|
|
@ -50,6 +50,10 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
|
||||||
self.check_suite("def f(): (yield 1)*2")
|
self.check_suite("def f(): (yield 1)*2")
|
||||||
self.check_suite("def f(): return; yield 1")
|
self.check_suite("def f(): return; yield 1")
|
||||||
self.check_suite("def f(): yield 1; return")
|
self.check_suite("def f(): yield 1; return")
|
||||||
|
self.check_suite("def f(): yield from 1")
|
||||||
|
self.check_suite("def f(): x = yield from 1")
|
||||||
|
self.check_suite("def f(): f((yield from 1))")
|
||||||
|
self.check_suite("def f(): yield 1; return 1")
|
||||||
self.check_suite("def f():\n"
|
self.check_suite("def f():\n"
|
||||||
" for x in range(30):\n"
|
" for x in range(30):\n"
|
||||||
" yield x\n")
|
" yield x\n")
|
||||||
|
@ -621,7 +625,6 @@ class OtherParserCase(unittest.TestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
parser.expr("a", "b")
|
parser.expr("a", "b")
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(
|
support.run_unittest(
|
||||||
RoundtripLegalSyntaxTestCase,
|
RoundtripLegalSyntaxTestCase,
|
||||||
|
|
|
@ -727,7 +727,7 @@ class SizeofTest(unittest.TestCase):
|
||||||
nfrees = len(x.f_code.co_freevars)
|
nfrees = len(x.f_code.co_freevars)
|
||||||
extras = x.f_code.co_stacksize + x.f_code.co_nlocals +\
|
extras = x.f_code.co_stacksize + x.f_code.co_nlocals +\
|
||||||
ncells + nfrees - 1
|
ncells + nfrees - 1
|
||||||
check(x, size(vh + '12P3i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
|
check(x, size(vh + '13P3i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
|
||||||
# function
|
# function
|
||||||
def func(): pass
|
def func(): pass
|
||||||
check(func, size(h + '12P'))
|
check(func, size(h + '12P'))
|
||||||
|
|
|
@ -96,6 +96,7 @@ Dominic Binks
|
||||||
Philippe Biondi
|
Philippe Biondi
|
||||||
Stuart Bishop
|
Stuart Bishop
|
||||||
Roy Bixler
|
Roy Bixler
|
||||||
|
Renaud Blanch
|
||||||
Mike Bland
|
Mike Bland
|
||||||
Martin Bless
|
Martin Bless
|
||||||
Pablo Bleyer
|
Pablo Bleyer
|
||||||
|
@ -482,6 +483,7 @@ Geert Jansen
|
||||||
Jack Jansen
|
Jack Jansen
|
||||||
Bill Janssen
|
Bill Janssen
|
||||||
Thomas Jarosch
|
Thomas Jarosch
|
||||||
|
Zbigniew Jędrzejewski-Szmek
|
||||||
Julien Jehannet
|
Julien Jehannet
|
||||||
Drew Jenkins
|
Drew Jenkins
|
||||||
Flemming Kjær Jensen
|
Flemming Kjær Jensen
|
||||||
|
|
|
@ -10,6 +10,10 @@ What's New in Python 3.3 Alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- PEP 380, Issue #11682: Add "yield from <x>" to support easy delegation to
|
||||||
|
subgenerators (initial patch by Greg Ewing, integration into 3.3 by
|
||||||
|
Renaud Blanch, Ryan Kelly, Zbigniew Jędrzejewski-Szmek and Nick Coghlan)
|
||||||
|
|
||||||
- Issue #13748: Raw bytes literals can now be written with the ``rb`` prefix
|
- Issue #13748: Raw bytes literals can now be written with the ``rb`` prefix
|
||||||
as well as ``br``.
|
as well as ``br``.
|
||||||
|
|
||||||
|
|
|
@ -298,25 +298,25 @@ parser_richcompare(PyObject *left, PyObject *right, int op)
|
||||||
|
|
||||||
/* Convert return value to a Boolean */
|
/* Convert return value to a Boolean */
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Py_EQ:
|
case Py_EQ:
|
||||||
v = TEST_COND(result == 0);
|
v = TEST_COND(result == 0);
|
||||||
break;
|
break;
|
||||||
case Py_NE:
|
case Py_NE:
|
||||||
v = TEST_COND(result != 0);
|
v = TEST_COND(result != 0);
|
||||||
break;
|
break;
|
||||||
case Py_LE:
|
case Py_LE:
|
||||||
v = TEST_COND(result <= 0);
|
v = TEST_COND(result <= 0);
|
||||||
break;
|
break;
|
||||||
case Py_GE:
|
case Py_GE:
|
||||||
v = TEST_COND(result >= 0);
|
v = TEST_COND(result >= 0);
|
||||||
break;
|
break;
|
||||||
case Py_LT:
|
case Py_LT:
|
||||||
v = TEST_COND(result < 0);
|
v = TEST_COND(result < 0);
|
||||||
break;
|
break;
|
||||||
case Py_GT:
|
case Py_GT:
|
||||||
v = TEST_COND(result > 0);
|
v = TEST_COND(result > 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_BadArgument();
|
PyErr_BadArgument();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -976,6 +976,7 @@ VALIDATER(comp_iter); VALIDATER(comp_if);
|
||||||
VALIDATER(testlist_comp); VALIDATER(yield_expr);
|
VALIDATER(testlist_comp); VALIDATER(yield_expr);
|
||||||
VALIDATER(or_test);
|
VALIDATER(or_test);
|
||||||
VALIDATER(test_nocond); VALIDATER(lambdef_nocond);
|
VALIDATER(test_nocond); VALIDATER(lambdef_nocond);
|
||||||
|
VALIDATER(yield_arg);
|
||||||
|
|
||||||
#undef VALIDATER
|
#undef VALIDATER
|
||||||
|
|
||||||
|
@ -1636,22 +1637,49 @@ validate_raise_stmt(node *tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* yield_expr: 'yield' [testlist]
|
/* yield_expr: 'yield' [yield_arg]
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
validate_yield_expr(node *tree)
|
validate_yield_expr(node *tree)
|
||||||
{
|
{
|
||||||
int nch = NCH(tree);
|
int nch = NCH(tree);
|
||||||
int res = (validate_ntype(tree, yield_expr)
|
if (nch < 1 || nch > 2)
|
||||||
&& ((nch == 1) || (nch == 2))
|
return 0;
|
||||||
&& validate_name(CHILD(tree, 0), "yield"));
|
if (!validate_ntype(tree, yield_expr))
|
||||||
|
return 0;
|
||||||
if (res && (nch == 2))
|
if (!validate_name(CHILD(tree, 0), "yield"))
|
||||||
res = validate_testlist(CHILD(tree, 1));
|
return 0;
|
||||||
|
if (nch == 2) {
|
||||||
return (res);
|
if (!validate_yield_arg(CHILD(tree, 1)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* yield_arg: 'from' test | testlist
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
validate_yield_arg(node *tree)
|
||||||
|
{
|
||||||
|
int nch = NCH(tree);
|
||||||
|
if (!validate_ntype(tree, yield_arg))
|
||||||
|
return 0;
|
||||||
|
switch (nch) {
|
||||||
|
case 1:
|
||||||
|
if (!validate_testlist(CHILD(tree, nch - 1)))
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (!validate_name(CHILD(tree, 0), "from"))
|
||||||
|
return 0;
|
||||||
|
if (!validate_test(CHILD(tree, 1)))
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* yield_stmt: yield_expr
|
/* yield_stmt: yield_expr
|
||||||
*/
|
*/
|
||||||
|
@ -2120,16 +2148,16 @@ validate_comp_op(node *tree)
|
||||||
*/
|
*/
|
||||||
tree = CHILD(tree, 0);
|
tree = CHILD(tree, 0);
|
||||||
switch (TYPE(tree)) {
|
switch (TYPE(tree)) {
|
||||||
case LESS:
|
case LESS:
|
||||||
case GREATER:
|
case GREATER:
|
||||||
case EQEQUAL:
|
case EQEQUAL:
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
case NOTEQUAL:
|
case NOTEQUAL:
|
||||||
res = 1;
|
res = 1;
|
||||||
break;
|
break;
|
||||||
case NAME:
|
case NAME:
|
||||||
res = ((strcmp(STR(tree), "in") == 0)
|
res = ((strcmp(STR(tree), "in") == 0)
|
||||||
|| (strcmp(STR(tree), "is") == 0));
|
|| (strcmp(STR(tree), "is") == 0));
|
||||||
if (!res) {
|
if (!res) {
|
||||||
|
@ -2665,9 +2693,9 @@ validate_argument(node *tree)
|
||||||
{
|
{
|
||||||
int nch = NCH(tree);
|
int nch = NCH(tree);
|
||||||
int res = (validate_ntype(tree, argument)
|
int res = (validate_ntype(tree, argument)
|
||||||
&& ((nch == 1) || (nch == 2) || (nch == 3))
|
&& ((nch == 1) || (nch == 2) || (nch == 3)));
|
||||||
&& validate_test(CHILD(tree, 0)));
|
if (res)
|
||||||
|
res = validate_test(CHILD(tree, 0));
|
||||||
if (res && (nch == 2))
|
if (res && (nch == 2))
|
||||||
res = validate_comp_for(CHILD(tree, 1));
|
res = validate_comp_for(CHILD(tree, 1));
|
||||||
else if (res && (nch == 3))
|
else if (res && (nch == 3))
|
||||||
|
|
|
@ -2267,7 +2267,6 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
|
||||||
|
|
||||||
func = PyObject_GetAttrString(o, name);
|
func = PyObject_GetAttrString(o, name);
|
||||||
if (func == NULL) {
|
if (func == NULL) {
|
||||||
PyErr_SetString(PyExc_AttributeError, name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2311,7 +2310,6 @@ _PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
|
||||||
|
|
||||||
func = PyObject_GetAttrString(o, name);
|
func = PyObject_GetAttrString(o, name);
|
||||||
if (func == NULL) {
|
if (func == NULL) {
|
||||||
PyErr_SetString(PyExc_AttributeError, name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
|
|
|
@ -487,8 +487,70 @@ SimpleExtendsException(PyExc_Exception, TypeError,
|
||||||
/*
|
/*
|
||||||
* StopIteration extends Exception
|
* StopIteration extends Exception
|
||||||
*/
|
*/
|
||||||
SimpleExtendsException(PyExc_Exception, StopIteration,
|
|
||||||
"Signal the end from iterator.__next__().");
|
static PyMemberDef StopIteration_members[] = {
|
||||||
|
{"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0,
|
||||||
|
PyDoc_STR("generator return value")},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
Py_ssize_t size = PyTuple_GET_SIZE(args);
|
||||||
|
PyObject *value;
|
||||||
|
|
||||||
|
if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
|
||||||
|
return -1;
|
||||||
|
Py_CLEAR(self->value);
|
||||||
|
if (size > 0)
|
||||||
|
value = PyTuple_GET_ITEM(args, 0);
|
||||||
|
else
|
||||||
|
value = Py_None;
|
||||||
|
Py_INCREF(value);
|
||||||
|
self->value = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
StopIteration_clear(PyStopIterationObject *self)
|
||||||
|
{
|
||||||
|
Py_CLEAR(self->value);
|
||||||
|
return BaseException_clear((PyBaseExceptionObject *)self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
StopIteration_dealloc(PyStopIterationObject *self)
|
||||||
|
{
|
||||||
|
_PyObject_GC_UNTRACK(self);
|
||||||
|
StopIteration_clear(self);
|
||||||
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
|
||||||
|
{
|
||||||
|
Py_VISIT(self->value);
|
||||||
|
return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
PyStopIteration_Create(PyObject *value)
|
||||||
|
{
|
||||||
|
return PyObject_CallFunctionObjArgs(PyExc_StopIteration, value, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexExtendsException(
|
||||||
|
PyExc_Exception, /* base */
|
||||||
|
StopIteration, /* name */
|
||||||
|
StopIteration, /* prefix for *_init, etc */
|
||||||
|
0, /* new */
|
||||||
|
0, /* methods */
|
||||||
|
StopIteration_members, /* members */
|
||||||
|
0, /* getset */
|
||||||
|
0, /* str */
|
||||||
|
"Signal the end from iterator.__next__()."
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,11 +15,12 @@
|
||||||
#define OFF(x) offsetof(PyFrameObject, x)
|
#define OFF(x) offsetof(PyFrameObject, x)
|
||||||
|
|
||||||
static PyMemberDef frame_memberlist[] = {
|
static PyMemberDef frame_memberlist[] = {
|
||||||
{"f_back", T_OBJECT, OFF(f_back), READONLY},
|
{"f_back", T_OBJECT, OFF(f_back), READONLY},
|
||||||
{"f_code", T_OBJECT, OFF(f_code), READONLY},
|
{"f_code", T_OBJECT, OFF(f_code), READONLY},
|
||||||
{"f_builtins", T_OBJECT, OFF(f_builtins),READONLY},
|
{"f_builtins", T_OBJECT, OFF(f_builtins), READONLY},
|
||||||
{"f_globals", T_OBJECT, OFF(f_globals), READONLY},
|
{"f_globals", T_OBJECT, OFF(f_globals), READONLY},
|
||||||
{"f_lasti", T_INT, OFF(f_lasti), READONLY},
|
{"f_lasti", T_INT, OFF(f_lasti), READONLY},
|
||||||
|
{"f_yieldfrom", T_OBJECT, OFF(f_yieldfrom), READONLY},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -444,6 +445,7 @@ frame_dealloc(PyFrameObject *f)
|
||||||
Py_CLEAR(f->f_exc_type);
|
Py_CLEAR(f->f_exc_type);
|
||||||
Py_CLEAR(f->f_exc_value);
|
Py_CLEAR(f->f_exc_value);
|
||||||
Py_CLEAR(f->f_exc_traceback);
|
Py_CLEAR(f->f_exc_traceback);
|
||||||
|
Py_CLEAR(f->f_yieldfrom);
|
||||||
|
|
||||||
co = f->f_code;
|
co = f->f_code;
|
||||||
if (co->co_zombieframe == NULL)
|
if (co->co_zombieframe == NULL)
|
||||||
|
@ -475,6 +477,7 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
|
||||||
Py_VISIT(f->f_exc_type);
|
Py_VISIT(f->f_exc_type);
|
||||||
Py_VISIT(f->f_exc_value);
|
Py_VISIT(f->f_exc_value);
|
||||||
Py_VISIT(f->f_exc_traceback);
|
Py_VISIT(f->f_exc_traceback);
|
||||||
|
Py_VISIT(f->f_yieldfrom);
|
||||||
|
|
||||||
/* locals */
|
/* locals */
|
||||||
slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
|
slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
|
||||||
|
@ -508,6 +511,7 @@ frame_clear(PyFrameObject *f)
|
||||||
Py_CLEAR(f->f_exc_value);
|
Py_CLEAR(f->f_exc_value);
|
||||||
Py_CLEAR(f->f_exc_traceback);
|
Py_CLEAR(f->f_exc_traceback);
|
||||||
Py_CLEAR(f->f_trace);
|
Py_CLEAR(f->f_trace);
|
||||||
|
Py_CLEAR(f->f_yieldfrom);
|
||||||
|
|
||||||
/* locals */
|
/* locals */
|
||||||
slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
|
slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
|
||||||
|
@ -711,6 +715,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
|
||||||
f->f_lasti = -1;
|
f->f_lasti = -1;
|
||||||
f->f_lineno = code->co_firstlineno;
|
f->f_lineno = code->co_firstlineno;
|
||||||
f->f_iblock = 0;
|
f->f_iblock = 0;
|
||||||
|
f->f_yieldfrom = NULL;
|
||||||
|
|
||||||
_PyObject_GC_TRACK(f);
|
_PyObject_GC_TRACK(f);
|
||||||
return f;
|
return f;
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
|
|
||||||
|
static PyObject *gen_close(PyGenObject *gen, PyObject *args);
|
||||||
|
static void gen_undelegate(PyGenObject *gen);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
|
gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -90,12 +93,18 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
|
||||||
|
|
||||||
/* If the generator just returned (as opposed to yielding), signal
|
/* If the generator just returned (as opposed to yielding), signal
|
||||||
* that the generator is exhausted. */
|
* that the generator is exhausted. */
|
||||||
if (result == Py_None && f->f_stacktop == NULL) {
|
if (result && f->f_stacktop == NULL) {
|
||||||
Py_DECREF(result);
|
if (result == Py_None) {
|
||||||
result = NULL;
|
/* Delay exception instantiation if we can */
|
||||||
/* Set exception if not called by gen_iternext() */
|
|
||||||
if (arg)
|
|
||||||
PyErr_SetNone(PyExc_StopIteration);
|
PyErr_SetNone(PyExc_StopIteration);
|
||||||
|
} else {
|
||||||
|
PyObject *e = PyStopIteration_Create(result);
|
||||||
|
if (e != NULL) {
|
||||||
|
PyErr_SetObject(PyExc_StopIteration, e);
|
||||||
|
Py_DECREF(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_CLEAR(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result || f->f_stacktop == NULL) {
|
if (!result || f->f_stacktop == NULL) {
|
||||||
|
@ -111,8 +120,8 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
|
||||||
Py_XDECREF(t);
|
Py_XDECREF(t);
|
||||||
Py_XDECREF(v);
|
Py_XDECREF(v);
|
||||||
Py_XDECREF(tb);
|
Py_XDECREF(tb);
|
||||||
Py_DECREF(f);
|
|
||||||
gen->gi_frame = NULL;
|
gen->gi_frame = NULL;
|
||||||
|
Py_DECREF(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -125,17 +134,91 @@ return next yielded value or raise StopIteration.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gen_send(PyGenObject *gen, PyObject *arg)
|
gen_send(PyGenObject *gen, PyObject *arg)
|
||||||
{
|
{
|
||||||
return gen_send_ex(gen, arg, 0);
|
int exc = 0;
|
||||||
|
PyObject *ret;
|
||||||
|
PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
|
||||||
|
/* XXX (ncoghlan): Are the incref/decref on arg and yf strictly needed?
|
||||||
|
* Or would it be valid to rely on borrowed references?
|
||||||
|
*/
|
||||||
|
Py_INCREF(arg);
|
||||||
|
if (yf) {
|
||||||
|
Py_INCREF(yf);
|
||||||
|
if (PyGen_CheckExact(yf)) {
|
||||||
|
ret = gen_send((PyGenObject *)yf, arg);
|
||||||
|
} else {
|
||||||
|
if (arg == Py_None)
|
||||||
|
ret = PyIter_Next(yf);
|
||||||
|
else
|
||||||
|
ret = PyObject_CallMethod(yf, "send", "O", arg);
|
||||||
|
}
|
||||||
|
if (ret) {
|
||||||
|
Py_DECREF(yf);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
gen_undelegate(gen);
|
||||||
|
Py_CLEAR(arg);
|
||||||
|
if (PyGen_FetchStopIterationValue(&arg) < 0) {
|
||||||
|
exc = 1;
|
||||||
|
}
|
||||||
|
Py_DECREF(yf);
|
||||||
|
}
|
||||||
|
ret = gen_send_ex(gen, arg, exc);
|
||||||
|
done:
|
||||||
|
Py_XDECREF(arg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(close_doc,
|
PyDoc_STRVAR(close_doc,
|
||||||
"close(arg) -> raise GeneratorExit inside generator.");
|
"close(arg) -> raise GeneratorExit inside generator.");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This helper function is used by gen_close and gen_throw to
|
||||||
|
* close a subiterator being delegated to by yield-from.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen_close_iter(PyObject *yf)
|
||||||
|
{
|
||||||
|
PyObject *retval = NULL;
|
||||||
|
|
||||||
|
if (PyGen_CheckExact(yf)) {
|
||||||
|
retval = gen_close((PyGenObject *)yf, NULL);
|
||||||
|
if (retval == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PyObject *meth = PyObject_GetAttrString(yf, "close");
|
||||||
|
if (meth == NULL) {
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
PyErr_WriteUnraisable(yf);
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
} else {
|
||||||
|
retval = PyObject_CallFunction(meth, "");
|
||||||
|
Py_DECREF(meth);
|
||||||
|
if (!retval)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_XDECREF(retval);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gen_close(PyGenObject *gen, PyObject *args)
|
gen_close(PyGenObject *gen, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *retval;
|
PyObject *retval;
|
||||||
PyErr_SetNone(PyExc_GeneratorExit);
|
PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (yf) {
|
||||||
|
Py_INCREF(yf);
|
||||||
|
err = gen_close_iter(yf);
|
||||||
|
gen_undelegate(gen);
|
||||||
|
Py_DECREF(yf);
|
||||||
|
}
|
||||||
|
if (err == 0)
|
||||||
|
PyErr_SetNone(PyExc_GeneratorExit);
|
||||||
retval = gen_send_ex(gen, Py_None, 1);
|
retval = gen_send_ex(gen, Py_None, 1);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
Py_DECREF(retval);
|
Py_DECREF(retval);
|
||||||
|
@ -196,7 +279,7 @@ gen_del(PyObject *self)
|
||||||
_Py_NewReference(self);
|
_Py_NewReference(self);
|
||||||
self->ob_refcnt = refcnt;
|
self->ob_refcnt = refcnt;
|
||||||
}
|
}
|
||||||
assert(PyType_IS_GC(self->ob_type) &&
|
assert(PyType_IS_GC(Py_TYPE(self)) &&
|
||||||
_Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
|
_Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
|
||||||
|
|
||||||
/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
|
/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
|
||||||
|
@ -209,8 +292,8 @@ gen_del(PyObject *self)
|
||||||
* undone.
|
* undone.
|
||||||
*/
|
*/
|
||||||
#ifdef COUNT_ALLOCS
|
#ifdef COUNT_ALLOCS
|
||||||
--self->ob_type->tp_frees;
|
--(Py_TYPE(self)->tp_frees);
|
||||||
--self->ob_type->tp_allocs;
|
--(Py_TYPE(self)->tp_allocs);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,10 +309,55 @@ gen_throw(PyGenObject *gen, PyObject *args)
|
||||||
PyObject *typ;
|
PyObject *typ;
|
||||||
PyObject *tb = NULL;
|
PyObject *tb = NULL;
|
||||||
PyObject *val = NULL;
|
PyObject *val = NULL;
|
||||||
|
PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
|
if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (yf) {
|
||||||
|
PyObject *ret;
|
||||||
|
int err;
|
||||||
|
Py_INCREF(yf);
|
||||||
|
if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
|
||||||
|
err = gen_close_iter(yf);
|
||||||
|
Py_DECREF(yf);
|
||||||
|
gen_undelegate(gen);
|
||||||
|
if (err < 0)
|
||||||
|
return gen_send_ex(gen, Py_None, 1);
|
||||||
|
goto throw_here;
|
||||||
|
}
|
||||||
|
if (PyGen_CheckExact(yf)) {
|
||||||
|
ret = gen_throw((PyGenObject *)yf, args);
|
||||||
|
} else {
|
||||||
|
PyObject *meth = PyObject_GetAttrString(yf, "throw");
|
||||||
|
if (meth == NULL) {
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
Py_DECREF(yf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
Py_DECREF(yf);
|
||||||
|
gen_undelegate(gen);
|
||||||
|
goto throw_here;
|
||||||
|
}
|
||||||
|
ret = PyObject_CallObject(meth, args);
|
||||||
|
Py_DECREF(meth);
|
||||||
|
}
|
||||||
|
Py_DECREF(yf);
|
||||||
|
if (!ret) {
|
||||||
|
PyObject *val;
|
||||||
|
gen_undelegate(gen);
|
||||||
|
if (PyGen_FetchStopIterationValue(&val) == 0) {
|
||||||
|
ret = gen_send_ex(gen, val, 0);
|
||||||
|
Py_DECREF(val);
|
||||||
|
} else {
|
||||||
|
ret = gen_send_ex(gen, Py_None, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw_here:
|
||||||
/* First, check the traceback argument, replacing None with
|
/* First, check the traceback argument, replacing None with
|
||||||
NULL. */
|
NULL. */
|
||||||
if (tb == Py_None) {
|
if (tb == Py_None) {
|
||||||
|
@ -272,7 +400,7 @@ gen_throw(PyGenObject *gen, PyObject *args)
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"exceptions must be classes or instances "
|
"exceptions must be classes or instances "
|
||||||
"deriving from BaseException, not %s",
|
"deriving from BaseException, not %s",
|
||||||
typ->ob_type->tp_name);
|
Py_TYPE(typ)->tp_name);
|
||||||
goto failed_throw;
|
goto failed_throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,9 +419,74 @@ failed_throw:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gen_iternext(PyGenObject *gen)
|
gen_iternext(PyGenObject *gen)
|
||||||
{
|
{
|
||||||
return gen_send_ex(gen, NULL, 0);
|
PyObject *val = NULL;
|
||||||
|
PyObject *ret;
|
||||||
|
int exc = 0;
|
||||||
|
PyObject *yf = gen->gi_frame ? gen->gi_frame->f_yieldfrom : NULL;
|
||||||
|
if (yf) {
|
||||||
|
Py_INCREF(yf);
|
||||||
|
/* ceval.c ensures that yf is an iterator */
|
||||||
|
ret = Py_TYPE(yf)->tp_iternext(yf);
|
||||||
|
if (ret) {
|
||||||
|
Py_DECREF(yf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
gen_undelegate(gen);
|
||||||
|
if (PyGen_FetchStopIterationValue(&val) < 0)
|
||||||
|
exc = 1;
|
||||||
|
Py_DECREF(yf);
|
||||||
|
}
|
||||||
|
ret = gen_send_ex(gen, val, exc);
|
||||||
|
Py_XDECREF(val);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In certain recursive situations, a generator may lose its frame
|
||||||
|
* before we get a chance to clear f_yieldfrom, so we use this
|
||||||
|
* helper function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
gen_undelegate(PyGenObject *gen) {
|
||||||
|
if (gen->gi_frame) {
|
||||||
|
Py_XDECREF(gen->gi_frame->f_yieldfrom);
|
||||||
|
gen->gi_frame->f_yieldfrom = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If StopIteration exception is set, fetches its 'value'
|
||||||
|
* attribute if any, otherwise sets pvalue to None.
|
||||||
|
*
|
||||||
|
* Returns 0 if no exception or StopIteration is set.
|
||||||
|
* If any other exception is set, returns -1 and leaves
|
||||||
|
* pvalue unchanged.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
PyGen_FetchStopIterationValue(PyObject **pvalue) {
|
||||||
|
PyObject *et, *ev, *tb;
|
||||||
|
PyObject *value = NULL;
|
||||||
|
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
|
||||||
|
PyErr_Fetch(&et, &ev, &tb);
|
||||||
|
Py_XDECREF(et);
|
||||||
|
Py_XDECREF(tb);
|
||||||
|
if (ev) {
|
||||||
|
value = ((PyStopIterationObject *)ev)->value;
|
||||||
|
Py_DECREF(ev);
|
||||||
|
}
|
||||||
|
} else if (PyErr_Occurred()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (value == NULL) {
|
||||||
|
value = Py_None;
|
||||||
|
}
|
||||||
|
Py_INCREF(value);
|
||||||
|
*pvalue = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gen_repr(PyGenObject *gen)
|
gen_repr(PyGenObject *gen)
|
||||||
|
|
|
@ -59,7 +59,7 @@ module Python
|
||||||
| DictComp(expr key, expr value, comprehension* generators)
|
| DictComp(expr key, expr value, comprehension* generators)
|
||||||
| GeneratorExp(expr elt, comprehension* generators)
|
| GeneratorExp(expr elt, comprehension* generators)
|
||||||
-- the grammar constrains where yield expressions can occur
|
-- the grammar constrains where yield expressions can occur
|
||||||
| Yield(expr? value)
|
| Yield(int is_from, expr? value)
|
||||||
-- need sequences for compare to distinguish between
|
-- need sequences for compare to distinguish between
|
||||||
-- x < 4 < 3 and (x < 4) < 3
|
-- x < 4 < 3 and (x < 4) < 3
|
||||||
| Compare(expr left, cmpop* ops, expr* comparators)
|
| Compare(expr left, cmpop* ops, expr* comparators)
|
||||||
|
|
|
@ -231,7 +231,9 @@ static char *GeneratorExp_fields[]={
|
||||||
"generators",
|
"generators",
|
||||||
};
|
};
|
||||||
static PyTypeObject *Yield_type;
|
static PyTypeObject *Yield_type;
|
||||||
|
_Py_IDENTIFIER(is_from);
|
||||||
static char *Yield_fields[]={
|
static char *Yield_fields[]={
|
||||||
|
"is_from",
|
||||||
"value",
|
"value",
|
||||||
};
|
};
|
||||||
static PyTypeObject *Compare_type;
|
static PyTypeObject *Compare_type;
|
||||||
|
@ -810,7 +812,7 @@ static int init_types(void)
|
||||||
GeneratorExp_type = make_type("GeneratorExp", expr_type,
|
GeneratorExp_type = make_type("GeneratorExp", expr_type,
|
||||||
GeneratorExp_fields, 2);
|
GeneratorExp_fields, 2);
|
||||||
if (!GeneratorExp_type) return 0;
|
if (!GeneratorExp_type) return 0;
|
||||||
Yield_type = make_type("Yield", expr_type, Yield_fields, 1);
|
Yield_type = make_type("Yield", expr_type, Yield_fields, 2);
|
||||||
if (!Yield_type) return 0;
|
if (!Yield_type) return 0;
|
||||||
Compare_type = make_type("Compare", expr_type, Compare_fields, 3);
|
Compare_type = make_type("Compare", expr_type, Compare_fields, 3);
|
||||||
if (!Compare_type) return 0;
|
if (!Compare_type) return 0;
|
||||||
|
@ -1747,13 +1749,14 @@ GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ty
|
expr_ty
|
||||||
Yield(expr_ty value, int lineno, int col_offset, PyArena *arena)
|
Yield(int is_from, expr_ty value, int lineno, int col_offset, PyArena *arena)
|
||||||
{
|
{
|
||||||
expr_ty p;
|
expr_ty p;
|
||||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
p->kind = Yield_kind;
|
p->kind = Yield_kind;
|
||||||
|
p->v.Yield.is_from = is_from;
|
||||||
p->v.Yield.value = value;
|
p->v.Yield.value = value;
|
||||||
p->lineno = lineno;
|
p->lineno = lineno;
|
||||||
p->col_offset = col_offset;
|
p->col_offset = col_offset;
|
||||||
|
@ -2795,6 +2798,11 @@ ast2obj_expr(void* _o)
|
||||||
case Yield_kind:
|
case Yield_kind:
|
||||||
result = PyType_GenericNew(Yield_type, NULL, NULL);
|
result = PyType_GenericNew(Yield_type, NULL, NULL);
|
||||||
if (!result) goto failed;
|
if (!result) goto failed;
|
||||||
|
value = ast2obj_int(o->v.Yield.is_from);
|
||||||
|
if (!value) goto failed;
|
||||||
|
if (PyObject_SetAttrString(result, "is_from", value) == -1)
|
||||||
|
goto failed;
|
||||||
|
Py_DECREF(value);
|
||||||
value = ast2obj_expr(o->v.Yield.value);
|
value = ast2obj_expr(o->v.Yield.value);
|
||||||
if (!value) goto failed;
|
if (!value) goto failed;
|
||||||
if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
|
if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
|
||||||
|
@ -5337,8 +5345,21 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (isinstance) {
|
if (isinstance) {
|
||||||
|
int is_from;
|
||||||
expr_ty value;
|
expr_ty value;
|
||||||
|
|
||||||
|
if (_PyObject_HasAttrId(obj, &PyId_is_from)) {
|
||||||
|
int res;
|
||||||
|
tmp = _PyObject_GetAttrId(obj, &PyId_is_from);
|
||||||
|
if (tmp == NULL) goto failed;
|
||||||
|
res = obj2ast_int(tmp, &is_from, arena);
|
||||||
|
if (res != 0) goto failed;
|
||||||
|
Py_XDECREF(tmp);
|
||||||
|
tmp = NULL;
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "required field \"is_from\" missing from Yield");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (_PyObject_HasAttrId(obj, &PyId_value)) {
|
if (_PyObject_HasAttrId(obj, &PyId_value)) {
|
||||||
int res;
|
int res;
|
||||||
tmp = _PyObject_GetAttrId(obj, &PyId_value);
|
tmp = _PyObject_GetAttrId(obj, &PyId_value);
|
||||||
|
@ -5350,7 +5371,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
|
||||||
} else {
|
} else {
|
||||||
value = NULL;
|
value = NULL;
|
||||||
}
|
}
|
||||||
*out = Yield(value, lineno, col_offset, arena);
|
*out = Yield(is_from, value, lineno, col_offset, arena);
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
21
Python/ast.c
21
Python/ast.c
|
@ -2369,13 +2369,24 @@ ast_for_expr(struct compiling *c, const node *n)
|
||||||
}
|
}
|
||||||
return ast_for_binop(c, n);
|
return ast_for_binop(c, n);
|
||||||
case yield_expr: {
|
case yield_expr: {
|
||||||
|
node *an = NULL;
|
||||||
|
node *en = NULL;
|
||||||
|
int is_from = 0;
|
||||||
expr_ty exp = NULL;
|
expr_ty exp = NULL;
|
||||||
if (NCH(n) == 2) {
|
if (NCH(n) > 1)
|
||||||
exp = ast_for_testlist(c, CHILD(n, 1));
|
an = CHILD(n, 1); /* yield_arg */
|
||||||
|
if (an) {
|
||||||
|
en = CHILD(an, NCH(an) - 1);
|
||||||
|
if (NCH(an) == 2) {
|
||||||
|
is_from = 1;
|
||||||
|
exp = ast_for_expr(c, en);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
exp = ast_for_testlist(c, en);
|
||||||
if (!exp)
|
if (!exp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena);
|
return Yield(is_from, exp, LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
}
|
}
|
||||||
case factor:
|
case factor:
|
||||||
if (NCH(n) == 1) {
|
if (NCH(n) == 1) {
|
||||||
|
@ -2399,7 +2410,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
||||||
/*
|
/*
|
||||||
arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
|
arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
|
||||||
| '**' test)
|
| '**' test)
|
||||||
argument: [test '='] test [comp_for] # Really [keyword '='] test
|
argument: [test '='] (test) [comp_for] # Really [keyword '='] test
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int i, nargs, nkeywords, ngens;
|
int i, nargs, nkeywords, ngens;
|
||||||
|
@ -2693,7 +2704,7 @@ ast_for_flow_stmt(struct compiling *c, const node *n)
|
||||||
continue_stmt: 'continue'
|
continue_stmt: 'continue'
|
||||||
return_stmt: 'return' [testlist]
|
return_stmt: 'return' [testlist]
|
||||||
yield_stmt: yield_expr
|
yield_stmt: yield_expr
|
||||||
yield_expr: 'yield' testlist
|
yield_expr: 'yield' testlist | 'yield' 'from' test
|
||||||
raise_stmt: 'raise' [test [',' test [',' test]]]
|
raise_stmt: 'raise' [test [',' test [',' test]]]
|
||||||
*/
|
*/
|
||||||
node *ch;
|
node *ch;
|
||||||
|
|
|
@ -1828,6 +1828,52 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||||
why = WHY_RETURN;
|
why = WHY_RETURN;
|
||||||
goto fast_block_end;
|
goto fast_block_end;
|
||||||
|
|
||||||
|
TARGET(YIELD_FROM)
|
||||||
|
u = POP();
|
||||||
|
x = PyObject_GetIter(u);
|
||||||
|
Py_DECREF(u);
|
||||||
|
if (x == NULL)
|
||||||
|
break;
|
||||||
|
/* x is now the iterator, make the first next() call */
|
||||||
|
retval = (*Py_TYPE(x)->tp_iternext)(x);
|
||||||
|
if (!retval) {
|
||||||
|
/* iter may be exhausted */
|
||||||
|
Py_CLEAR(x);
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_StopIteration)) {
|
||||||
|
/* some other exception */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* try to get return value from exception */
|
||||||
|
PyObject *et, *ev, *tb;
|
||||||
|
PyErr_Fetch(&et, &ev, &tb);
|
||||||
|
Py_XDECREF(et);
|
||||||
|
Py_XDECREF(tb);
|
||||||
|
/* u is return value */
|
||||||
|
u = NULL;
|
||||||
|
if (ev) {
|
||||||
|
u = PyObject_GetAttrString(ev, "value");
|
||||||
|
Py_DECREF(ev);
|
||||||
|
if (u == NULL) {
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
/* some other exception */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (u == NULL) {
|
||||||
|
u = Py_None;
|
||||||
|
Py_INCREF(u);
|
||||||
|
}
|
||||||
|
PUSH(u);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* x is iterator, retval is value to be yielded */
|
||||||
|
f->f_yieldfrom = x;
|
||||||
|
f->f_stacktop = stack_pointer;
|
||||||
|
why = WHY_YIELD;
|
||||||
|
goto fast_yield;
|
||||||
|
|
||||||
TARGET(YIELD_VALUE)
|
TARGET(YIELD_VALUE)
|
||||||
retval = POP();
|
retval = POP();
|
||||||
f->f_stacktop = stack_pointer;
|
f->f_stacktop = stack_pointer;
|
||||||
|
|
|
@ -840,6 +840,7 @@ opcode_stack_effect(int opcode, int oparg)
|
||||||
case IMPORT_STAR:
|
case IMPORT_STAR:
|
||||||
return -1;
|
return -1;
|
||||||
case YIELD_VALUE:
|
case YIELD_VALUE:
|
||||||
|
case YIELD_FROM:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case POP_BLOCK:
|
case POP_BLOCK:
|
||||||
|
@ -3318,7 +3319,12 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
||||||
else {
|
else {
|
||||||
ADDOP_O(c, LOAD_CONST, Py_None, consts);
|
ADDOP_O(c, LOAD_CONST, Py_None, consts);
|
||||||
}
|
}
|
||||||
ADDOP(c, YIELD_VALUE);
|
if (e->v.Yield.is_from) {
|
||||||
|
ADDOP(c, YIELD_FROM);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ADDOP(c, YIELD_VALUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Compare_kind:
|
case Compare_kind:
|
||||||
return compiler_compare(c, e);
|
return compiler_compare(c, e);
|
||||||
|
|
|
@ -1791,7 +1791,7 @@ static arc arcs_80_0[1] = {
|
||||||
{167, 1},
|
{167, 1},
|
||||||
};
|
};
|
||||||
static arc arcs_80_1[2] = {
|
static arc arcs_80_1[2] = {
|
||||||
{9, 2},
|
{168, 2},
|
||||||
{0, 1},
|
{0, 1},
|
||||||
};
|
};
|
||||||
static arc arcs_80_2[1] = {
|
static arc arcs_80_2[1] = {
|
||||||
|
@ -1802,171 +1802,188 @@ static state states_80[3] = {
|
||||||
{2, arcs_80_1},
|
{2, arcs_80_1},
|
||||||
{1, arcs_80_2},
|
{1, arcs_80_2},
|
||||||
};
|
};
|
||||||
static dfa dfas[81] = {
|
static arc arcs_81_0[2] = {
|
||||||
{256, "single_input", 0, 3, states_0,
|
{73, 1},
|
||||||
"\004\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204"},
|
{9, 2},
|
||||||
{257, "file_input", 0, 2, states_1,
|
|
||||||
"\204\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204"},
|
|
||||||
{258, "eval_input", 0, 3, states_2,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{259, "decorator", 0, 7, states_3,
|
|
||||||
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{260, "decorators", 0, 2, states_4,
|
|
||||||
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{261, "decorated", 0, 3, states_5,
|
|
||||||
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{262, "funcdef", 0, 8, states_6,
|
|
||||||
"\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{263, "parameters", 0, 4, states_7,
|
|
||||||
"\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{264, "typedargslist", 0, 18, states_8,
|
|
||||||
"\000\000\040\200\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{265, "tfpdef", 0, 4, states_9,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{266, "varargslist", 0, 18, states_10,
|
|
||||||
"\000\000\040\200\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{267, "vfpdef", 0, 2, states_11,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{268, "stmt", 0, 2, states_12,
|
|
||||||
"\000\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204"},
|
|
||||||
{269, "simple_stmt", 0, 4, states_13,
|
|
||||||
"\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200"},
|
|
||||||
{270, "small_stmt", 0, 2, states_14,
|
|
||||||
"\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200"},
|
|
||||||
{271, "expr_stmt", 0, 6, states_15,
|
|
||||||
"\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{272, "testlist_star_expr", 0, 3, states_16,
|
|
||||||
"\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{273, "augassign", 0, 2, states_17,
|
|
||||||
"\000\000\000\000\000\000\376\037\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{274, "del_stmt", 0, 3, states_18,
|
|
||||||
"\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{275, "pass_stmt", 0, 2, states_19,
|
|
||||||
"\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{276, "flow_stmt", 0, 2, states_20,
|
|
||||||
"\000\000\000\000\000\000\000\000\340\001\000\000\000\000\000\000\000\000\000\000\200"},
|
|
||||||
{277, "break_stmt", 0, 2, states_21,
|
|
||||||
"\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{278, "continue_stmt", 0, 2, states_22,
|
|
||||||
"\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{279, "return_stmt", 0, 3, states_23,
|
|
||||||
"\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{280, "yield_stmt", 0, 2, states_24,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"},
|
|
||||||
{281, "raise_stmt", 0, 5, states_25,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{282, "import_stmt", 0, 2, states_26,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\022\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{283, "import_name", 0, 3, states_27,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{284, "import_from", 0, 8, states_28,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{285, "import_as_name", 0, 4, states_29,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{286, "dotted_as_name", 0, 4, states_30,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{287, "import_as_names", 0, 3, states_31,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{288, "dotted_as_names", 0, 2, states_32,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{289, "dotted_name", 0, 2, states_33,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{290, "global_stmt", 0, 3, states_34,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{291, "nonlocal_stmt", 0, 3, states_35,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{292, "assert_stmt", 0, 5, states_36,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{293, "compound_stmt", 0, 2, states_37,
|
|
||||||
"\000\010\020\000\000\000\000\000\000\000\000\220\045\000\000\000\000\000\000\000\004"},
|
|
||||||
{294, "if_stmt", 0, 8, states_38,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{295, "while_stmt", 0, 8, states_39,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{296, "for_stmt", 0, 10, states_40,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"},
|
|
||||||
{297, "try_stmt", 0, 13, states_41,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000"},
|
|
||||||
{298, "with_stmt", 0, 5, states_42,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"},
|
|
||||||
{299, "with_item", 0, 4, states_43,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{300, "except_clause", 0, 5, states_44,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"},
|
|
||||||
{301, "suite", 0, 5, states_45,
|
|
||||||
"\004\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200"},
|
|
||||||
{302, "test", 0, 6, states_46,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{303, "test_nocond", 0, 2, states_47,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{304, "lambdef", 0, 5, states_48,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000"},
|
|
||||||
{305, "lambdef_nocond", 0, 5, states_49,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000"},
|
|
||||||
{306, "or_test", 0, 2, states_50,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000"},
|
|
||||||
{307, "and_test", 0, 2, states_51,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000"},
|
|
||||||
{308, "not_test", 0, 3, states_52,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000"},
|
|
||||||
{309, "comparison", 0, 2, states_53,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{310, "comp_op", 0, 4, states_54,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\002\000\220\177\000\000\000\000\000"},
|
|
||||||
{311, "star_expr", 0, 3, states_55,
|
|
||||||
"\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{312, "expr", 0, 2, states_56,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{313, "xor_expr", 0, 2, states_57,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{314, "and_expr", 0, 2, states_58,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{315, "shift_expr", 0, 2, states_59,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{316, "arith_expr", 0, 2, states_60,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{317, "term", 0, 2, states_61,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{318, "factor", 0, 3, states_62,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{319, "power", 0, 4, states_63,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000"},
|
|
||||||
{320, "atom", 0, 9, states_64,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000"},
|
|
||||||
{321, "testlist_comp", 0, 5, states_65,
|
|
||||||
"\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{322, "trailer", 0, 7, states_66,
|
|
||||||
"\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\020\000\000"},
|
|
||||||
{323, "subscriptlist", 0, 3, states_67,
|
|
||||||
"\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{324, "subscript", 0, 5, states_68,
|
|
||||||
"\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{325, "sliceop", 0, 3, states_69,
|
|
||||||
"\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{326, "exprlist", 0, 3, states_70,
|
|
||||||
"\000\040\040\200\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000"},
|
|
||||||
{327, "testlist", 0, 3, states_71,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{328, "dictorsetmaker", 0, 11, states_72,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{329, "classdef", 0, 8, states_73,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004"},
|
|
||||||
{330, "arglist", 0, 8, states_74,
|
|
||||||
"\000\040\040\200\001\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{331, "argument", 0, 4, states_75,
|
|
||||||
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000"},
|
|
||||||
{332, "comp_iter", 0, 2, states_76,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000"},
|
|
||||||
{333, "comp_for", 0, 6, states_77,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"},
|
|
||||||
{334, "comp_if", 0, 4, states_78,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{335, "encoding_decl", 0, 2, states_79,
|
|
||||||
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
|
||||||
{336, "yield_expr", 0, 3, states_80,
|
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"},
|
|
||||||
};
|
};
|
||||||
static label labels[168] = {
|
static arc arcs_81_1[1] = {
|
||||||
|
{24, 2},
|
||||||
|
};
|
||||||
|
static arc arcs_81_2[1] = {
|
||||||
|
{0, 2},
|
||||||
|
};
|
||||||
|
static state states_81[3] = {
|
||||||
|
{2, arcs_81_0},
|
||||||
|
{1, arcs_81_1},
|
||||||
|
{1, arcs_81_2},
|
||||||
|
};
|
||||||
|
static dfa dfas[82] = {
|
||||||
|
{256, "single_input", 0, 3, states_0,
|
||||||
|
"\004\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"},
|
||||||
|
{257, "file_input", 0, 2, states_1,
|
||||||
|
"\204\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"},
|
||||||
|
{258, "eval_input", 0, 3, states_2,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{259, "decorator", 0, 7, states_3,
|
||||||
|
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{260, "decorators", 0, 2, states_4,
|
||||||
|
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{261, "decorated", 0, 3, states_5,
|
||||||
|
"\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{262, "funcdef", 0, 8, states_6,
|
||||||
|
"\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{263, "parameters", 0, 4, states_7,
|
||||||
|
"\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{264, "typedargslist", 0, 18, states_8,
|
||||||
|
"\000\000\040\200\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{265, "tfpdef", 0, 4, states_9,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{266, "varargslist", 0, 18, states_10,
|
||||||
|
"\000\000\040\200\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{267, "vfpdef", 0, 2, states_11,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{268, "stmt", 0, 2, states_12,
|
||||||
|
"\000\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"},
|
||||||
|
{269, "simple_stmt", 0, 4, states_13,
|
||||||
|
"\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"},
|
||||||
|
{270, "small_stmt", 0, 2, states_14,
|
||||||
|
"\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"},
|
||||||
|
{271, "expr_stmt", 0, 6, states_15,
|
||||||
|
"\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{272, "testlist_star_expr", 0, 3, states_16,
|
||||||
|
"\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{273, "augassign", 0, 2, states_17,
|
||||||
|
"\000\000\000\000\000\000\376\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{274, "del_stmt", 0, 3, states_18,
|
||||||
|
"\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{275, "pass_stmt", 0, 2, states_19,
|
||||||
|
"\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{276, "flow_stmt", 0, 2, states_20,
|
||||||
|
"\000\000\000\000\000\000\000\000\340\001\000\000\000\000\000\000\000\000\000\000\200\000"},
|
||||||
|
{277, "break_stmt", 0, 2, states_21,
|
||||||
|
"\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{278, "continue_stmt", 0, 2, states_22,
|
||||||
|
"\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{279, "return_stmt", 0, 3, states_23,
|
||||||
|
"\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{280, "yield_stmt", 0, 2, states_24,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"},
|
||||||
|
{281, "raise_stmt", 0, 5, states_25,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{282, "import_stmt", 0, 2, states_26,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\022\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{283, "import_name", 0, 3, states_27,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{284, "import_from", 0, 8, states_28,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{285, "import_as_name", 0, 4, states_29,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{286, "dotted_as_name", 0, 4, states_30,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{287, "import_as_names", 0, 3, states_31,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{288, "dotted_as_names", 0, 2, states_32,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{289, "dotted_name", 0, 2, states_33,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{290, "global_stmt", 0, 3, states_34,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{291, "nonlocal_stmt", 0, 3, states_35,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{292, "assert_stmt", 0, 5, states_36,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{293, "compound_stmt", 0, 2, states_37,
|
||||||
|
"\000\010\020\000\000\000\000\000\000\000\000\220\045\000\000\000\000\000\000\000\004\000"},
|
||||||
|
{294, "if_stmt", 0, 8, states_38,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{295, "while_stmt", 0, 8, states_39,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{296, "for_stmt", 0, 10, states_40,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{297, "try_stmt", 0, 13, states_41,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{298, "with_stmt", 0, 5, states_42,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{299, "with_item", 0, 4, states_43,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{300, "except_clause", 0, 5, states_44,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"},
|
||||||
|
{301, "suite", 0, 5, states_45,
|
||||||
|
"\004\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"},
|
||||||
|
{302, "test", 0, 6, states_46,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{303, "test_nocond", 0, 2, states_47,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{304, "lambdef", 0, 5, states_48,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"},
|
||||||
|
{305, "lambdef_nocond", 0, 5, states_49,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"},
|
||||||
|
{306, "or_test", 0, 2, states_50,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"},
|
||||||
|
{307, "and_test", 0, 2, states_51,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"},
|
||||||
|
{308, "not_test", 0, 3, states_52,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"},
|
||||||
|
{309, "comparison", 0, 2, states_53,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{310, "comp_op", 0, 4, states_54,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\002\000\220\177\000\000\000\000\000\000"},
|
||||||
|
{311, "star_expr", 0, 3, states_55,
|
||||||
|
"\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{312, "expr", 0, 2, states_56,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{313, "xor_expr", 0, 2, states_57,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{314, "and_expr", 0, 2, states_58,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{315, "shift_expr", 0, 2, states_59,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{316, "arith_expr", 0, 2, states_60,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{317, "term", 0, 2, states_61,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{318, "factor", 0, 3, states_62,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{319, "power", 0, 4, states_63,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000\000"},
|
||||||
|
{320, "atom", 0, 9, states_64,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000\000"},
|
||||||
|
{321, "testlist_comp", 0, 5, states_65,
|
||||||
|
"\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{322, "trailer", 0, 7, states_66,
|
||||||
|
"\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\020\000\000\000"},
|
||||||
|
{323, "subscriptlist", 0, 3, states_67,
|
||||||
|
"\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{324, "subscript", 0, 5, states_68,
|
||||||
|
"\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{325, "sliceop", 0, 3, states_69,
|
||||||
|
"\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{326, "exprlist", 0, 3, states_70,
|
||||||
|
"\000\040\040\200\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"},
|
||||||
|
{327, "testlist", 0, 3, states_71,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{328, "dictorsetmaker", 0, 11, states_72,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{329, "classdef", 0, 8, states_73,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000"},
|
||||||
|
{330, "arglist", 0, 8, states_74,
|
||||||
|
"\000\040\040\200\001\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{331, "argument", 0, 4, states_75,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
{332, "comp_iter", 0, 2, states_76,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{333, "comp_for", 0, 6, states_77,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{334, "comp_if", 0, 4, states_78,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{335, "encoding_decl", 0, 2, states_79,
|
||||||
|
"\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
|
||||||
|
{336, "yield_expr", 0, 3, states_80,
|
||||||
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"},
|
||||||
|
{337, "yield_arg", 0, 3, states_81,
|
||||||
|
"\000\040\040\000\000\000\000\000\000\202\000\000\000\200\020\000\000\206\120\076\000\000"},
|
||||||
|
};
|
||||||
|
static label labels[169] = {
|
||||||
{0, "EMPTY"},
|
{0, "EMPTY"},
|
||||||
{256, 0},
|
{256, 0},
|
||||||
{4, 0},
|
{4, 0},
|
||||||
|
@ -2135,10 +2152,11 @@ static label labels[168] = {
|
||||||
{334, 0},
|
{334, 0},
|
||||||
{335, 0},
|
{335, 0},
|
||||||
{1, "yield"},
|
{1, "yield"},
|
||||||
|
{337, 0},
|
||||||
};
|
};
|
||||||
grammar _PyParser_Grammar = {
|
grammar _PyParser_Grammar = {
|
||||||
81,
|
82,
|
||||||
dfas,
|
dfas,
|
||||||
{168, labels},
|
{169, labels},
|
||||||
256
|
256
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,7 +71,7 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_STORE_LOCALS,
|
&&TARGET_STORE_LOCALS,
|
||||||
&&TARGET_PRINT_EXPR,
|
&&TARGET_PRINT_EXPR,
|
||||||
&&TARGET_LOAD_BUILD_CLASS,
|
&&TARGET_LOAD_BUILD_CLASS,
|
||||||
&&_unknown_opcode,
|
&&TARGET_YIELD_FROM,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&TARGET_INPLACE_LSHIFT,
|
&&TARGET_INPLACE_LSHIFT,
|
||||||
|
|
|
@ -19,10 +19,6 @@
|
||||||
|
|
||||||
#define IMPORT_STAR_WARNING "import * only allowed at module level"
|
#define IMPORT_STAR_WARNING "import * only allowed at module level"
|
||||||
|
|
||||||
#define RETURN_VAL_IN_GENERATOR \
|
|
||||||
"'return' with argument inside generator"
|
|
||||||
|
|
||||||
|
|
||||||
static PySTEntryObject *
|
static PySTEntryObject *
|
||||||
ste_new(struct symtable *st, identifier name, _Py_block_ty block,
|
ste_new(struct symtable *st, identifier name, _Py_block_ty block,
|
||||||
void *key, int lineno, int col_offset)
|
void *key, int lineno, int col_offset)
|
||||||
|
@ -1133,14 +1129,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
|
||||||
if (s->v.Return.value) {
|
if (s->v.Return.value) {
|
||||||
VISIT(st, expr, s->v.Return.value);
|
VISIT(st, expr, s->v.Return.value);
|
||||||
st->st_cur->ste_returns_value = 1;
|
st->st_cur->ste_returns_value = 1;
|
||||||
if (st->st_cur->ste_generator) {
|
|
||||||
PyErr_SetString(PyExc_SyntaxError,
|
|
||||||
RETURN_VAL_IN_GENERATOR);
|
|
||||||
PyErr_SyntaxLocationEx(st->st_filename,
|
|
||||||
s->lineno,
|
|
||||||
s->col_offset);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Delete_kind:
|
case Delete_kind:
|
||||||
|
@ -1345,13 +1333,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
||||||
if (e->v.Yield.value)
|
if (e->v.Yield.value)
|
||||||
VISIT(st, expr, e->v.Yield.value);
|
VISIT(st, expr, e->v.Yield.value);
|
||||||
st->st_cur->ste_generator = 1;
|
st->st_cur->ste_generator = 1;
|
||||||
if (st->st_cur->ste_returns_value) {
|
|
||||||
PyErr_SetString(PyExc_SyntaxError,
|
|
||||||
RETURN_VAL_IN_GENERATOR);
|
|
||||||
PyErr_SyntaxLocationEx(st->st_filename,
|
|
||||||
e->lineno, e->col_offset);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Compare_kind:
|
case Compare_kind:
|
||||||
VISIT(st, expr, e->v.Compare.left);
|
VISIT(st, expr, e->v.Compare.left);
|
||||||
|
|
Loading…
Reference in New Issue