diff options
author | Yury Selivanov <yury@magic.io> | 2016-09-09 03:50:03 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2016-09-09 03:50:03 (GMT) |
commit | f8cb8a16a344ab208fd46876c4b63604987347b8 (patch) | |
tree | c44caa48291401d1e1e388004d2762513ac88c93 | |
parent | 09ad17810c38d1aaae02de69084dd2a8ad9f5cdb (diff) | |
download | cpython-f8cb8a16a344ab208fd46876c4b63604987347b8.zip cpython-f8cb8a16a344ab208fd46876c4b63604987347b8.tar.gz cpython-f8cb8a16a344ab208fd46876c4b63604987347b8.tar.bz2 |
Issue #27985: Implement PEP 526 -- Syntax for Variable Annotations.
Patch by Ivan Levkivskyi.
45 files changed, 3116 insertions, 1182 deletions
diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 3d05c14..f80b6df 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -964,6 +964,18 @@ Glossary ``'\r'``. See :pep:`278` and :pep:`3116`, as well as :func:`bytes.splitlines` for an additional use. + variable annotation + A type metadata value associated with a module global variable or + a class attribute. Its syntax is explained in section :ref:`annassign`. + Annotations are stored in the :attr:`__annotations__` special + attribute of a class or module object and can be accessed using + :func:`typing.get_type_hints`. + + Python itself does not assign any particular meaning to variable + annotations. They are intended to be interpreted by third-party libraries + or type checking tools. See :pep:`526`, :pep:`484` which describe + some of their potential uses. + virtual environment A cooperatively isolated runtime environment that allows Python users and applications to install and upgrade Python distribution packages diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index b74df0a..0a64d46 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -607,6 +607,12 @@ iterations of the loop. .. versionadded:: 3.3 +.. opcode:: SETUP_ANNOTATIONS + + Checks whether ``__annotations__`` is defined in ``locals()``, if not it is + set up to an empty ``dict``. This opcode is only emmitted if a class + or module body contains :term:`variable annotations <variable annotation>` + statically. .. opcode:: IMPORT_STAR @@ -890,6 +896,11 @@ All of the following opcodes use their arguments. Deletes local ``co_varnames[var_num]``. +.. opcode:: STORE_ANNOTATION (namei) + + Stores TOS as ``locals()['__annotations__'][co_names[namei]] = TOS``. + + .. opcode:: LOAD_CLOSURE (i) Pushes a reference to the cell contained in slot *i* of the cell and free diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index a075503..3d581a5 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -686,33 +686,36 @@ Modules Attribute assignment updates the module's namespace dictionary, e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. - .. index:: single: __dict__ (module attribute) - - Special read-only attribute: :attr:`~object.__dict__` is the module's namespace as a - dictionary object. - - .. impl-detail:: - - Because of the way CPython clears module dictionaries, the module - dictionary will be cleared when the module falls out of scope even if the - dictionary still has live references. To avoid this, copy the dictionary - or keep the module around while using its dictionary directly. - .. index:: single: __name__ (module attribute) single: __doc__ (module attribute) single: __file__ (module attribute) + single: __annotations__ (module attribute) pair: module; namespace Predefined (writable) attributes: :attr:`__name__` is the module's name; :attr:`__doc__` is the module's documentation string, or ``None`` if - unavailable; :attr:`__file__` is the pathname of the file from which the + unavailable; :attr:`__annotations__` (optional) is a dictionary containing + :term:`variable annotations <variable annotation>` collected during module + body execution; :attr:`__file__` is the pathname of the file from which the module was loaded, if it was loaded from a file. The :attr:`__file__` attribute may be missing for certain types of modules, such as C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file. + .. index:: single: __dict__ (module attribute) + + Special read-only attribute: :attr:`~object.__dict__` is the module's + namespace as a dictionary object. + + .. impl-detail:: + + Because of the way CPython clears module dictionaries, the module + dictionary will be cleared when the module falls out of scope even if the + dictionary still has live references. To avoid this, copy the dictionary + or keep the module around while using its dictionary directly. + Custom classes Custom class types are typically created by class definitions (see section :ref:`class`). A class has a namespace implemented by a dictionary object. @@ -761,13 +764,17 @@ Custom classes single: __dict__ (class attribute) single: __bases__ (class attribute) single: __doc__ (class attribute) + single: __annotations__ (class attribute) Special attributes: :attr:`~definition.__name__` is the class name; :attr:`__module__` is the module name in which the class was defined; :attr:`~object.__dict__` is the dictionary containing the class's namespace; :attr:`~class.__bases__` is a tuple (possibly empty or a singleton) containing the base classes, in the order of their occurrence in the base class list; :attr:`__doc__` is the - class's documentation string, or None if undefined. + class's documentation string, or None if undefined; + :attr:`__annotations__` (optional) is a dictionary containing + :term:`variable annotations <variable annotation>` collected during + class body execution. Class instances .. index:: diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index eee3f43..1973272 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -16,6 +16,7 @@ simple statements is: : | `assert_stmt` : | `assignment_stmt` : | `augmented_assignment_stmt` + : | `annotated_assignment_stmt` : | `pass_stmt` : | `del_stmt` : | `return_stmt` @@ -312,6 +313,49 @@ For targets which are attribute references, the same :ref:`caveat about class and instance attributes <attr-target-note>` applies as for regular assignments. +.. _annassign: + +Annotated assignment statements +------------------------------- + +.. index:: + pair: annotated; assignment + single: statement; assignment, annotated + +Annotation assignment is the combination, in a single statement, +of a variable or attribute annotation and an optional assignment statement: + +.. productionlist:: + annotated_assignment_stmt: `augtarget` ":" `expression` ["=" `expression`] + +The difference from normal :ref:`assignment` is that only single target and +only single right hand side value is allowed. + +For simple names as assignment targets, if in class or module scope, +the annotations are evaluated and stored in a special class or module +attribute :attr:`__annotations__` +that is a dictionary mapping from variable names to evaluated annotations. +This attribute is writable and is automatically created at the start +of class or module body execution, if annotations are found statically. + +For expressions as assignment targets, the annotations are evaluated if +in class or module scope, but not stored. + +If a name is annotated in a function scope, then this name is local for +that scope. Annotations are never evaluated and stored in function scopes. + +If the right hand side is present, an annotated +assignment performs the actual assignment before evaluating annotations +(where applicable). If the right hand side is not present for an expression +target, then the interpreter evaluates the target except for the last +:meth:`__setitem__` or :meth:`__setattr__` call. + +.. seealso:: + + :pep:`526` - Variable and attribute annotation syntax + :pep:`484` - Type hints + + .. _assert: The :keyword:`assert` statement diff --git a/Grammar/Grammar b/Grammar/Grammar index 9e4979e..1478d76 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -45,12 +45,13 @@ stmt: simple_stmt | compound_stmt simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt) -expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | +expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) +annassign: ':' test ['=' test] testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') -# For normal assignments, additional restrictions enforced by the interpreter +# For normal and annotated assignments, additional restrictions enforced by the interpreter del_stmt: 'del' exprlist pass_stmt: 'pass' flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 1ab376a..1423055 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -65,11 +65,12 @@ struct _mod { enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, Return_kind=4, Delete_kind=5, Assign_kind=6, - AugAssign_kind=7, For_kind=8, AsyncFor_kind=9, While_kind=10, - If_kind=11, With_kind=12, AsyncWith_kind=13, Raise_kind=14, - Try_kind=15, Assert_kind=16, Import_kind=17, - ImportFrom_kind=18, Global_kind=19, Nonlocal_kind=20, - Expr_kind=21, Pass_kind=22, Break_kind=23, Continue_kind=24}; + AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, + AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, + AsyncWith_kind=14, Raise_kind=15, Try_kind=16, + Assert_kind=17, Import_kind=18, ImportFrom_kind=19, + Global_kind=20, Nonlocal_kind=21, Expr_kind=22, Pass_kind=23, + Break_kind=24, Continue_kind=25}; struct _stmt { enum _stmt_kind kind; union { @@ -118,6 +119,13 @@ struct _stmt { struct { expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + } AnnAssign; + + struct { + expr_ty target; expr_ty iter; asdl_seq *body; asdl_seq *orelse; @@ -461,6 +469,9 @@ stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int #define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5) stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int col_offset, PyArena *arena); +#define AnnAssign(a0, a1, a2, a3, a4, a5, a6) _Py_AnnAssign(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int + simple, int lineno, int col_offset, PyArena *arena); #define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6) stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int lineno, int col_offset, PyArena *arena); diff --git a/Include/graminit.h b/Include/graminit.h index d030bc3..e9b4a93 100644 --- a/Include/graminit.h +++ b/Include/graminit.h @@ -17,71 +17,72 @@ #define simple_stmt 270 #define small_stmt 271 #define expr_stmt 272 -#define testlist_star_expr 273 -#define augassign 274 -#define del_stmt 275 -#define pass_stmt 276 -#define flow_stmt 277 -#define break_stmt 278 -#define continue_stmt 279 -#define return_stmt 280 -#define yield_stmt 281 -#define raise_stmt 282 -#define import_stmt 283 -#define import_name 284 -#define import_from 285 -#define import_as_name 286 -#define dotted_as_name 287 -#define import_as_names 288 -#define dotted_as_names 289 -#define dotted_name 290 -#define global_stmt 291 -#define nonlocal_stmt 292 -#define assert_stmt 293 -#define compound_stmt 294 -#define async_stmt 295 -#define if_stmt 296 -#define while_stmt 297 -#define for_stmt 298 -#define try_stmt 299 -#define with_stmt 300 -#define with_item 301 -#define except_clause 302 -#define suite 303 -#define test 304 -#define test_nocond 305 -#define lambdef 306 -#define lambdef_nocond 307 -#define or_test 308 -#define and_test 309 -#define not_test 310 -#define comparison 311 -#define comp_op 312 -#define star_expr 313 -#define expr 314 -#define xor_expr 315 -#define and_expr 316 -#define shift_expr 317 -#define arith_expr 318 -#define term 319 -#define factor 320 -#define power 321 -#define atom_expr 322 -#define atom 323 -#define testlist_comp 324 -#define trailer 325 -#define subscriptlist 326 -#define subscript 327 -#define sliceop 328 -#define exprlist 329 -#define testlist 330 -#define dictorsetmaker 331 -#define classdef 332 -#define arglist 333 -#define argument 334 -#define comp_iter 335 -#define comp_for 336 -#define comp_if 337 -#define encoding_decl 338 -#define yield_expr 339 -#define yield_arg 340 +#define annassign 273 +#define testlist_star_expr 274 +#define augassign 275 +#define del_stmt 276 +#define pass_stmt 277 +#define flow_stmt 278 +#define break_stmt 279 +#define continue_stmt 280 +#define return_stmt 281 +#define yield_stmt 282 +#define raise_stmt 283 +#define import_stmt 284 +#define import_name 285 +#define import_from 286 +#define import_as_name 287 +#define dotted_as_name 288 +#define import_as_names 289 +#define dotted_as_names 290 +#define dotted_name 291 +#define global_stmt 292 +#define nonlocal_stmt 293 +#define assert_stmt 294 +#define compound_stmt 295 +#define async_stmt 296 +#define if_stmt 297 +#define while_stmt 298 +#define for_stmt 299 +#define try_stmt 300 +#define with_stmt 301 +#define with_item 302 +#define except_clause 303 +#define suite 304 +#define test 305 +#define test_nocond 306 +#define lambdef 307 +#define lambdef_nocond 308 +#define or_test 309 +#define and_test 310 +#define not_test 311 +#define comparison 312 +#define comp_op 313 +#define star_expr 314 +#define expr 315 +#define xor_expr 316 +#define and_expr 317 +#define shift_expr 318 +#define arith_expr 319 +#define term 320 +#define factor 321 +#define power 322 +#define atom_expr 323 +#define atom 324 +#define testlist_comp 325 +#define trailer 326 +#define subscriptlist 327 +#define subscript 328 +#define sliceop 329 +#define exprlist 330 +#define testlist 331 +#define dictorsetmaker 332 +#define classdef 333 +#define arglist 334 +#define argument 335 +#define comp_iter 336 +#define comp_for 337 +#define comp_if 338 +#define encoding_decl 339 +#define yield_expr 340 +#define yield_arg 341 diff --git a/Include/opcode.h b/Include/opcode.h index 836c604..e2dd301 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -60,6 +60,7 @@ extern "C" { #define WITH_CLEANUP_FINISH 82 #define RETURN_VALUE 83 #define IMPORT_STAR 84 +#define SETUP_ANNOTATIONS 85 #define YIELD_VALUE 86 #define POP_BLOCK 87 #define END_FINALLY 88 @@ -98,6 +99,7 @@ extern "C" { #define LOAD_FAST 124 #define STORE_FAST 125 #define DELETE_FAST 126 +#define STORE_ANNOTATION 127 #define RAISE_VARARGS 130 #define CALL_FUNCTION 131 #define MAKE_FUNCTION 132 diff --git a/Include/symtable.h b/Include/symtable.h index 1409cd9..b0259d6 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -91,6 +91,7 @@ PyAPI_FUNC(void) PySymtable_Free(struct symtable *); #define DEF_FREE 2<<4 /* name used but not defined in nested block */ #define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ #define DEF_IMPORT 2<<6 /* assignment occurred via import */ +#define DEF_ANNOT 2<<7 /* this name is annotated */ #define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 828246c..ffb9325 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -234,6 +234,8 @@ _code_type = type(_write_atomic.__code__) # Python 3.6a1 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE # #27095) # Python 3.6b1 3373 (add BUILD_STRING opcode #27078) +# Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes +# #27985) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually @@ -242,7 +244,7 @@ _code_type = type(_write_atomic.__code__) # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3373).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3375).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt index c954669..abe1268 100644 --- a/Lib/lib2to3/Grammar.txt +++ b/Lib/lib2to3/Grammar.txt @@ -54,12 +54,13 @@ stmt: simple_stmt | compound_stmt simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt) -expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | +expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) +annassign: ':' test ['=' test] testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') -# For normal assignments, additional restrictions enforced by the interpreter +# For normal and annotated assignments, additional restrictions enforced by the interpreter print_stmt: 'print' ( [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] ) del_stmt: 'del' exprlist diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py index 9adb031..b378163 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/lib2to3/tests/test_parser.py @@ -237,6 +237,36 @@ class TestFunctionAnnotations(GrammarTest): self.validate(s) +# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.test_var_annot +class TestFunctionAnnotations(GrammarTest): + def test_1(self): + self.validate("var1: int = 5") + + def test_2(self): + self.validate("var2: [int, str]") + + def test_3(self): + self.validate("def f():\n" + " st: str = 'Hello'\n" + " a.b: int = (1, 2)\n" + " return st\n") + + def test_4(self): + self.validate("def fbad():\n" + " x: int\n" + " print(x)\n") + + def test_5(self): + self.validate("class C:\n" + " x: int\n" + " s: str = 'attr'\n" + " z = 2\n" + " def __init__(self, x):\n" + " self.x: int = x\n") + + def test_6(self): + self.validate("lst: List[int] = []") + class TestExcept(GrammarTest): def test_new(self): s = """ diff --git a/Lib/opcode.py b/Lib/opcode.py index d9202e8..31d1534 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -119,7 +119,7 @@ def_op('WITH_CLEANUP_FINISH', 82) def_op('RETURN_VALUE', 83) def_op('IMPORT_STAR', 84) - +def_op('SETUP_ANNOTATIONS', 85) def_op('YIELD_VALUE', 86) def_op('POP_BLOCK', 87) def_op('END_FINALLY', 88) @@ -169,6 +169,7 @@ def_op('STORE_FAST', 125) # Local variable number haslocal.append(125) def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) +name_op('STORE_ANNOTATION', 127) # Index in name list def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8) diff --git a/Lib/symbol.py b/Lib/symbol.py index 7541497..d9f01e0 100755 --- a/Lib/symbol.py +++ b/Lib/symbol.py @@ -27,74 +27,75 @@ stmt = 269 simple_stmt = 270 small_stmt = 271 expr_stmt = 272 -testlist_star_expr = 273 -augassign = 274 -del_stmt = 275 -pass_stmt = 276 -flow_stmt = 277 -break_stmt = 278 -continue_stmt = 279 -return_stmt = 280 -yield_stmt = 281 -raise_stmt = 282 -import_stmt = 283 -import_name = 284 -import_from = 285 -import_as_name = 286 -dotted_as_name = 287 -import_as_names = 288 -dotted_as_names = 289 -dotted_name = 290 -global_stmt = 291 -nonlocal_stmt = 292 -assert_stmt = 293 -compound_stmt = 294 -async_stmt = 295 -if_stmt = 296 -while_stmt = 297 -for_stmt = 298 -try_stmt = 299 -with_stmt = 300 -with_item = 301 -except_clause = 302 -suite = 303 -test = 304 -test_nocond = 305 -lambdef = 306 -lambdef_nocond = 307 -or_test = 308 -and_test = 309 -not_test = 310 -comparison = 311 -comp_op = 312 -star_expr = 313 -expr = 314 -xor_expr = 315 -and_expr = 316 -shift_expr = 317 -arith_expr = 318 -term = 319 -factor = 320 -power = 321 -atom_expr = 322 -atom = 323 -testlist_comp = 324 -trailer = 325 -subscriptlist = 326 -subscript = 327 -sliceop = 328 -exprlist = 329 -testlist = 330 -dictorsetmaker = 331 -classdef = 332 -arglist = 333 -argument = 334 -comp_iter = 335 -comp_for = 336 -comp_if = 337 -encoding_decl = 338 -yield_expr = 339 -yield_arg = 340 +annassign = 273 +testlist_star_expr = 274 +augassign = 275 +del_stmt = 276 +pass_stmt = 277 +flow_stmt = 278 +break_stmt = 279 +continue_stmt = 280 +return_stmt = 281 +yield_stmt = 282 +raise_stmt = 283 +import_stmt = 284 +import_name = 285 +import_from = 286 +import_as_name = 287 +dotted_as_name = 288 +import_as_names = 289 +dotted_as_names = 290 +dotted_name = 291 +global_stmt = 292 +nonlocal_stmt = 293 +assert_stmt = 294 +compound_stmt = 295 +async_stmt = 296 +if_stmt = 297 +while_stmt = 298 +for_stmt = 299 +try_stmt = 300 +with_stmt = 301 +with_item = 302 +except_clause = 303 +suite = 304 +test = 305 +test_nocond = 306 +lambdef = 307 +lambdef_nocond = 308 +or_test = 309 +and_test = 310 +not_test = 311 +comparison = 312 +comp_op = 313 +star_expr = 314 +expr = 315 +xor_expr = 316 +and_expr = 317 +shift_expr = 318 +arith_expr = 319 +term = 320 +factor = 321 +power = 322 +atom_expr = 323 +atom = 324 +testlist_comp = 325 +trailer = 326 +subscriptlist = 327 +subscript = 328 +sliceop = 329 +exprlist = 330 +testlist = 331 +dictorsetmaker = 332 +classdef = 333 +arglist = 334 +argument = 335 +comp_iter = 336 +comp_for = 337 +comp_if = 338 +encoding_decl = 339 +yield_expr = 340 +yield_arg = 341 #--end constants-- sym_name = {} diff --git a/Lib/symtable.py b/Lib/symtable.py index 84fec4a..b0e5260 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -2,7 +2,7 @@ import _symtable from _symtable import (USE, DEF_GLOBAL, DEF_LOCAL, DEF_PARAM, - DEF_IMPORT, DEF_BOUND, SCOPE_OFF, SCOPE_MASK, FREE, + DEF_IMPORT, DEF_BOUND, DEF_ANNOT, SCOPE_OFF, SCOPE_MASK, FREE, LOCAL, GLOBAL_IMPLICIT, GLOBAL_EXPLICIT, CELL) import weakref @@ -190,6 +190,9 @@ class Symbol(object): def is_local(self): return bool(self.__flags & DEF_BOUND) + def is_annotated(self): + return bool(self.__flags & DEF_ANNOT) + def is_free(self): return bool(self.__scope == FREE) diff --git a/Lib/test/ann_module.py b/Lib/test/ann_module.py new file mode 100644 index 0000000..9e6b87d --- /dev/null +++ b/Lib/test/ann_module.py @@ -0,0 +1,53 @@ + + +""" +The module for testing variable annotations. +Empty lines above are for good reason (testing for correct line numbers) +""" + +from typing import Optional + +__annotations__[1] = 2 + +class C: + + x = 5; y: Optional['C'] = None + +from typing import Tuple +x: int = 5; y: str = x; f: Tuple[int, int] + +class M(type): + + __annotations__['123'] = 123 + o: type = object + +(pars): bool = True + +class D(C): + j: str = 'hi'; k: str= 'bye' + +from types import new_class +h_class = new_class('H', (C,)) +j_class = new_class('J') + +class F(): + z: int = 5 + def __init__(self, x): + pass + +class Y(F): + def __init__(self): + super(F, self).__init__(123) + +class Meta(type): + def __new__(meta, name, bases, namespace): + return super().__new__(meta, name, bases, namespace) + +class S(metaclass = Meta): + x: str = 'something' + y: str = 'something else' + +def foo(x: int = 10): + def bar(y: List[str]): + x: str = 'yes' + bar() diff --git a/Lib/test/ann_module2.py b/Lib/test/ann_module2.py new file mode 100644 index 0000000..76cf5b3 --- /dev/null +++ b/Lib/test/ann_module2.py @@ -0,0 +1,36 @@ +""" +Some correct syntax for variable annotation here. +More examples are in test_grammar and test_parser. +""" + +from typing import no_type_check, ClassVar + +i: int = 1 +j: int +x: float = i/10 + +def f(): + class C: ... + return C() + +f().new_attr: object = object() + +class C: + def __init__(self, x: int) -> None: + self.x = x + +c = C(5) +c.new_attr: int = 10 + +__annotations__ = {} + + +@no_type_check +class NTC: + def meth(self, param: complex) -> None: + ... + +class CV: + var: ClassVar['CV'] + +CV.var = CV() diff --git a/Lib/test/ann_module3.py b/Lib/test/ann_module3.py new file mode 100644 index 0000000..eccd7be --- /dev/null +++ b/Lib/test/ann_module3.py @@ -0,0 +1,18 @@ +""" +Correct syntax for variable annotation that should fail at runtime +in a certain manner. More examples are in test_grammar and test_parser. +""" + +def f_bad_ann(): + __annotations__[1] = 2 + +class C_OK: + def __init__(self, x: int) -> None: + self.x: no_such_name = x # This one is OK as proposed by Guido + +class D_bad_ann: + def __init__(self, x: int) -> None: + sfel.y: int = 0 + +def g_bad_ann(): + no_such_name.attr: int = 0 diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index cda1c9e..9c1fff5 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -12,7 +12,7 @@ class A: pass class B(object): - NO_MEANING = "eggs" + NO_MEANING: str = "eggs" pass class C(object): diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index e94d984..ae9114e 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -38,6 +38,8 @@ class AllTest(unittest.TestCase): modname, e.__class__.__name__, e)) if "__builtins__" in names: del names["__builtins__"] + if '__annotations__' in names: + del names['__annotations__'] keys = set(names) all_list = sys.modules[modname].__all__ all_set = set(all_list) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 09e68ce..6081073 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -207,6 +207,38 @@ dis_simple_stmt_str = """\ 10 RETURN_VALUE """ +annot_stmt_str = """\ + +x: int = 1 +y: fun(1) +lst[fun(0)]: int = 1 +""" +# leading newline is for a reason (tests lineno) + +dis_annot_stmt_str = """\ + 2 0 SETUP_ANNOTATIONS + 2 LOAD_CONST 0 (1) + 4 STORE_NAME 0 (x) + 6 LOAD_NAME 1 (int) + 8 STORE_ANNOTATION 0 (x) + + 3 10 LOAD_NAME 2 (fun) + 12 LOAD_CONST 0 (1) + 14 CALL_FUNCTION 1 (1 positional, 0 keyword pair) + 16 STORE_ANNOTATION 3 (y) + + 4 18 LOAD_CONST 0 (1) + 20 LOAD_NAME 4 (lst) + 22 LOAD_NAME 2 (fun) + 24 LOAD_CONST 1 (0) + 26 CALL_FUNCTION 1 (1 positional, 0 keyword pair) + 28 STORE_SUBSCR + 30 LOAD_NAME 1 (int) + 32 POP_TOP + 34 LOAD_CONST 2 (None) + 36 RETURN_VALUE +""" + compound_stmt_str = """\ x = 0 while 1: @@ -345,6 +377,7 @@ class DisTests(unittest.TestCase): def test_disassemble_str(self): self.do_disassembly_test(expr_str, dis_expr_str) self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str) + self.do_disassembly_test(annot_stmt_str, dis_annot_stmt_str) self.do_disassembly_test(compound_stmt_str, dis_compound_stmt_str) def test_disassemble_bytes(self): diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index bfe5225..109013f 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -8,6 +8,14 @@ import sys # testing import * from sys import * +# different import patterns to check that __annotations__ does not interfere +# with import machinery +import test.ann_module as ann_module +import typing +from collections import ChainMap +from test import ann_module2 +import test + class TokenTests(unittest.TestCase): @@ -139,6 +147,19 @@ the \'lazy\' dog.\n\ compile(s, "<test>", "exec") self.assertIn("unexpected EOF", str(cm.exception)) +var_annot_global: int # a global annotated is necessary for test_var_annot + +# custom namespace for testing __annotations__ + +class CNS: + def __init__(self): + self._dct = {} + def __setitem__(self, item, value): + self._dct[item.lower()] = value + def __getitem__(self, item): + return self._dct[item] + + class GrammarTests(unittest.TestCase): # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE @@ -154,6 +175,163 @@ class GrammarTests(unittest.TestCase): # testlist ENDMARKER x = eval('1, 0 or 1') + def test_var_annot_basics(self): + # all these should be allowed + var1: int = 5 + var2: [int, str] + my_lst = [42] + def one(): + return 1 + int.new_attr: int + [list][0]: type + my_lst[one()-1]: int = 5 + self.assertEqual(my_lst, [5]) + + def test_var_annot_syntax_errors(self): + # parser pass + check_syntax_error(self, "def f: int") + check_syntax_error(self, "x: int: str") + check_syntax_error(self, "def f():\n" + " nonlocal x: int\n") + # AST pass + check_syntax_error(self, "[x, 0]: int\n") + check_syntax_error(self, "f(): int\n") + check_syntax_error(self, "(x,): int") + check_syntax_error(self, "def f():\n" + " (x, y): int = (1, 2)\n") + # symtable pass + check_syntax_error(self, "def f():\n" + " x: int\n" + " global x\n") + check_syntax_error(self, "def f():\n" + " global x\n" + " x: int\n") + + def test_var_annot_basic_semantics(self): + # execution order + with self.assertRaises(ZeroDivisionError): + no_name[does_not_exist]: no_name_again = 1/0 + with self.assertRaises(NameError): + no_name[does_not_exist]: 1/0 = 0 + global var_annot_global + + # function semantics + def f(): + st: str = "Hello" + a.b: int = (1, 2) + return st + self.assertEqual(f.__annotations__, {}) + def f_OK(): + x: 1/0 + f_OK() + def fbad(): + x: int + print(x) + with self.assertRaises(UnboundLocalError): + fbad() + def f2bad(): + (no_such_global): int + print(no_such_global) + try: + f2bad() + except Exception as e: + self.assertIs(type(e), NameError) + + # class semantics + class C: + x: int + s: str = "attr" + z = 2 + def __init__(self, x): + self.x: int = x + self.assertEqual(C.__annotations__, {'x': int, 's': str}) + with self.assertRaises(NameError): + class CBad: + no_such_name_defined.attr: int = 0 + with self.assertRaises(NameError): + class Cbad2(C): + x: int + x.y: list = [] + + def test_var_annot_metaclass_semantics(self): + class CMeta(type): + @classmethod + def __prepare__(metacls, name, bases, **kwds): + return {'__annotations__': CNS()} + class CC(metaclass=CMeta): + XX: 'ANNOT' + self.assertEqual(CC.__annotations__['xx'], 'ANNOT') + + def test_var_annot_module_semantics(self): + with self.assertRaises(AttributeError): + print(test.__annotations__) + self.assertEqual(ann_module.__annotations__, + {1: 2, 'x': int, 'y': str, 'f': typing.Tuple[int, int]}) + self.assertEqual(ann_module.M.__annotations__, + {'123': 123, 'o': type}) + self.assertEqual(ann_module2.__annotations__, {}) + self.assertEqual(typing.get_type_hints(ann_module2.CV, + ann_module2.__dict__), + ChainMap({'var': typing.ClassVar[ann_module2.CV]}, {})) + + def test_var_annot_in_module(self): + # check that functions fail the same way when executed + # outside of module where they were defined + from test.ann_module3 import f_bad_ann, g_bad_ann, D_bad_ann + with self.assertRaises(NameError): + f_bad_ann() + with self.assertRaises(NameError): + g_bad_ann() + with self.assertRaises(NameError): + D_bad_ann(5) + + def test_var_annot_simple_exec(self): + gns = {}; lns= {} + exec("'docstring'\n" + "__annotations__[1] = 2\n" + "x: int = 5\n", gns, lns) + self.assertEqual(lns["__annotations__"], {1: 2, 'x': int}) + with self.assertRaises(KeyError): + gns['__annotations__'] + + def test_var_annot_custom_maps(self): + # tests with custom locals() and __annotations__ + ns = {'__annotations__': CNS()} + exec('X: int; Z: str = "Z"; (w): complex = 1j', ns) + self.assertEqual(ns['__annotations__']['x'], int) + self.assertEqual(ns['__annotations__']['z'], str) + with self.assertRaises(KeyError): + ns['__annotations__']['w'] + nonloc_ns = {} + class CNS2: + def __init__(self): + self._dct = {} + def __setitem__(self, item, value): + nonlocal nonloc_ns + self._dct[item] = value + nonloc_ns[item] = value + def __getitem__(self, item): + return self._dct[item] + exec('x: int = 1', {}, CNS2()) + self.assertEqual(nonloc_ns['__annotations__']['x'], int) + + def test_var_annot_refleak(self): + # complex case: custom locals plus custom __annotations__ + # this was causing refleak + cns = CNS() + nonloc_ns = {'__annotations__': cns} + class CNS2: + def __init__(self): + self._dct = {'__annotations__': cns} + def __setitem__(self, item, value): + nonlocal nonloc_ns + self._dct[item] = value + nonloc_ns[item] = value + def __getitem__(self, item): + return self._dct[item] + exec('X: str', {}, CNS2()) + self.assertEqual(nonloc_ns['__annotations__']['x'], str) + def test_funcdef(self): ### [decorators] 'def' NAME parameters ['->' test] ':' suite ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py index 6ef93d9..6806c61 100644 --- a/Lib/test/test_opcodes.py +++ b/Lib/test/test_opcodes.py @@ -1,6 +1,7 @@ # Python test set -- part 2, opcodes import unittest +from test import ann_module class OpcodeTest(unittest.TestCase): @@ -20,6 +21,32 @@ class OpcodeTest(unittest.TestCase): if n != 90: self.fail('try inside for') + def test_setup_annotations_line(self): + # check that SETUP_ANNOTATIONS does not create spurious line numbers + try: + with open(ann_module.__file__) as f: + txt = f.read() + co = compile(txt, ann_module.__file__, 'exec') + self.assertEqual(co.co_firstlineno, 6) + except OSError: + pass + + def test_no_annotations_if_not_needed(self): + class C: pass + with self.assertRaises(AttributeError): + C.__annotations__ + + def test_use_existing_annotations(self): + ns = {'__annotations__': {1: 2}} + exec('x: int', ns) + self.assertEqual(ns['__annotations__'], {'x': int, 1: 2}) + + def test_do_not_recreate_annotations(self): + class C: + del __annotations__ + with self.assertRaises(NameError): + x: int + def test_raise_class_exceptions(self): class AClass(Exception): pass diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index e2a42f9..d6e6f71 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -138,6 +138,45 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): self.check_suite("a = b") self.check_suite("a = b = c = d = e") + def test_var_annot(self): + self.check_suite("x: int = 5") + self.check_suite("y: List[T] = []; z: [list] = fun()") + self.check_suite("x: tuple = (1, 2)") + self.check_suite("d[f()]: int = 42") + self.check_suite("f(d[x]): str = 'abc'") + self.check_suite("x.y.z.w: complex = 42j") + self.check_suite("x: int") + self.check_suite("def f():\n" + " x: str\n" + " y: int = 5\n") + self.check_suite("class C:\n" + " x: str\n" + " y: int = 5\n") + self.check_suite("class C:\n" + " def __init__(self, x: int) -> None:\n" + " self.x: int = x\n") + # double check for nonsense + with self.assertRaises(SyntaxError): + exec("2+2: int", {}, {}) + with self.assertRaises(SyntaxError): + exec("[]: int = 5", {}, {}) + with self.assertRaises(SyntaxError): + exec("x, *y, z: int = range(5)", {}, {}) + with self.assertRaises(SyntaxError): + exec("t: tuple = 1, 2", {}, {}) + with self.assertRaises(SyntaxError): + exec("u = v: int", {}, {}) + with self.assertRaises(SyntaxError): + exec("False: int", {}, {}) + with self.assertRaises(SyntaxError): + exec("x.False: int", {}, {}) + with self.assertRaises(SyntaxError): + exec("x.y,: int", {}, {}) + with self.assertRaises(SyntaxError): + exec("[0]: int", {}, {}) + with self.assertRaises(SyntaxError): + exec("f(): int", {}, {}) + def test_simple_augmented_assignments(self): self.check_suite("a += b") self.check_suite("a -= b") diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 17a82c2..5174d56 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -83,6 +83,8 @@ CLASSES | Data and other attributes defined here: |\x20\x20 | NO_MEANING = 'eggs' + |\x20\x20 + | __annotations__ = {'NO_MEANING': <class 'str'>} \x20\x20\x20\x20 class C(builtins.object) | Methods defined here: @@ -195,6 +197,8 @@ Data descriptors defined here:<br> Data and other attributes defined here:<br> <dl><dt><strong>NO_MEANING</strong> = 'eggs'</dl> +<dl><dt><strong>__annotations__</strong> = {'NO_MEANING': <class 'str'>}</dl> + </td></tr></table> <p> <table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#ffc8d8"> diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index bf99505..3047165 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -133,6 +133,17 @@ class SymtableTest(unittest.TestCase): self.assertTrue(self.Mine.lookup("a_method").is_assigned()) self.assertFalse(self.internal.lookup("x").is_assigned()) + def test_annotated(self): + st1 = symtable.symtable('def f():\n x: int\n', 'test', 'exec') + st2 = st1.get_children()[0] + self.assertTrue(st2.lookup('x').is_local()) + self.assertTrue(st2.lookup('x').is_annotated()) + self.assertFalse(st2.lookup('x').is_global()) + st3 = symtable.symtable('def f():\n x = 1\n', 'test', 'exec') + st4 = st3.get_children()[0] + self.assertTrue(st4.lookup('x').is_local()) + self.assertFalse(st4.lookup('x').is_annotated()) + def test_imported(self): self.assertTrue(self.top.lookup("sys").is_imported()) diff --git a/Lib/test/test_tools/test_com2ann.py b/Lib/test/test_tools/test_com2ann.py new file mode 100644 index 0000000..2731f82 --- /dev/null +++ b/Lib/test/test_tools/test_com2ann.py @@ -0,0 +1,260 @@ +"""Tests for the com2ann.py script in the Tools/parser directory.""" + +import unittest +import test.support +import os +import re + +from test.test_tools import basepath, toolsdir, skip_if_missing + +skip_if_missing() + +parser_path = os.path.join(toolsdir, "parser") + +with test.support.DirsOnSysPath(parser_path): + from com2ann import * + +class BaseTestCase(unittest.TestCase): + + def check(self, code, expected, n=False, e=False): + self.assertEqual(com2ann(code, + drop_None=n, drop_Ellipsis=e, silent=True), + expected) + +class SimpleTestCase(BaseTestCase): + # Tests for basic conversions + + def test_basics(self): + self.check("z = 5", "z = 5") + self.check("z: int = 5", "z: int = 5") + self.check("z = 5 # type: int", "z: int = 5") + self.check("z = 5 # type: int # comment", + "z: int = 5 # comment") + + def test_type_ignore(self): + self.check("foobar = foobaz() #type: ignore", + "foobar = foobaz() #type: ignore") + self.check("a = 42 #type: ignore #comment", + "a = 42 #type: ignore #comment") + + def test_complete_tuple(self): + self.check("t = 1, 2, 3 # type: Tuple[int, ...]", + "t: Tuple[int, ...] = (1, 2, 3)") + self.check("t = 1, # type: Tuple[int]", + "t: Tuple[int] = (1,)") + self.check("t = (1, 2, 3) # type: Tuple[int, ...]", + "t: Tuple[int, ...] = (1, 2, 3)") + + def test_drop_None(self): + self.check("x = None # type: int", + "x: int", True) + self.check("x = None # type: int # another", + "x: int # another", True) + self.check("x = None # type: int # None", + "x: int # None", True) + + def test_drop_Ellipsis(self): + self.check("x = ... # type: int", + "x: int", False, True) + self.check("x = ... # type: int # another", + "x: int # another", False, True) + self.check("x = ... # type: int # ...", + "x: int # ...", False, True) + + def test_newline(self): + self.check("z = 5 # type: int\r\n", "z: int = 5\r\n") + self.check("z = 5 # type: int # comment\x85", + "z: int = 5 # comment\x85") + + def test_wrong(self): + self.check("#type : str", "#type : str") + self.check("x==y #type: bool", "x==y #type: bool") + + def test_pattern(self): + for line in ["#type: int", " # type: str[:] # com"]: + self.assertTrue(re.search(TYPE_COM, line)) + for line in ["", "#", "# comment", "#type", "type int:"]: + self.assertFalse(re.search(TYPE_COM, line)) + +class BigTestCase(BaseTestCase): + # Tests for really crazy formatting, to be sure + # that script works reasonably in extreme situations + + def test_crazy(self): + self.maxDiff = None + self.check(crazy_code, big_result, False, False) + self.check(crazy_code, big_result_ne, True, True) + +crazy_code = """\ +# -*- coding: utf-8 -*- # this should not be spoiled +''' +Docstring here +''' + +import testmod +x = 5 #type : int # this one is OK +ttt \\ + = \\ + 1.0, \\ + 2.0, \\ + 3.0, #type: Tuple[float, float, float] +with foo(x==1) as f: #type: str + print(f) + +for i, j in my_inter(x=1): # type: ignore + i + j # type: int # what about this + +x = y = z = 1 # type: int +x, y, z = [], [], [] # type: (List[int], List[int], List[str]) +class C: + + + l[f(x + =1)] = [ + + 1, + 2, + ] # type: List[int] + + + (C.x[1]) = \\ + 42 == 5# type: bool +lst[...] = \\ + ((\\ +...)) # type: int # comment .. + +y = ... # type: int # comment ... +z = ... +#type: int + + +#DONE placement of annotation after target rather than before = + +TD.x[1] \\ + = 0 == 5# type: bool + +TD.y[1] =5 == 5# type: bool # one more here +F[G(x == y, + +# hm... + + z)]\\ + = None # type: OMG[int] # comment: None +x = None#type:int #comment : None""" + +big_result = """\ +# -*- coding: utf-8 -*- # this should not be spoiled +''' +Docstring here +''' + +import testmod +x: int = 5 # this one is OK +ttt: Tuple[float, float, float] \\ + = \\ + (1.0, \\ + 2.0, \\ + 3.0,) +with foo(x==1) as f: #type: str + print(f) + +for i, j in my_inter(x=1): # type: ignore + i + j # type: int # what about this + +x = y = z = 1 # type: int +x, y, z = [], [], [] # type: (List[int], List[int], List[str]) +class C: + + + l[f(x + =1)]: List[int] = [ + + 1, + 2, + ] + + + (C.x[1]): bool = \\ + 42 == 5 +lst[...]: int = \\ + ((\\ +...)) # comment .. + +y: int = ... # comment ... +z = ... +#type: int + + +#DONE placement of annotation after target rather than before = + +TD.x[1]: bool \\ + = 0 == 5 + +TD.y[1]: bool =5 == 5 # one more here +F[G(x == y, + +# hm... + + z)]: OMG[int]\\ + = None # comment: None +x: int = None #comment : None""" + +big_result_ne = """\ +# -*- coding: utf-8 -*- # this should not be spoiled +''' +Docstring here +''' + +import testmod +x: int = 5 # this one is OK +ttt: Tuple[float, float, float] \\ + = \\ + (1.0, \\ + 2.0, \\ + 3.0,) +with foo(x==1) as f: #type: str + print(f) + +for i, j in my_inter(x=1): # type: ignore + i + j # type: int # what about this + +x = y = z = 1 # type: int +x, y, z = [], [], [] # type: (List[int], List[int], List[str]) +class C: + + + l[f(x + =1)]: List[int] = [ + + 1, + 2, + ] + + + (C.x[1]): bool = \\ + 42 == 5 +lst[...]: int \\ + \\ + # comment .. + +y: int # comment ... +z = ... +#type: int + + +#DONE placement of annotation after target rather than before = + +TD.x[1]: bool \\ + = 0 == 5 + +TD.y[1]: bool =5 == 5 # one more here +F[G(x == y, + +# hm... + + z)]: OMG[int]\\ + # comment: None +x: int #comment : None""" + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 72afe67..e3904b1 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4,14 +4,16 @@ import pickle import re import sys from unittest import TestCase, main, skipUnless, SkipTest +from collections import ChainMap +from test import ann_module, ann_module2, ann_module3 from typing import Any from typing import TypeVar, AnyStr from typing import T, KT, VT # Not in __all__. from typing import Union, Optional -from typing import Tuple +from typing import Tuple, List from typing import Callable -from typing import Generic +from typing import Generic, ClassVar from typing import cast from typing import get_type_hints from typing import no_type_check, no_type_check_decorator @@ -827,6 +829,43 @@ class GenericTests(BaseTestCase): with self.assertRaises(Exception): D[T] +class ClassVarTests(BaseTestCase): + + def test_basics(self): + with self.assertRaises(TypeError): + ClassVar[1] + with self.assertRaises(TypeError): + ClassVar[int, str] + with self.assertRaises(TypeError): + ClassVar[int][str] + + def test_repr(self): + self.assertEqual(repr(ClassVar), 'typing.ClassVar') + cv = ClassVar[int] + self.assertEqual(repr(cv), 'typing.ClassVar[int]') + cv = ClassVar[Employee] + self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) + + def test_cannot_subclass(self): + with self.assertRaises(TypeError): + class C(type(ClassVar)): + pass + with self.assertRaises(TypeError): + class C(type(ClassVar[int])): + pass + + def test_cannot_init(self): + with self.assertRaises(TypeError): + type(ClassVar)() + with self.assertRaises(TypeError): + type(ClassVar[Optional[int]])() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, ClassVar[int]) + with self.assertRaises(TypeError): + issubclass(int, ClassVar) + class VarianceTests(BaseTestCase): @@ -930,6 +969,46 @@ class ForwardRefTests(BaseTestCase): right_hints = get_type_hints(t.add_right, globals(), locals()) self.assertEqual(right_hints['node'], Optional[Node[T]]) + def test_get_type_hints(self): + gth = get_type_hints + self.assertEqual(gth(ann_module), {'x': int, 'y': str}) + self.assertEqual(gth(ann_module.C, ann_module.__dict__), + ChainMap({'y': Optional[ann_module.C]}, {})) + self.assertEqual(gth(ann_module2), {}) + self.assertEqual(gth(ann_module3), {}) + self.assertEqual(repr(gth(ann_module.j_class)), 'ChainMap({}, {})') + self.assertEqual(gth(ann_module.M), ChainMap({'123': 123, 'o': type}, + {}, {})) + self.assertEqual(gth(ann_module.D), + ChainMap({'j': str, 'k': str, + 'y': Optional[ann_module.C]}, {})) + self.assertEqual(gth(ann_module.Y), ChainMap({'z': int}, {})) + self.assertEqual(gth(ann_module.h_class), + ChainMap({}, {'y': Optional[ann_module.C]}, {})) + self.assertEqual(gth(ann_module.S), ChainMap({'x': str, 'y': str}, + {})) + self.assertEqual(gth(ann_module.foo), {'x': int}) + + def testf(x, y): ... + testf.__annotations__['x'] = 'int' + self.assertEqual(gth(testf), {'x': int}) + self.assertEqual(gth(ann_module2.NTC.meth), {}) + + # interactions with ClassVar + class B: + x: ClassVar[Optional['B']] = None + y: int + class C(B): + z: ClassVar['C'] = B() + class G(Generic[T]): + lst: ClassVar[List[T]] = [] + self.assertEqual(gth(B, locals()), + ChainMap({'y': int, 'x': ClassVar[Optional[B]]}, {})) + self.assertEqual(gth(C, locals()), + ChainMap({'z': ClassVar[C]}, + {'y': int, 'x': ClassVar[Optional[B]]}, {})) + self.assertEqual(gth(G), ChainMap({'lst': ClassVar[List[T]]},{},{})) + def test_forwardref_instance_type_error(self): fr = typing._ForwardRef('int') with self.assertRaises(TypeError): diff --git a/Lib/typing.py b/Lib/typing.py index 5573a1f..6ce74fc 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -6,6 +6,7 @@ import functools import re as stdlib_re # Avoid confusion with the re we export. import sys import types + try: import collections.abc as collections_abc except ImportError: @@ -17,6 +18,7 @@ __all__ = [ # Super-special typing primitives. 'Any', 'Callable', + 'ClassVar', 'Generic', 'Optional', 'Tuple', @@ -270,7 +272,7 @@ class _TypeAlias: def _get_type_vars(types, tvars): for t in types: - if isinstance(t, TypingMeta): + if isinstance(t, TypingMeta) or isinstance(t, _ClassVar): t._get_type_vars(tvars) @@ -281,7 +283,7 @@ def _type_vars(types): def _eval_type(t, globalns, localns): - if isinstance(t, TypingMeta): + if isinstance(t, TypingMeta) or isinstance(t, _ClassVar): return t._eval_type(globalns, localns) else: return t @@ -1114,6 +1116,67 @@ class Generic(metaclass=GenericMeta): return obj +class _ClassVar(metaclass=TypingMeta, _root=True): + """Special type construct to mark class variables. + + An annotation wrapped in ClassVar indicates that a given + attribute is intended to be used as a class variable and + should not be set on instances of that class. Usage:: + + class Starship: + stats: ClassVar[Dict[str, int]] = {} # class variable + damage: int = 10 # instance variable + + ClassVar accepts only types and cannot be further subscribed. + + Note that ClassVar is not a class itself, and should not + be used with isinstance() or issubclass(). + """ + + def __init__(self, tp=None, _root=False): + cls = type(self) + if _root: + self.__type__ = tp + else: + raise TypeError('Cannot initialize {}'.format(cls.__name__[1:])) + + def __getitem__(self, item): + cls = type(self) + if self.__type__ is None: + return cls(_type_check(item, + '{} accepts only types.'.format(cls.__name__[1:])), + _root=True) + raise TypeError('{} cannot be further subscripted' + .format(cls.__name__[1:])) + + def _eval_type(self, globalns, localns): + return type(self)(_eval_type(self.__type__, globalns, localns), + _root=True) + + def _get_type_vars(self, tvars): + if self.__type__: + _get_type_vars(self.__type__, tvars) + + def __repr__(self): + cls = type(self) + if not self.__type__: + return '{}.{}'.format(cls.__module__, cls.__name__[1:]) + return '{}.{}[{}]'.format(cls.__module__, cls.__name__[1:], + _type_repr(self.__type__)) + + def __hash__(self): + return hash((type(self).__name__, self.__type__)) + + def __eq__(self, other): + if not isinstance(other, _ClassVar): + return NotImplemented + if self.__type__ is not None: + return self.__type__ == other.__type__ + return self is other + +ClassVar = _ClassVar(_root=True) + + def cast(typ, val): """Cast a value to a type. @@ -1142,12 +1205,20 @@ def _get_defaults(func): def get_type_hints(obj, globalns=None, localns=None): - """Return type hints for a function or method object. + """Return type hints for an object. This is often the same as obj.__annotations__, but it handles forward references encoded as string literals, and if necessary adds Optional[t] if a default value equal to None is set. + The argument may be a module, class, method, or function. The annotations + are returned as a dictionary, or in the case of a class, a ChainMap of + dictionaries. + + TypeError is raised if the argument is not of a type that can contain + annotations, and an empty dictionary is returned if no annotations are + present. + BEWARE -- the behavior of globalns and localns is counterintuitive (unless you are familiar with how eval() and exec() work). The search order is locals first, then globals. @@ -1162,6 +1233,7 @@ def get_type_hints(obj, globalns=None, localns=None): - If two dict arguments are passed, they specify globals and locals, respectively. """ + if getattr(obj, '__no_type_check__', None): return {} if globalns is None: @@ -1170,16 +1242,62 @@ def get_type_hints(obj, globalns=None, localns=None): localns = globalns elif localns is None: localns = globalns - defaults = _get_defaults(obj) - hints = dict(obj.__annotations__) - for name, value in hints.items(): - if isinstance(value, str): - value = _ForwardRef(value) - value = _eval_type(value, globalns, localns) - if name in defaults and defaults[name] is None: - value = Optional[value] - hints[name] = value - return hints + + if (isinstance(obj, types.FunctionType) or + isinstance(obj, types.BuiltinFunctionType) or + isinstance(obj, types.MethodType)): + defaults = _get_defaults(obj) + hints = obj.__annotations__ + for name, value in hints.items(): + if value is None: + value = type(None) + if isinstance(value, str): + value = _ForwardRef(value) + value = _eval_type(value, globalns, localns) + if name in defaults and defaults[name] is None: + value = Optional[value] + hints[name] = value + return hints + + if isinstance(obj, types.ModuleType): + try: + hints = obj.__annotations__ + except AttributeError: + return {} + # we keep only those annotations that can be accessed on module + members = obj.__dict__ + hints = {name: value for name, value in hints.items() + if name in members} + for name, value in hints.items(): + if value is None: + value = type(None) + if isinstance(value, str): + value = _ForwardRef(value) + value = _eval_type(value, globalns, localns) + hints[name] = value + return hints + + if isinstance(object, type): + cmap = None + for base in reversed(obj.__mro__): + new_map = collections.ChainMap if cmap is None else cmap.new_child + try: + hints = base.__dict__['__annotations__'] + except KeyError: + cmap = new_map() + else: + for name, value in hints.items(): + if value is None: + value = type(None) + if isinstance(value, str): + value = _ForwardRef(value) + value = _eval_type(value, globalns, localns) + hints[name] = value + cmap = new_map(hints) + return cmap + + raise TypeError('{!r} is not a module, class, method, ' + 'or function.'.format(obj)) def no_type_check(arg): @@ -1300,6 +1418,8 @@ class _ProtocolMeta(GenericMeta): else: if (not attr.startswith('_abc_') and attr != '__abstractmethods__' and + attr != '__annotations__' and + attr != '__weakref__' and attr != '_is_protocol' and attr != '__dict__' and attr != '__args__' and @@ -468,6 +468,7 @@ Jason Fried Robin Friedrich Bradley Froehle Ivan Frohne +Ivan Levkivskyi Matthias Fuchs Jim Fulton Tadayoshi Funaba @@ -100,6 +100,9 @@ Core and Builtins In a brand new thread, raise a RuntimeError since there is no active exception to reraise. Patch written by Xiang Zhang. +- Issue #27985: Implement PEP 526 -- Syntax for Variable Annotations. + Patch by Ivan Levkivskyi. + Library ------- diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index f84cc78..34a6fc5 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -79,6 +79,7 @@ PyInit__symtable(void) PyModule_AddIntMacro(m, DEF_FREE_CLASS); PyModule_AddIntMacro(m, DEF_IMPORT); PyModule_AddIntMacro(m, DEF_BOUND); + PyModule_AddIntMacro(m, DEF_ANNOT); PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock); PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock); diff --git a/PC/launcher.c b/PC/launcher.c index 2214b08..92f2c2a 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -1089,7 +1089,7 @@ static PYC_MAGIC magic_values[] = { { 3190, 3230, L"3.3" }, { 3250, 3310, L"3.4" }, { 3320, 3351, L"3.5" }, - { 3360, 3373, L"3.6" }, + { 3360, 3375, L"3.6" }, { 0 } }; diff --git a/Parser/Python.asdl b/Parser/Python.asdl index aaddf61..6e982f4 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -28,6 +28,8 @@ module Python | Delete(expr* targets) | Assign(expr* targets, expr value) | AugAssign(expr target, operator op, expr value) + -- 'simple' indicates that we annotate simple name without parens + | AnnAssign(expr target, expr annotation, expr? value, int simple) -- use 'orelse' because else is a keyword in target languages | For(expr target, expr iter, stmt* body, stmt* orelse) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 1193c7c..6ab57df 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -86,6 +86,15 @@ static char *AugAssign_fields[]={ "op", "value", }; +static PyTypeObject *AnnAssign_type; +_Py_IDENTIFIER(annotation); +_Py_IDENTIFIER(simple); +static char *AnnAssign_fields[]={ + "target", + "annotation", + "value", + "simple", +}; static PyTypeObject *For_type; _Py_IDENTIFIER(iter); _Py_IDENTIFIER(orelse); @@ -466,7 +475,6 @@ static char *arg_attributes[] = { "col_offset", }; _Py_IDENTIFIER(arg); -_Py_IDENTIFIER(annotation); static char *arg_fields[]={ "arg", "annotation", @@ -873,6 +881,8 @@ static int init_types(void) if (!Assign_type) return 0; AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3); if (!AugAssign_type) return 0; + AnnAssign_type = make_type("AnnAssign", stmt_type, AnnAssign_fields, 4); + if (!AnnAssign_type) return 0; For_type = make_type("For", stmt_type, For_fields, 4); if (!For_type) return 0; AsyncFor_type = make_type("AsyncFor", stmt_type, AsyncFor_fields, 4); @@ -1407,6 +1417,34 @@ AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int } stmt_ty +AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int + lineno, int col_offset, PyArena *arena) +{ + stmt_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for AnnAssign"); + return NULL; + } + if (!annotation) { + PyErr_SetString(PyExc_ValueError, + "field annotation is required for AnnAssign"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = AnnAssign_kind; + p->v.AnnAssign.target = target; + p->v.AnnAssign.annotation = annotation; + p->v.AnnAssign.value = value; + p->v.AnnAssign.simple = simple; + p->lineno = lineno; + p->col_offset = col_offset; + return p; +} + +stmt_ty For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int lineno, int col_offset, PyArena *arena) { @@ -2740,6 +2778,30 @@ ast2obj_stmt(void* _o) goto failed; Py_DECREF(value); break; + case AnnAssign_kind: + result = PyType_GenericNew(AnnAssign_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.AnnAssign.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AnnAssign.annotation); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_annotation, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AnnAssign.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->v.AnnAssign.simple); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_simple, value) == -1) + goto failed; + Py_DECREF(value); + break; case For_kind: result = PyType_GenericNew(For_type, NULL, NULL); if (!result) goto failed; @@ -4535,6 +4597,64 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) if (*out == NULL) goto failed; return 0; } + isinstance = PyObject_IsInstance(obj, (PyObject*)AnnAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + + if (_PyObject_HasAttrId(obj, &PyId_target)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_target); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_annotation)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_annotation); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &annotation, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign"); + return 1; + } + if (exists_not_none(obj, &PyId_value)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_value); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + value = NULL; + } + if (_PyObject_HasAttrId(obj, &PyId_simple)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_simple); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &simple, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign"); + return 1; + } + *out = AnnAssign(target, annotation, value, simple, lineno, col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject*)For_type); if (isinstance == -1) { return 1; @@ -7517,6 +7637,8 @@ PyInit__ast(void) NULL; if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_type) < 0) return NULL; + if (PyDict_SetItemString(d, "AnnAssign", (PyObject*)AnnAssign_type) < 0) + return NULL; if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return NULL; if (PyDict_SetItemString(d, "AsyncFor", (PyObject*)AsyncFor_type) < 0) return NULL; diff --git a/Python/ast.c b/Python/ast.c index c5f363b..e89ec22 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -397,6 +397,17 @@ validate_stmt(stmt_ty stmt) case AugAssign_kind: return validate_expr(stmt->v.AugAssign.target, Store) && validate_expr(stmt->v.AugAssign.value, Load); + case AnnAssign_kind: + if (stmt->v.AnnAssign.target->kind != Name_kind && + stmt->v.AnnAssign.simple) { + PyErr_SetString(PyExc_TypeError, + "AnnAssign with simple non-Name target"); + return 0; + } + return validate_expr(stmt->v.AnnAssign.target, Store) && + (!stmt->v.AnnAssign.value || + validate_expr(stmt->v.AnnAssign.value, Load)) && + validate_expr(stmt->v.AnnAssign.annotation, Load); case For_kind: return validate_expr(stmt->v.For.target, Store) && validate_expr(stmt->v.For.iter, Load) && @@ -2847,8 +2858,9 @@ static stmt_ty ast_for_expr_stmt(struct compiling *c, const node *n) { REQ(n, expr_stmt); - /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) - | ('=' (yield_expr|testlist))*) + /* expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) + annassign: ':' test ['=' test] testlist_star_expr: (test|star_expr) (',' test|star_expr)* [','] augassign: '+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' @@ -2900,6 +2912,76 @@ ast_for_expr_stmt(struct compiling *c, const node *n) return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, c->c_arena); } + else if (TYPE(CHILD(n, 1)) == annassign) { + expr_ty expr1, expr2, expr3; + node *ch = CHILD(n, 0); + node *deep, *ann = CHILD(n, 1); + int simple = 1; + + /* we keep track of parens to qualify (x) as expression not name */ + deep = ch; + while (NCH(deep) == 1) { + deep = CHILD(deep, 0); + } + if (NCH(deep) > 0 && TYPE(CHILD(deep, 0)) == LPAR) { + simple = 0; + } + expr1 = ast_for_testlist(c, ch); + if (!expr1) { + return NULL; + } + switch (expr1->kind) { + case Name_kind: + if (forbidden_name(c, expr1->v.Name.id, n, 0)) { + return NULL; + } + expr1->v.Name.ctx = Store; + break; + case Attribute_kind: + if (forbidden_name(c, expr1->v.Attribute.attr, n, 1)) { + return NULL; + } + expr1->v.Attribute.ctx = Store; + break; + case Subscript_kind: + expr1->v.Subscript.ctx = Store; + break; + case List_kind: + ast_error(c, ch, + "only single target (not list) can be annotated"); + return NULL; + case Tuple_kind: + ast_error(c, ch, + "only single target (not tuple) can be annotated"); + return NULL; + default: + ast_error(c, ch, + "illegal target for annotation"); + return NULL; + } + + if (expr1->kind != Name_kind) { + simple = 0; + } + ch = CHILD(ann, 1); + expr2 = ast_for_expr(c, ch); + if (!expr2) { + return NULL; + } + if (NCH(ann) == 2) { + return AnnAssign(expr1, expr2, NULL, simple, + LINENO(n), n->n_col_offset, c->c_arena); + } + else { + ch = CHILD(ann, 3); + expr3 = ast_for_expr(c, ch); + if (!expr3) { + return NULL; + } + return AnnAssign(expr1, expr2, expr3, simple, + LINENO(n), n->n_col_offset, c->c_arena); + } + } else { int i; asdl_seq *targets; diff --git a/Python/ceval.c b/Python/ceval.c index 0c3ef7b..a52ee8a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1873,6 +1873,62 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(STORE_ANNOTATION) { + _Py_IDENTIFIER(__annotations__); + PyObject *ann_dict; + PyObject *ann = POP(); + PyObject *name = GETITEM(names, oparg); + int err; + if (f->f_locals == NULL) { + PyErr_Format(PyExc_SystemError, + "no locals found when storing annotation"); + Py_DECREF(ann); + goto error; + } + /* first try to get __annotations__ from locals... */ + if (PyDict_CheckExact(f->f_locals)) { + ann_dict = _PyDict_GetItemId(f->f_locals, + &PyId___annotations__); + if (ann_dict == NULL) { + PyErr_SetString(PyExc_NameError, + "__annotations__ not found"); + Py_DECREF(ann); + goto error; + } + Py_INCREF(ann_dict); + } + else { + PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__); + if (ann_str == NULL) { + Py_DECREF(ann); + goto error; + } + ann_dict = PyObject_GetItem(f->f_locals, ann_str); + if (ann_dict == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_SetString(PyExc_NameError, + "__annotations__ not found"); + } + Py_DECREF(ann); + goto error; + } + } + /* ...if succeeded, __annotations__[name] = ann */ + if (PyDict_CheckExact(ann_dict)) { + err = PyDict_SetItem(ann_dict, name, ann); + } + else { + err = PyObject_SetItem(ann_dict, name, ann); + } + Py_DECREF(ann_dict); + if (err != 0) { + Py_DECREF(ann); + goto error; + } + Py_DECREF(ann); + DISPATCH(); + } + TARGET(DELETE_SUBSCR) { PyObject *sub = TOP(); PyObject *container = SECOND(); @@ -2680,6 +2736,62 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(SETUP_ANNOTATIONS) { + _Py_IDENTIFIER(__annotations__); + int err; + PyObject *ann_dict; + if (f->f_locals == NULL) { + PyErr_Format(PyExc_SystemError, + "no locals found when setting up annotations"); + goto error; + } + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(f->f_locals)) { + ann_dict = _PyDict_GetItemId(f->f_locals, + &PyId___annotations__); + if (ann_dict == NULL) { + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + if (ann_dict == NULL) { + goto error; + } + err = _PyDict_SetItemId(f->f_locals, + &PyId___annotations__, ann_dict); + Py_DECREF(ann_dict); + if (err != 0) { + goto error; + } + } + } + else { + /* do the same if locals() is not a dict */ + PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__); + if (ann_str == NULL) { + break; + } + ann_dict = PyObject_GetItem(f->f_locals, ann_str); + if (ann_dict == NULL) { + if (!PyErr_ExceptionMatches(PyExc_KeyError)) { + goto error; + } + PyErr_Clear(); + ann_dict = PyDict_New(); + if (ann_dict == NULL) { + goto error; + } + err = PyObject_SetItem(f->f_locals, ann_str, ann_dict); + Py_DECREF(ann_dict); + if (err != 0) { + goto error; + } + } + else { + Py_DECREF(ann_dict); + } + } + DISPATCH(); + } + TARGET(BUILD_CONST_KEY_MAP) { Py_ssize_t i; PyObject *map; diff --git a/Python/compile.c b/Python/compile.c index 45e4262..b46edd4 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -179,6 +179,7 @@ static int compiler_visit_stmt(struct compiler *, stmt_ty); static int compiler_visit_keyword(struct compiler *, keyword_ty); static int compiler_visit_expr(struct compiler *, expr_ty); static int compiler_augassign(struct compiler *, stmt_ty); +static int compiler_annassign(struct compiler *, stmt_ty); static int compiler_visit_slice(struct compiler *, slice_ty, expr_context_ty); @@ -933,6 +934,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return -1; case IMPORT_STAR: return -1; + case SETUP_ANNOTATIONS: + return 0; case YIELD_VALUE: return 0; case YIELD_FROM: @@ -1020,6 +1023,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return -1; case DELETE_FAST: return 0; + case STORE_ANNOTATION: + return -1; case RAISE_VARARGS: return -oparg; @@ -1358,7 +1363,65 @@ get_const_value(expr_ty e) } } -/* Compile a sequence of statements, checking for a docstring. */ +/* Search if variable annotations are present statically in a block. */ + +static int +find_ann(asdl_seq *stmts) +{ + int i, j, res = 0; + stmt_ty st; + + for (i = 0; i < asdl_seq_LEN(stmts); i++) { + st = (stmt_ty)asdl_seq_GET(stmts, i); + switch (st->kind) { + case AnnAssign_kind: + return 1; + case For_kind: + res = find_ann(st->v.For.body) || + find_ann(st->v.For.orelse); + break; + case AsyncFor_kind: + res = find_ann(st->v.AsyncFor.body) || + find_ann(st->v.AsyncFor.orelse); + break; + case While_kind: + res = find_ann(st->v.While.body) || + find_ann(st->v.While.orelse); + break; + case If_kind: + res = find_ann(st->v.If.body) || + find_ann(st->v.If.orelse); + break; + case With_kind: + res = find_ann(st->v.With.body); + break; + case AsyncWith_kind: + res = find_ann(st->v.AsyncWith.body); + break; + case Try_kind: + for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) { + excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( + st->v.Try.handlers, j); + if (find_ann(handler->v.ExceptHandler.body)) { + return 1; + } + } + res = find_ann(st->v.Try.body) || + find_ann(st->v.Try.finalbody) || + find_ann(st->v.Try.orelse); + break; + default: + res = 0; + } + if (res) { + break; + } + } + return res; +} + +/* Compile a sequence of statements, checking for a docstring + and for annotations. */ static int compiler_body(struct compiler *c, asdl_seq *stmts) @@ -1366,6 +1429,19 @@ compiler_body(struct compiler *c, asdl_seq *stmts) int i = 0; stmt_ty st; + /* Set current line number to the line number of first statement. + This way line number for SETUP_ANNOTATIONS will always + coincide with the line number of first "real" statement in module. + If body is empy, then lineno will be set later in assemble. */ + if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && + !c->u->u_lineno && asdl_seq_LEN(stmts)) { + st = (stmt_ty)asdl_seq_GET(stmts, 0); + c->u->u_lineno = st->lineno; + } + /* Every annotated class and module should have __annotations__. */ + if (find_ann(stmts)) { + ADDOP(c, SETUP_ANNOTATIONS); + } if (!asdl_seq_LEN(stmts)) return 1; st = (stmt_ty)asdl_seq_GET(stmts, 0); @@ -1403,6 +1479,9 @@ compiler_mod(struct compiler *c, mod_ty mod) } break; case Interactive_kind: + if (find_ann(mod->v.Interactive.body)) { + ADDOP(c, SETUP_ANNOTATIONS); + } c->c_interactive = 1; VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); @@ -2743,6 +2822,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) break; case AugAssign_kind: return compiler_augassign(c, s); + case AnnAssign_kind: + return compiler_annassign(c, s); case For_kind: return compiler_for(c, s); case While_kind: @@ -4223,6 +4304,138 @@ compiler_augassign(struct compiler *c, stmt_ty s) } static int +check_ann_expr(struct compiler *c, expr_ty e) +{ + VISIT(c, expr, e); + ADDOP(c, POP_TOP); + return 1; +} + +static int +check_annotation(struct compiler *c, stmt_ty s) +{ + /* Annotations are only evaluated in a module or class. */ + if (c->u->u_scope_type == COMPILER_SCOPE_MODULE || + c->u->u_scope_type == COMPILER_SCOPE_CLASS) { + return check_ann_expr(c, s->v.AnnAssign.annotation); + } + return 1; +} + +static int +check_ann_slice(struct compiler *c, slice_ty sl) +{ + switch(sl->kind) { + case Index_kind: + return check_ann_expr(c, sl->v.Index.value); + case Slice_kind: + if (sl->v.Slice.lower && !check_ann_expr(c, sl->v.Slice.lower)) { + return 0; + } + if (sl->v.Slice.upper && !check_ann_expr(c, sl->v.Slice.upper)) { + return 0; + } + if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) { + return 0; + } + break; + default: + PyErr_SetString(PyExc_SystemError, + "unexpected slice kind"); + return 0; + } + return 1; +} + +static int +check_ann_subscr(struct compiler *c, slice_ty sl) +{ + /* We check that everything in a subscript is defined at runtime. */ + Py_ssize_t i, n; + + switch (sl->kind) { + case Index_kind: + case Slice_kind: + if (!check_ann_slice(c, sl)) { + return 0; + } + break; + case ExtSlice_kind: + n = asdl_seq_LEN(sl->v.ExtSlice.dims); + for (i = 0; i < n; i++) { + slice_ty subsl = (slice_ty)asdl_seq_GET(sl->v.ExtSlice.dims, i); + switch (subsl->kind) { + case Index_kind: + case Slice_kind: + if (!check_ann_slice(c, subsl)) { + return 0; + } + break; + case ExtSlice_kind: + default: + PyErr_SetString(PyExc_SystemError, + "extended slice invalid in nested slice"); + return 0; + } + } + break; + default: + PyErr_Format(PyExc_SystemError, + "invalid subscript kind %d", sl->kind); + return 0; + } + return 1; +} + +static int +compiler_annassign(struct compiler *c, stmt_ty s) +{ + expr_ty targ = s->v.AnnAssign.target; + + assert(s->kind == AnnAssign_kind); + + /* We perform the actual assignment first. */ + if (s->v.AnnAssign.value) { + VISIT(c, expr, s->v.AnnAssign.value); + VISIT(c, expr, targ); + } + switch (targ->kind) { + case Name_kind: + /* If we have a simple name in a module or class, store annotation. */ + if (s->v.AnnAssign.simple && + (c->u->u_scope_type == COMPILER_SCOPE_MODULE || + c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { + VISIT(c, expr, s->v.AnnAssign.annotation); + ADDOP_O(c, STORE_ANNOTATION, targ->v.Name.id, names) + } + break; + case Attribute_kind: + if (!s->v.AnnAssign.value && + !check_ann_expr(c, targ->v.Attribute.value)) { + return 0; + } + break; + case Subscript_kind: + if (!s->v.AnnAssign.value && + (!check_ann_expr(c, targ->v.Subscript.value) || + !check_ann_subscr(c, targ->v.Subscript.slice))) { + return 0; + } + break; + default: + PyErr_Format(PyExc_SystemError, + "invalid node type (%d) for annotated assignment", + targ->kind); + return 0; + } + /* Annotation is evaluated last. */ + if (!s->v.AnnAssign.simple && !check_annotation(c, s)) { + return 0; + } + return 1; +} + +static int compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b) { struct fblockinfo *f; diff --git a/Python/graminit.c b/Python/graminit.c index 354dc12..c11b831 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -459,54 +459,77 @@ static state states_15[2] = { static arc arcs_16_0[1] = { {47, 1}, }; -static arc arcs_16_1[3] = { +static arc arcs_16_1[4] = { {48, 2}, - {31, 3}, + {49, 3}, + {31, 4}, {0, 1}, }; -static arc arcs_16_2[2] = { - {49, 4}, - {9, 4}, +static arc arcs_16_2[1] = { + {0, 2}, }; static arc arcs_16_3[2] = { - {49, 5}, - {47, 5}, + {50, 2}, + {9, 2}, }; -static arc arcs_16_4[1] = { - {0, 4}, +static arc arcs_16_4[2] = { + {50, 5}, + {47, 5}, }; static arc arcs_16_5[2] = { - {31, 3}, + {31, 4}, {0, 5}, }; static state states_16[6] = { {1, arcs_16_0}, - {3, arcs_16_1}, - {2, arcs_16_2}, + {4, arcs_16_1}, + {1, arcs_16_2}, {2, arcs_16_3}, - {1, arcs_16_4}, + {2, arcs_16_4}, {2, arcs_16_5}, }; -static arc arcs_17_0[2] = { +static arc arcs_17_0[1] = { + {27, 1}, +}; +static arc arcs_17_1[1] = { + {26, 2}, +}; +static arc arcs_17_2[2] = { + {31, 3}, + {0, 2}, +}; +static arc arcs_17_3[1] = { + {26, 4}, +}; +static arc arcs_17_4[1] = { + {0, 4}, +}; +static state states_17[5] = { + {1, arcs_17_0}, + {1, arcs_17_1}, + {2, arcs_17_2}, + {1, arcs_17_3}, + {1, arcs_17_4}, +}; +static arc arcs_18_0[2] = { {26, 1}, - {50, 1}, + {51, 1}, }; -static arc arcs_17_1[2] = { +static arc arcs_18_1[2] = { {32, 2}, {0, 1}, }; -static arc arcs_17_2[3] = { +static arc arcs_18_2[3] = { {26, 1}, - {50, 1}, + {51, 1}, {0, 2}, }; -static state states_17[3] = { - {2, arcs_17_0}, - {2, arcs_17_1}, - {3, arcs_17_2}, +static state states_18[3] = { + {2, arcs_18_0}, + {2, arcs_18_1}, + {3, arcs_18_2}, }; -static arc arcs_18_0[13] = { - {51, 1}, +static arc arcs_19_0[13] = { {52, 1}, {53, 1}, {54, 1}, @@ -519,60 +542,51 @@ static arc arcs_18_0[13] = { {61, 1}, {62, 1}, {63, 1}, -}; -static arc arcs_18_1[1] = { - {0, 1}, -}; -static state states_18[2] = { - {13, arcs_18_0}, - {1, arcs_18_1}, -}; -static arc arcs_19_0[1] = { {64, 1}, }; static arc arcs_19_1[1] = { - {65, 2}, -}; -static arc arcs_19_2[1] = { - {0, 2}, + {0, 1}, }; -static state states_19[3] = { - {1, arcs_19_0}, +static state states_19[2] = { + {13, arcs_19_0}, {1, arcs_19_1}, - {1, arcs_19_2}, }; static arc arcs_20_0[1] = { - {66, 1}, + {65, 1}, }; static arc arcs_20_1[1] = { - {0, 1}, + {66, 2}, +}; +static arc arcs_20_2[1] = { + {0, 2}, }; -static state states_20[2] = { +static state states_20[3] = { {1, arcs_20_0}, {1, arcs_20_1}, + {1, arcs_20_2}, }; -static arc arcs_21_0[5] = { +static arc arcs_21_0[1] = { {67, 1}, - {68, 1}, - {69, 1}, - {70, 1}, - {71, 1}, }; static arc arcs_21_1[1] = { {0, 1}, }; static state states_21[2] = { - {5, arcs_21_0}, + {1, arcs_21_0}, {1, arcs_21_1}, }; -static arc arcs_22_0[1] = { +static arc arcs_22_0[5] = { + {68, 1}, + {69, 1}, + {70, 1}, + {71, 1}, {72, 1}, }; static arc arcs_22_1[1] = { {0, 1}, }; static state states_22[2] = { - {1, arcs_22_0}, + {5, arcs_22_0}, {1, arcs_22_1}, }; static arc arcs_23_0[1] = { @@ -588,142 +602,133 @@ static state states_23[2] = { static arc arcs_24_0[1] = { {74, 1}, }; -static arc arcs_24_1[2] = { - {9, 2}, +static arc arcs_24_1[1] = { {0, 1}, }; -static arc arcs_24_2[1] = { - {0, 2}, -}; -static state states_24[3] = { +static state states_24[2] = { {1, arcs_24_0}, - {2, arcs_24_1}, - {1, arcs_24_2}, + {1, arcs_24_1}, }; static arc arcs_25_0[1] = { - {49, 1}, + {75, 1}, }; -static arc arcs_25_1[1] = { +static arc arcs_25_1[2] = { + {9, 2}, {0, 1}, }; -static state states_25[2] = { +static arc arcs_25_2[1] = { + {0, 2}, +}; +static state states_25[3] = { {1, arcs_25_0}, - {1, arcs_25_1}, + {2, arcs_25_1}, + {1, arcs_25_2}, }; static arc arcs_26_0[1] = { - {75, 1}, + {50, 1}, +}; +static arc arcs_26_1[1] = { + {0, 1}, +}; +static state states_26[2] = { + {1, arcs_26_0}, + {1, arcs_26_1}, +}; +static arc arcs_27_0[1] = { + {76, 1}, }; -static arc arcs_26_1[2] = { +static arc arcs_27_1[2] = { {26, 2}, {0, 1}, }; -static arc arcs_26_2[2] = { - {76, 3}, +static arc arcs_27_2[2] = { + {77, 3}, {0, 2}, }; -static arc arcs_26_3[1] = { +static arc arcs_27_3[1] = { {26, 4}, }; -static arc arcs_26_4[1] = { +static arc arcs_27_4[1] = { {0, 4}, }; -static state states_26[5] = { - {1, arcs_26_0}, - {2, arcs_26_1}, - {2, arcs_26_2}, - {1, arcs_26_3}, - {1, arcs_26_4}, +static state states_27[5] = { + {1, arcs_27_0}, + {2, arcs_27_1}, + {2, arcs_27_2}, + {1, arcs_27_3}, + {1, arcs_27_4}, }; -static arc arcs_27_0[2] = { - {77, 1}, +static arc arcs_28_0[2] = { {78, 1}, + {79, 1}, }; -static arc arcs_27_1[1] = { +static arc arcs_28_1[1] = { {0, 1}, }; -static state states_27[2] = { - {2, arcs_27_0}, - {1, arcs_27_1}, +static state states_28[2] = { + {2, arcs_28_0}, + {1, arcs_28_1}, }; -static arc arcs_28_0[1] = { - {79, 1}, +static arc arcs_29_0[1] = { + {80, 1}, }; -static arc arcs_28_1[1] = { - {80, 2}, +static arc arcs_29_1[1] = { + {81, 2}, }; -static arc arcs_28_2[1] = { +static arc arcs_29_2[1] = { {0, 2}, }; -static state states_28[3] = { - {1, arcs_28_0}, - {1, arcs_28_1}, - {1, arcs_28_2}, +static state states_29[3] = { + {1, arcs_29_0}, + {1, arcs_29_1}, + {1, arcs_29_2}, }; -static arc arcs_29_0[1] = { - {76, 1}, +static arc arcs_30_0[1] = { + {77, 1}, }; -static arc arcs_29_1[3] = { - {81, 2}, +static arc arcs_30_1[3] = { {82, 2}, + {83, 2}, {12, 3}, }; -static arc arcs_29_2[4] = { - {81, 2}, +static arc arcs_30_2[4] = { {82, 2}, + {83, 2}, {12, 3}, - {79, 4}, + {80, 4}, }; -static arc arcs_29_3[1] = { - {79, 4}, +static arc arcs_30_3[1] = { + {80, 4}, }; -static arc arcs_29_4[3] = { +static arc arcs_30_4[3] = { {33, 5}, {13, 6}, - {83, 5}, + {84, 5}, }; -static arc arcs_29_5[1] = { +static arc arcs_30_5[1] = { {0, 5}, }; -static arc arcs_29_6[1] = { - {83, 7}, +static arc arcs_30_6[1] = { + {84, 7}, }; -static arc arcs_29_7[1] = { +static arc arcs_30_7[1] = { {15, 5}, }; -static state states_29[8] = { - {1, arcs_29_0}, - {3, arcs_29_1}, - {4, arcs_29_2}, - {1, arcs_29_3}, - {3, arcs_29_4}, - {1, arcs_29_5}, - {1, arcs_29_6}, - {1, arcs_29_7}, -}; -static arc arcs_30_0[1] = { - {23, 1}, -}; -static arc arcs_30_1[2] = { - {85, 2}, - {0, 1}, -}; -static arc arcs_30_2[1] = { - {23, 3}, -}; -static arc arcs_30_3[1] = { - {0, 3}, -}; -static state states_30[4] = { +static state states_30[8] = { {1, arcs_30_0}, - {2, arcs_30_1}, - {1, arcs_30_2}, + {3, arcs_30_1}, + {4, arcs_30_2}, {1, arcs_30_3}, + {3, arcs_30_4}, + {1, arcs_30_5}, + {1, arcs_30_6}, + {1, arcs_30_7}, }; static arc arcs_31_0[1] = { - {12, 1}, + {23, 1}, }; static arc arcs_31_1[2] = { - {85, 2}, + {86, 2}, {0, 1}, }; static arc arcs_31_2[1] = { @@ -739,37 +744,45 @@ static state states_31[4] = { {1, arcs_31_3}, }; static arc arcs_32_0[1] = { - {84, 1}, + {12, 1}, }; static arc arcs_32_1[2] = { - {32, 2}, + {86, 2}, {0, 1}, }; -static arc arcs_32_2[2] = { - {84, 1}, - {0, 2}, +static arc arcs_32_2[1] = { + {23, 3}, +}; +static arc arcs_32_3[1] = { + {0, 3}, }; -static state states_32[3] = { +static state states_32[4] = { {1, arcs_32_0}, {2, arcs_32_1}, - {2, arcs_32_2}, + {1, arcs_32_2}, + {1, arcs_32_3}, }; static arc arcs_33_0[1] = { - {86, 1}, + {85, 1}, }; static arc arcs_33_1[2] = { - {32, 0}, + {32, 2}, {0, 1}, }; -static state states_33[2] = { +static arc arcs_33_2[2] = { + {85, 1}, + {0, 2}, +}; +static state states_33[3] = { {1, arcs_33_0}, {2, arcs_33_1}, + {2, arcs_33_2}, }; static arc arcs_34_0[1] = { - {23, 1}, + {87, 1}, }; static arc arcs_34_1[2] = { - {81, 0}, + {32, 0}, {0, 1}, }; static state states_34[2] = { @@ -777,19 +790,15 @@ static state states_34[2] = { {2, arcs_34_1}, }; static arc arcs_35_0[1] = { - {87, 1}, -}; -static arc arcs_35_1[1] = { - {23, 2}, + {23, 1}, }; -static arc arcs_35_2[2] = { - {32, 1}, - {0, 2}, +static arc arcs_35_1[2] = { + {82, 0}, + {0, 1}, }; -static state states_35[3] = { +static state states_35[2] = { {1, arcs_35_0}, - {1, arcs_35_1}, - {2, arcs_35_2}, + {2, arcs_35_1}, }; static arc arcs_36_0[1] = { {88, 1}, @@ -810,97 +819,76 @@ static arc arcs_37_0[1] = { {89, 1}, }; static arc arcs_37_1[1] = { - {26, 2}, + {23, 2}, }; static arc arcs_37_2[2] = { + {32, 1}, + {0, 2}, +}; +static state states_37[3] = { + {1, arcs_37_0}, + {1, arcs_37_1}, + {2, arcs_37_2}, +}; +static arc arcs_38_0[1] = { + {90, 1}, +}; +static arc arcs_38_1[1] = { + {26, 2}, +}; +static arc arcs_38_2[2] = { {32, 3}, {0, 2}, }; -static arc arcs_37_3[1] = { +static arc arcs_38_3[1] = { {26, 4}, }; -static arc arcs_37_4[1] = { +static arc arcs_38_4[1] = { {0, 4}, }; -static state states_37[5] = { - {1, arcs_37_0}, - {1, arcs_37_1}, - {2, arcs_37_2}, - {1, arcs_37_3}, - {1, arcs_37_4}, +static state states_38[5] = { + {1, arcs_38_0}, + {1, arcs_38_1}, + {2, arcs_38_2}, + {1, arcs_38_3}, + {1, arcs_38_4}, }; -static arc arcs_38_0[9] = { - {90, 1}, +static arc arcs_39_0[9] = { {91, 1}, {92, 1}, {93, 1}, {94, 1}, + {95, 1}, {19, 1}, {18, 1}, {17, 1}, - {95, 1}, + {96, 1}, }; -static arc arcs_38_1[1] = { +static arc arcs_39_1[1] = { {0, 1}, }; -static state states_38[2] = { - {9, arcs_38_0}, - {1, arcs_38_1}, +static state states_39[2] = { + {9, arcs_39_0}, + {1, arcs_39_1}, }; -static arc arcs_39_0[1] = { +static arc arcs_40_0[1] = { {21, 1}, }; -static arc arcs_39_1[3] = { +static arc arcs_40_1[3] = { {19, 2}, - {94, 2}, - {92, 2}, -}; -static arc arcs_39_2[1] = { - {0, 2}, -}; -static state states_39[3] = { - {1, arcs_39_0}, - {3, arcs_39_1}, - {1, arcs_39_2}, -}; -static arc arcs_40_0[1] = { - {96, 1}, -}; -static arc arcs_40_1[1] = { - {26, 2}, + {95, 2}, + {93, 2}, }; static arc arcs_40_2[1] = { - {27, 3}, -}; -static arc arcs_40_3[1] = { - {28, 4}, -}; -static arc arcs_40_4[3] = { - {97, 1}, - {98, 5}, - {0, 4}, -}; -static arc arcs_40_5[1] = { - {27, 6}, -}; -static arc arcs_40_6[1] = { - {28, 7}, -}; -static arc arcs_40_7[1] = { - {0, 7}, + {0, 2}, }; -static state states_40[8] = { +static state states_40[3] = { {1, arcs_40_0}, - {1, arcs_40_1}, + {3, arcs_40_1}, {1, arcs_40_2}, - {1, arcs_40_3}, - {3, arcs_40_4}, - {1, arcs_40_5}, - {1, arcs_40_6}, - {1, arcs_40_7}, }; static arc arcs_41_0[1] = { - {99, 1}, + {97, 1}, }; static arc arcs_41_1[1] = { {26, 2}, @@ -911,8 +899,9 @@ static arc arcs_41_2[1] = { static arc arcs_41_3[1] = { {28, 4}, }; -static arc arcs_41_4[2] = { - {98, 5}, +static arc arcs_41_4[3] = { + {98, 1}, + {99, 5}, {0, 4}, }; static arc arcs_41_5[1] = { @@ -929,7 +918,7 @@ static state states_41[8] = { {1, arcs_41_1}, {1, arcs_41_2}, {1, arcs_41_3}, - {2, arcs_41_4}, + {3, arcs_41_4}, {1, arcs_41_5}, {1, arcs_41_6}, {1, arcs_41_7}, @@ -938,258 +927,270 @@ static arc arcs_42_0[1] = { {100, 1}, }; static arc arcs_42_1[1] = { - {65, 2}, + {26, 2}, }; static arc arcs_42_2[1] = { - {101, 3}, + {27, 3}, }; static arc arcs_42_3[1] = { - {9, 4}, + {28, 4}, }; -static arc arcs_42_4[1] = { - {27, 5}, +static arc arcs_42_4[2] = { + {99, 5}, + {0, 4}, }; static arc arcs_42_5[1] = { - {28, 6}, + {27, 6}, }; -static arc arcs_42_6[2] = { - {98, 7}, - {0, 6}, +static arc arcs_42_6[1] = { + {28, 7}, }; static arc arcs_42_7[1] = { - {27, 8}, -}; -static arc arcs_42_8[1] = { - {28, 9}, -}; -static arc arcs_42_9[1] = { - {0, 9}, + {0, 7}, }; -static state states_42[10] = { +static state states_42[8] = { {1, arcs_42_0}, {1, arcs_42_1}, {1, arcs_42_2}, {1, arcs_42_3}, - {1, arcs_42_4}, + {2, arcs_42_4}, {1, arcs_42_5}, - {2, arcs_42_6}, + {1, arcs_42_6}, {1, arcs_42_7}, - {1, arcs_42_8}, - {1, arcs_42_9}, }; static arc arcs_43_0[1] = { - {102, 1}, + {101, 1}, }; static arc arcs_43_1[1] = { - {27, 2}, + {66, 2}, }; static arc arcs_43_2[1] = { - {28, 3}, + {102, 3}, }; -static arc arcs_43_3[2] = { - {103, 4}, - {104, 5}, +static arc arcs_43_3[1] = { + {9, 4}, }; static arc arcs_43_4[1] = { - {27, 6}, + {27, 5}, }; static arc arcs_43_5[1] = { - {27, 7}, + {28, 6}, }; -static arc arcs_43_6[1] = { - {28, 8}, +static arc arcs_43_6[2] = { + {99, 7}, + {0, 6}, }; static arc arcs_43_7[1] = { - {28, 9}, + {27, 8}, }; -static arc arcs_43_8[4] = { - {103, 4}, - {98, 10}, - {104, 5}, - {0, 8}, +static arc arcs_43_8[1] = { + {28, 9}, }; static arc arcs_43_9[1] = { {0, 9}, }; -static arc arcs_43_10[1] = { - {27, 11}, -}; -static arc arcs_43_11[1] = { - {28, 12}, -}; -static arc arcs_43_12[2] = { - {104, 5}, - {0, 12}, -}; -static state states_43[13] = { +static state states_43[10] = { {1, arcs_43_0}, {1, arcs_43_1}, {1, arcs_43_2}, - {2, arcs_43_3}, + {1, arcs_43_3}, {1, arcs_43_4}, {1, arcs_43_5}, - {1, arcs_43_6}, + {2, arcs_43_6}, {1, arcs_43_7}, - {4, arcs_43_8}, + {1, arcs_43_8}, {1, arcs_43_9}, - {1, arcs_43_10}, - {1, arcs_43_11}, - {2, arcs_43_12}, }; static arc arcs_44_0[1] = { - {105, 1}, + {103, 1}, }; static arc arcs_44_1[1] = { - {106, 2}, + {27, 2}, }; -static arc arcs_44_2[2] = { - {32, 1}, - {27, 3}, +static arc arcs_44_2[1] = { + {28, 3}, }; -static arc arcs_44_3[1] = { - {28, 4}, +static arc arcs_44_3[2] = { + {104, 4}, + {105, 5}, }; static arc arcs_44_4[1] = { - {0, 4}, + {27, 6}, }; -static state states_44[5] = { +static arc arcs_44_5[1] = { + {27, 7}, +}; +static arc arcs_44_6[1] = { + {28, 8}, +}; +static arc arcs_44_7[1] = { + {28, 9}, +}; +static arc arcs_44_8[4] = { + {104, 4}, + {99, 10}, + {105, 5}, + {0, 8}, +}; +static arc arcs_44_9[1] = { + {0, 9}, +}; +static arc arcs_44_10[1] = { + {27, 11}, +}; +static arc arcs_44_11[1] = { + {28, 12}, +}; +static arc arcs_44_12[2] = { + {105, 5}, + {0, 12}, +}; +static state states_44[13] = { {1, arcs_44_0}, {1, arcs_44_1}, - {2, arcs_44_2}, - {1, arcs_44_3}, + {1, arcs_44_2}, + {2, arcs_44_3}, {1, arcs_44_4}, + {1, arcs_44_5}, + {1, arcs_44_6}, + {1, arcs_44_7}, + {4, arcs_44_8}, + {1, arcs_44_9}, + {1, arcs_44_10}, + {1, arcs_44_11}, + {2, arcs_44_12}, }; static arc arcs_45_0[1] = { - {26, 1}, + {106, 1}, }; -static arc arcs_45_1[2] = { - {85, 2}, - {0, 1}, +static arc arcs_45_1[1] = { + {107, 2}, }; -static arc arcs_45_2[1] = { - {107, 3}, +static arc arcs_45_2[2] = { + {32, 1}, + {27, 3}, }; static arc arcs_45_3[1] = { - {0, 3}, + {28, 4}, }; -static state states_45[4] = { +static arc arcs_45_4[1] = { + {0, 4}, +}; +static state states_45[5] = { {1, arcs_45_0}, - {2, arcs_45_1}, - {1, arcs_45_2}, + {1, arcs_45_1}, + {2, arcs_45_2}, {1, arcs_45_3}, + {1, arcs_45_4}, }; static arc arcs_46_0[1] = { - {108, 1}, + {26, 1}, }; static arc arcs_46_1[2] = { - {26, 2}, + {86, 2}, {0, 1}, }; -static arc arcs_46_2[2] = { - {85, 3}, - {0, 2}, +static arc arcs_46_2[1] = { + {108, 3}, }; static arc arcs_46_3[1] = { - {23, 4}, -}; -static arc arcs_46_4[1] = { - {0, 4}, + {0, 3}, }; -static state states_46[5] = { +static state states_46[4] = { {1, arcs_46_0}, {2, arcs_46_1}, - {2, arcs_46_2}, + {1, arcs_46_2}, {1, arcs_46_3}, - {1, arcs_46_4}, }; -static arc arcs_47_0[2] = { - {3, 1}, - {2, 2}, +static arc arcs_47_0[1] = { + {109, 1}, }; -static arc arcs_47_1[1] = { +static arc arcs_47_1[2] = { + {26, 2}, {0, 1}, }; -static arc arcs_47_2[1] = { - {109, 3}, +static arc arcs_47_2[2] = { + {86, 3}, + {0, 2}, }; static arc arcs_47_3[1] = { - {6, 4}, + {23, 4}, }; -static arc arcs_47_4[2] = { - {6, 4}, - {110, 1}, +static arc arcs_47_4[1] = { + {0, 4}, }; static state states_47[5] = { - {2, arcs_47_0}, - {1, arcs_47_1}, - {1, arcs_47_2}, + {1, arcs_47_0}, + {2, arcs_47_1}, + {2, arcs_47_2}, {1, arcs_47_3}, - {2, arcs_47_4}, + {1, arcs_47_4}, }; static arc arcs_48_0[2] = { - {111, 1}, - {112, 2}, + {3, 1}, + {2, 2}, }; -static arc arcs_48_1[2] = { - {96, 3}, +static arc arcs_48_1[1] = { {0, 1}, }; static arc arcs_48_2[1] = { - {0, 2}, + {110, 3}, }; static arc arcs_48_3[1] = { - {111, 4}, -}; -static arc arcs_48_4[1] = { - {98, 5}, + {6, 4}, }; -static arc arcs_48_5[1] = { - {26, 2}, +static arc arcs_48_4[2] = { + {6, 4}, + {111, 1}, }; -static state states_48[6] = { +static state states_48[5] = { {2, arcs_48_0}, - {2, arcs_48_1}, + {1, arcs_48_1}, {1, arcs_48_2}, {1, arcs_48_3}, - {1, arcs_48_4}, - {1, arcs_48_5}, + {2, arcs_48_4}, }; static arc arcs_49_0[2] = { - {111, 1}, - {114, 1}, + {112, 1}, + {113, 2}, }; -static arc arcs_49_1[1] = { +static arc arcs_49_1[2] = { + {97, 3}, {0, 1}, }; -static state states_49[2] = { - {2, arcs_49_0}, - {1, arcs_49_1}, +static arc arcs_49_2[1] = { + {0, 2}, }; -static arc arcs_50_0[1] = { - {115, 1}, +static arc arcs_49_3[1] = { + {112, 4}, }; -static arc arcs_50_1[2] = { - {35, 2}, - {27, 3}, +static arc arcs_49_4[1] = { + {99, 5}, }; -static arc arcs_50_2[1] = { - {27, 3}, +static arc arcs_49_5[1] = { + {26, 2}, }; -static arc arcs_50_3[1] = { - {26, 4}, +static state states_49[6] = { + {2, arcs_49_0}, + {2, arcs_49_1}, + {1, arcs_49_2}, + {1, arcs_49_3}, + {1, arcs_49_4}, + {1, arcs_49_5}, +}; +static arc arcs_50_0[2] = { + {112, 1}, + {115, 1}, }; -static arc arcs_50_4[1] = { - {0, 4}, +static arc arcs_50_1[1] = { + {0, 1}, }; -static state states_50[5] = { - {1, arcs_50_0}, - {2, arcs_50_1}, - {1, arcs_50_2}, - {1, arcs_50_3}, - {1, arcs_50_4}, +static state states_50[2] = { + {2, arcs_50_0}, + {1, arcs_50_1}, }; static arc arcs_51_0[1] = { - {115, 1}, + {116, 1}, }; static arc arcs_51_1[2] = { {35, 2}, @@ -1199,7 +1200,7 @@ static arc arcs_51_2[1] = { {27, 3}, }; static arc arcs_51_3[1] = { - {113, 4}, + {26, 4}, }; static arc arcs_51_4[1] = { {0, 4}, @@ -1215,108 +1216,120 @@ static arc arcs_52_0[1] = { {116, 1}, }; static arc arcs_52_1[2] = { - {117, 0}, - {0, 1}, + {35, 2}, + {27, 3}, +}; +static arc arcs_52_2[1] = { + {27, 3}, +}; +static arc arcs_52_3[1] = { + {114, 4}, }; -static state states_52[2] = { +static arc arcs_52_4[1] = { + {0, 4}, +}; +static state states_52[5] = { {1, arcs_52_0}, {2, arcs_52_1}, + {1, arcs_52_2}, + {1, arcs_52_3}, + {1, arcs_52_4}, }; static arc arcs_53_0[1] = { - {118, 1}, + {117, 1}, }; static arc arcs_53_1[2] = { - {119, 0}, + {118, 0}, {0, 1}, }; static state states_53[2] = { {1, arcs_53_0}, {2, arcs_53_1}, }; -static arc arcs_54_0[2] = { - {120, 1}, - {121, 2}, +static arc arcs_54_0[1] = { + {119, 1}, +}; +static arc arcs_54_1[2] = { + {120, 0}, + {0, 1}, +}; +static state states_54[2] = { + {1, arcs_54_0}, + {2, arcs_54_1}, }; -static arc arcs_54_1[1] = { - {118, 2}, +static arc arcs_55_0[2] = { + {121, 1}, + {122, 2}, }; -static arc arcs_54_2[1] = { +static arc arcs_55_1[1] = { + {119, 2}, +}; +static arc arcs_55_2[1] = { {0, 2}, }; -static state states_54[3] = { - {2, arcs_54_0}, - {1, arcs_54_1}, - {1, arcs_54_2}, +static state states_55[3] = { + {2, arcs_55_0}, + {1, arcs_55_1}, + {1, arcs_55_2}, }; -static arc arcs_55_0[1] = { - {107, 1}, +static arc arcs_56_0[1] = { + {108, 1}, }; -static arc arcs_55_1[2] = { - {122, 0}, +static arc arcs_56_1[2] = { + {123, 0}, {0, 1}, }; -static state states_55[2] = { - {1, arcs_55_0}, - {2, arcs_55_1}, +static state states_56[2] = { + {1, arcs_56_0}, + {2, arcs_56_1}, }; -static arc arcs_56_0[10] = { - {123, 1}, +static arc arcs_57_0[10] = { {124, 1}, {125, 1}, {126, 1}, {127, 1}, {128, 1}, {129, 1}, - {101, 1}, - {120, 2}, - {130, 3}, + {130, 1}, + {102, 1}, + {121, 2}, + {131, 3}, }; -static arc arcs_56_1[1] = { +static arc arcs_57_1[1] = { {0, 1}, }; -static arc arcs_56_2[1] = { - {101, 1}, +static arc arcs_57_2[1] = { + {102, 1}, }; -static arc arcs_56_3[2] = { - {120, 1}, +static arc arcs_57_3[2] = { + {121, 1}, {0, 3}, }; -static state states_56[4] = { - {10, arcs_56_0}, - {1, arcs_56_1}, - {1, arcs_56_2}, - {2, arcs_56_3}, -}; -static arc arcs_57_0[1] = { - {33, 1}, -}; -static arc arcs_57_1[1] = { - {107, 2}, -}; -static arc arcs_57_2[1] = { - {0, 2}, -}; -static state states_57[3] = { - {1, arcs_57_0}, +static state states_57[4] = { + {10, arcs_57_0}, {1, arcs_57_1}, {1, arcs_57_2}, + {2, arcs_57_3}, }; static arc arcs_58_0[1] = { - {131, 1}, + {33, 1}, }; -static arc arcs_58_1[2] = { - {132, 0}, - {0, 1}, +static arc arcs_58_1[1] = { + {108, 2}, +}; +static arc arcs_58_2[1] = { + {0, 2}, }; -static state states_58[2] = { +static state states_58[3] = { {1, arcs_58_0}, - {2, arcs_58_1}, + {1, arcs_58_1}, + {1, arcs_58_2}, }; static arc arcs_59_0[1] = { - {133, 1}, + {132, 1}, }; static arc arcs_59_1[2] = { - {134, 0}, + {133, 0}, {0, 1}, }; static state states_59[2] = { @@ -1324,10 +1337,10 @@ static state states_59[2] = { {2, arcs_59_1}, }; static arc arcs_60_0[1] = { - {135, 1}, + {134, 1}, }; static arc arcs_60_1[2] = { - {136, 0}, + {135, 0}, {0, 1}, }; static state states_60[2] = { @@ -1335,23 +1348,22 @@ static state states_60[2] = { {2, arcs_60_1}, }; static arc arcs_61_0[1] = { - {137, 1}, + {136, 1}, }; -static arc arcs_61_1[3] = { - {138, 0}, - {139, 0}, +static arc arcs_61_1[2] = { + {137, 0}, {0, 1}, }; static state states_61[2] = { {1, arcs_61_0}, - {3, arcs_61_1}, + {2, arcs_61_1}, }; static arc arcs_62_0[1] = { - {140, 1}, + {138, 1}, }; static arc arcs_62_1[3] = { - {141, 0}, - {142, 0}, + {139, 0}, + {140, 0}, {0, 1}, }; static state states_62[2] = { @@ -1359,528 +1371,540 @@ static state states_62[2] = { {3, arcs_62_1}, }; static arc arcs_63_0[1] = { - {143, 1}, + {141, 1}, }; -static arc arcs_63_1[6] = { +static arc arcs_63_1[3] = { + {142, 0}, + {143, 0}, + {0, 1}, +}; +static state states_63[2] = { + {1, arcs_63_0}, + {3, arcs_63_1}, +}; +static arc arcs_64_0[1] = { + {144, 1}, +}; +static arc arcs_64_1[6] = { {33, 0}, {11, 0}, - {144, 0}, {145, 0}, {146, 0}, + {147, 0}, {0, 1}, }; -static state states_63[2] = { - {1, arcs_63_0}, - {6, arcs_63_1}, +static state states_64[2] = { + {1, arcs_64_0}, + {6, arcs_64_1}, }; -static arc arcs_64_0[4] = { - {141, 1}, +static arc arcs_65_0[4] = { {142, 1}, - {147, 1}, - {148, 2}, + {143, 1}, + {148, 1}, + {149, 2}, }; -static arc arcs_64_1[1] = { - {143, 2}, +static arc arcs_65_1[1] = { + {144, 2}, }; -static arc arcs_64_2[1] = { +static arc arcs_65_2[1] = { {0, 2}, }; -static state states_64[3] = { - {4, arcs_64_0}, - {1, arcs_64_1}, - {1, arcs_64_2}, +static state states_65[3] = { + {4, arcs_65_0}, + {1, arcs_65_1}, + {1, arcs_65_2}, }; -static arc arcs_65_0[1] = { - {149, 1}, +static arc arcs_66_0[1] = { + {150, 1}, }; -static arc arcs_65_1[2] = { +static arc arcs_66_1[2] = { {34, 2}, {0, 1}, }; -static arc arcs_65_2[1] = { - {143, 3}, +static arc arcs_66_2[1] = { + {144, 3}, }; -static arc arcs_65_3[1] = { +static arc arcs_66_3[1] = { {0, 3}, }; -static state states_65[4] = { - {1, arcs_65_0}, - {2, arcs_65_1}, - {1, arcs_65_2}, - {1, arcs_65_3}, -}; -static arc arcs_66_0[2] = { - {150, 1}, - {151, 2}, +static state states_66[4] = { + {1, arcs_66_0}, + {2, arcs_66_1}, + {1, arcs_66_2}, + {1, arcs_66_3}, }; -static arc arcs_66_1[1] = { - {151, 2}, +static arc arcs_67_0[2] = { + {151, 1}, + {152, 2}, }; -static arc arcs_66_2[2] = { +static arc arcs_67_1[1] = { {152, 2}, +}; +static arc arcs_67_2[2] = { + {153, 2}, {0, 2}, }; -static state states_66[3] = { - {2, arcs_66_0}, - {1, arcs_66_1}, - {2, arcs_66_2}, +static state states_67[3] = { + {2, arcs_67_0}, + {1, arcs_67_1}, + {2, arcs_67_2}, }; -static arc arcs_67_0[10] = { +static arc arcs_68_0[10] = { {13, 1}, - {154, 2}, - {156, 3}, + {155, 2}, + {157, 3}, {23, 4}, - {159, 4}, - {160, 5}, - {82, 4}, - {161, 4}, + {160, 4}, + {161, 5}, + {83, 4}, {162, 4}, {163, 4}, + {164, 4}, }; -static arc arcs_67_1[3] = { - {49, 6}, - {153, 6}, +static arc arcs_68_1[3] = { + {50, 6}, + {154, 6}, {15, 4}, }; -static arc arcs_67_2[2] = { - {153, 7}, - {155, 4}, +static arc arcs_68_2[2] = { + {154, 7}, + {156, 4}, }; -static arc arcs_67_3[2] = { - {157, 8}, - {158, 4}, +static arc arcs_68_3[2] = { + {158, 8}, + {159, 4}, }; -static arc arcs_67_4[1] = { +static arc arcs_68_4[1] = { {0, 4}, }; -static arc arcs_67_5[2] = { - {160, 5}, +static arc arcs_68_5[2] = { + {161, 5}, {0, 5}, }; -static arc arcs_67_6[1] = { +static arc arcs_68_6[1] = { {15, 4}, }; -static arc arcs_67_7[1] = { - {155, 4}, +static arc arcs_68_7[1] = { + {156, 4}, }; -static arc arcs_67_8[1] = { - {158, 4}, +static arc arcs_68_8[1] = { + {159, 4}, }; -static state states_67[9] = { - {10, arcs_67_0}, - {3, arcs_67_1}, - {2, arcs_67_2}, - {2, arcs_67_3}, - {1, arcs_67_4}, - {2, arcs_67_5}, - {1, arcs_67_6}, - {1, arcs_67_7}, - {1, arcs_67_8}, -}; -static arc arcs_68_0[2] = { +static state states_68[9] = { + {10, arcs_68_0}, + {3, arcs_68_1}, + {2, arcs_68_2}, + {2, arcs_68_3}, + {1, arcs_68_4}, + {2, arcs_68_5}, + {1, arcs_68_6}, + {1, arcs_68_7}, + {1, arcs_68_8}, +}; +static arc arcs_69_0[2] = { {26, 1}, - {50, 1}, + {51, 1}, }; -static arc arcs_68_1[3] = { - {164, 2}, +static arc arcs_69_1[3] = { + {165, 2}, {32, 3}, {0, 1}, }; -static arc arcs_68_2[1] = { +static arc arcs_69_2[1] = { {0, 2}, }; -static arc arcs_68_3[3] = { +static arc arcs_69_3[3] = { {26, 4}, - {50, 4}, + {51, 4}, {0, 3}, }; -static arc arcs_68_4[2] = { +static arc arcs_69_4[2] = { {32, 3}, {0, 4}, }; -static state states_68[5] = { - {2, arcs_68_0}, - {3, arcs_68_1}, - {1, arcs_68_2}, - {3, arcs_68_3}, - {2, arcs_68_4}, +static state states_69[5] = { + {2, arcs_69_0}, + {3, arcs_69_1}, + {1, arcs_69_2}, + {3, arcs_69_3}, + {2, arcs_69_4}, }; -static arc arcs_69_0[3] = { +static arc arcs_70_0[3] = { {13, 1}, - {154, 2}, - {81, 3}, + {155, 2}, + {82, 3}, }; -static arc arcs_69_1[2] = { +static arc arcs_70_1[2] = { {14, 4}, {15, 5}, }; -static arc arcs_69_2[1] = { - {165, 6}, +static arc arcs_70_2[1] = { + {166, 6}, }; -static arc arcs_69_3[1] = { +static arc arcs_70_3[1] = { {23, 5}, }; -static arc arcs_69_4[1] = { +static arc arcs_70_4[1] = { {15, 5}, }; -static arc arcs_69_5[1] = { +static arc arcs_70_5[1] = { {0, 5}, }; -static arc arcs_69_6[1] = { - {155, 5}, +static arc arcs_70_6[1] = { + {156, 5}, }; -static state states_69[7] = { - {3, arcs_69_0}, - {2, arcs_69_1}, - {1, arcs_69_2}, - {1, arcs_69_3}, - {1, arcs_69_4}, - {1, arcs_69_5}, - {1, arcs_69_6}, +static state states_70[7] = { + {3, arcs_70_0}, + {2, arcs_70_1}, + {1, arcs_70_2}, + {1, arcs_70_3}, + {1, arcs_70_4}, + {1, arcs_70_5}, + {1, arcs_70_6}, }; -static arc arcs_70_0[1] = { - {166, 1}, +static arc arcs_71_0[1] = { + {167, 1}, }; -static arc arcs_70_1[2] = { +static arc arcs_71_1[2] = { {32, 2}, {0, 1}, }; -static arc arcs_70_2[2] = { - {166, 1}, +static arc arcs_71_2[2] = { + {167, 1}, {0, 2}, }; -static state states_70[3] = { - {1, arcs_70_0}, - {2, arcs_70_1}, - {2, arcs_70_2}, +static state states_71[3] = { + {1, arcs_71_0}, + {2, arcs_71_1}, + {2, arcs_71_2}, }; -static arc arcs_71_0[2] = { +static arc arcs_72_0[2] = { {26, 1}, {27, 2}, }; -static arc arcs_71_1[2] = { +static arc arcs_72_1[2] = { {27, 2}, {0, 1}, }; -static arc arcs_71_2[3] = { +static arc arcs_72_2[3] = { {26, 3}, - {167, 4}, + {168, 4}, {0, 2}, }; -static arc arcs_71_3[2] = { - {167, 4}, +static arc arcs_72_3[2] = { + {168, 4}, {0, 3}, }; -static arc arcs_71_4[1] = { +static arc arcs_72_4[1] = { {0, 4}, }; -static state states_71[5] = { - {2, arcs_71_0}, - {2, arcs_71_1}, - {3, arcs_71_2}, - {2, arcs_71_3}, - {1, arcs_71_4}, +static state states_72[5] = { + {2, arcs_72_0}, + {2, arcs_72_1}, + {3, arcs_72_2}, + {2, arcs_72_3}, + {1, arcs_72_4}, }; -static arc arcs_72_0[1] = { +static arc arcs_73_0[1] = { {27, 1}, }; -static arc arcs_72_1[2] = { +static arc arcs_73_1[2] = { {26, 2}, {0, 1}, }; -static arc arcs_72_2[1] = { +static arc arcs_73_2[1] = { {0, 2}, }; -static state states_72[3] = { - {1, arcs_72_0}, - {2, arcs_72_1}, - {1, arcs_72_2}, +static state states_73[3] = { + {1, arcs_73_0}, + {2, arcs_73_1}, + {1, arcs_73_2}, }; -static arc arcs_73_0[2] = { - {107, 1}, - {50, 1}, +static arc arcs_74_0[2] = { + {108, 1}, + {51, 1}, }; -static arc arcs_73_1[2] = { +static arc arcs_74_1[2] = { {32, 2}, {0, 1}, }; -static arc arcs_73_2[3] = { - {107, 1}, - {50, 1}, +static arc arcs_74_2[3] = { + {108, 1}, + {51, 1}, {0, 2}, }; -static state states_73[3] = { - {2, arcs_73_0}, - {2, arcs_73_1}, - {3, arcs_73_2}, +static state states_74[3] = { + {2, arcs_74_0}, + {2, arcs_74_1}, + {3, arcs_74_2}, }; -static arc arcs_74_0[1] = { +static arc arcs_75_0[1] = { {26, 1}, }; -static arc arcs_74_1[2] = { +static arc arcs_75_1[2] = { {32, 2}, {0, 1}, }; -static arc arcs_74_2[2] = { +static arc arcs_75_2[2] = { {26, 1}, {0, 2}, }; -static state states_74[3] = { - {1, arcs_74_0}, - {2, arcs_74_1}, - {2, arcs_74_2}, +static state states_75[3] = { + {1, arcs_75_0}, + {2, arcs_75_1}, + {2, arcs_75_2}, }; -static arc arcs_75_0[3] = { +static arc arcs_76_0[3] = { {26, 1}, {34, 2}, - {50, 3}, + {51, 3}, }; -static arc arcs_75_1[4] = { +static arc arcs_76_1[4] = { {27, 4}, - {164, 5}, + {165, 5}, {32, 6}, {0, 1}, }; -static arc arcs_75_2[1] = { - {107, 7}, +static arc arcs_76_2[1] = { + {108, 7}, }; -static arc arcs_75_3[3] = { - {164, 5}, +static arc arcs_76_3[3] = { + {165, 5}, {32, 6}, {0, 3}, }; -static arc arcs_75_4[1] = { +static arc arcs_76_4[1] = { {26, 7}, }; -static arc arcs_75_5[1] = { +static arc arcs_76_5[1] = { {0, 5}, }; -static arc arcs_75_6[3] = { +static arc arcs_76_6[3] = { {26, 8}, - {50, 8}, + {51, 8}, {0, 6}, }; -static arc arcs_75_7[3] = { - {164, 5}, +static arc arcs_76_7[3] = { + {165, 5}, {32, 9}, {0, 7}, }; -static arc arcs_75_8[2] = { +static arc arcs_76_8[2] = { {32, 6}, {0, 8}, }; -static arc arcs_75_9[3] = { +static arc arcs_76_9[3] = { {26, 10}, {34, 11}, {0, 9}, }; -static arc arcs_75_10[1] = { +static arc arcs_76_10[1] = { {27, 12}, }; -static arc arcs_75_11[1] = { - {107, 13}, +static arc arcs_76_11[1] = { + {108, 13}, }; -static arc arcs_75_12[1] = { +static arc arcs_76_12[1] = { {26, 13}, }; -static arc arcs_75_13[2] = { +static arc arcs_76_13[2] = { {32, 9}, {0, 13}, }; -static state states_75[14] = { - {3, arcs_75_0}, - {4, arcs_75_1}, - {1, arcs_75_2}, - {3, arcs_75_3}, - {1, arcs_75_4}, - {1, arcs_75_5}, - {3, arcs_75_6}, - {3, arcs_75_7}, - {2, arcs_75_8}, - {3, arcs_75_9}, - {1, arcs_75_10}, - {1, arcs_75_11}, - {1, arcs_75_12}, - {2, arcs_75_13}, -}; -static arc arcs_76_0[1] = { - {168, 1}, -}; -static arc arcs_76_1[1] = { +static state states_76[14] = { + {3, arcs_76_0}, + {4, arcs_76_1}, + {1, arcs_76_2}, + {3, arcs_76_3}, + {1, arcs_76_4}, + {1, arcs_76_5}, + {3, arcs_76_6}, + {3, arcs_76_7}, + {2, arcs_76_8}, + {3, arcs_76_9}, + {1, arcs_76_10}, + {1, arcs_76_11}, + {1, arcs_76_12}, + {2, arcs_76_13}, +}; +static arc arcs_77_0[1] = { + {169, 1}, +}; +static arc arcs_77_1[1] = { {23, 2}, }; -static arc arcs_76_2[2] = { +static arc arcs_77_2[2] = { {13, 3}, {27, 4}, }; -static arc arcs_76_3[2] = { +static arc arcs_77_3[2] = { {14, 5}, {15, 6}, }; -static arc arcs_76_4[1] = { +static arc arcs_77_4[1] = { {28, 7}, }; -static arc arcs_76_5[1] = { +static arc arcs_77_5[1] = { {15, 6}, }; -static arc arcs_76_6[1] = { +static arc arcs_77_6[1] = { {27, 4}, }; -static arc arcs_76_7[1] = { +static arc arcs_77_7[1] = { {0, 7}, }; -static state states_76[8] = { - {1, arcs_76_0}, - {1, arcs_76_1}, - {2, arcs_76_2}, - {2, arcs_76_3}, - {1, arcs_76_4}, - {1, arcs_76_5}, - {1, arcs_76_6}, - {1, arcs_76_7}, +static state states_77[8] = { + {1, arcs_77_0}, + {1, arcs_77_1}, + {2, arcs_77_2}, + {2, arcs_77_3}, + {1, arcs_77_4}, + {1, arcs_77_5}, + {1, arcs_77_6}, + {1, arcs_77_7}, }; -static arc arcs_77_0[1] = { - {169, 1}, +static arc arcs_78_0[1] = { + {170, 1}, }; -static arc arcs_77_1[2] = { +static arc arcs_78_1[2] = { {32, 2}, {0, 1}, }; -static arc arcs_77_2[2] = { - {169, 1}, +static arc arcs_78_2[2] = { + {170, 1}, {0, 2}, }; -static state states_77[3] = { - {1, arcs_77_0}, - {2, arcs_77_1}, - {2, arcs_77_2}, +static state states_78[3] = { + {1, arcs_78_0}, + {2, arcs_78_1}, + {2, arcs_78_2}, }; -static arc arcs_78_0[3] = { +static arc arcs_79_0[3] = { {26, 1}, {34, 2}, {33, 2}, }; -static arc arcs_78_1[3] = { - {164, 3}, +static arc arcs_79_1[3] = { + {165, 3}, {31, 2}, {0, 1}, }; -static arc arcs_78_2[1] = { +static arc arcs_79_2[1] = { {26, 3}, }; -static arc arcs_78_3[1] = { +static arc arcs_79_3[1] = { {0, 3}, }; -static state states_78[4] = { - {3, arcs_78_0}, - {3, arcs_78_1}, - {1, arcs_78_2}, - {1, arcs_78_3}, +static state states_79[4] = { + {3, arcs_79_0}, + {3, arcs_79_1}, + {1, arcs_79_2}, + {1, arcs_79_3}, }; -static arc arcs_79_0[2] = { - {164, 1}, - {171, 1}, +static arc arcs_80_0[2] = { + {165, 1}, + {172, 1}, }; -static arc arcs_79_1[1] = { +static arc arcs_80_1[1] = { {0, 1}, }; -static state states_79[2] = { - {2, arcs_79_0}, - {1, arcs_79_1}, +static state states_80[2] = { + {2, arcs_80_0}, + {1, arcs_80_1}, }; -static arc arcs_80_0[1] = { - {100, 1}, +static arc arcs_81_0[1] = { + {101, 1}, }; -static arc arcs_80_1[1] = { - {65, 2}, +static arc arcs_81_1[1] = { + {66, 2}, }; -static arc arcs_80_2[1] = { - {101, 3}, +static arc arcs_81_2[1] = { + {102, 3}, }; -static arc arcs_80_3[1] = { - {111, 4}, +static arc arcs_81_3[1] = { + {112, 4}, }; -static arc arcs_80_4[2] = { - {170, 5}, +static arc arcs_81_4[2] = { + {171, 5}, {0, 4}, }; -static arc arcs_80_5[1] = { +static arc arcs_81_5[1] = { {0, 5}, }; -static state states_80[6] = { - {1, arcs_80_0}, - {1, arcs_80_1}, - {1, arcs_80_2}, - {1, arcs_80_3}, - {2, arcs_80_4}, - {1, arcs_80_5}, +static state states_81[6] = { + {1, arcs_81_0}, + {1, arcs_81_1}, + {1, arcs_81_2}, + {1, arcs_81_3}, + {2, arcs_81_4}, + {1, arcs_81_5}, }; -static arc arcs_81_0[1] = { - {96, 1}, +static arc arcs_82_0[1] = { + {97, 1}, }; -static arc arcs_81_1[1] = { - {113, 2}, +static arc arcs_82_1[1] = { + {114, 2}, }; -static arc arcs_81_2[2] = { - {170, 3}, +static arc arcs_82_2[2] = { + {171, 3}, {0, 2}, }; -static arc arcs_81_3[1] = { +static arc arcs_82_3[1] = { {0, 3}, }; -static state states_81[4] = { - {1, arcs_81_0}, - {1, arcs_81_1}, - {2, arcs_81_2}, - {1, arcs_81_3}, +static state states_82[4] = { + {1, arcs_82_0}, + {1, arcs_82_1}, + {2, arcs_82_2}, + {1, arcs_82_3}, }; -static arc arcs_82_0[1] = { +static arc arcs_83_0[1] = { {23, 1}, }; -static arc arcs_82_1[1] = { +static arc arcs_83_1[1] = { {0, 1}, }; -static state states_82[2] = { - {1, arcs_82_0}, - {1, arcs_82_1}, +static state states_83[2] = { + {1, arcs_83_0}, + {1, arcs_83_1}, }; -static arc arcs_83_0[1] = { - {173, 1}, +static arc arcs_84_0[1] = { + {174, 1}, }; -static arc arcs_83_1[2] = { - {174, 2}, +static arc arcs_84_1[2] = { + {175, 2}, {0, 1}, }; -static arc arcs_83_2[1] = { +static arc arcs_84_2[1] = { {0, 2}, }; -static state states_83[3] = { - {1, arcs_83_0}, - {2, arcs_83_1}, - {1, arcs_83_2}, +static state states_84[3] = { + {1, arcs_84_0}, + {2, arcs_84_1}, + {1, arcs_84_2}, }; -static arc arcs_84_0[2] = { - {76, 1}, +static arc arcs_85_0[2] = { + {77, 1}, {9, 2}, }; -static arc arcs_84_1[1] = { +static arc arcs_85_1[1] = { {26, 2}, }; -static arc arcs_84_2[1] = { +static arc arcs_85_2[1] = { {0, 2}, }; -static state states_84[3] = { - {2, arcs_84_0}, - {1, arcs_84_1}, - {1, arcs_84_2}, +static state states_85[3] = { + {2, arcs_85_0}, + {1, arcs_85_1}, + {1, arcs_85_2}, }; -static dfa dfas[85] = { +static dfa dfas[86] = { {256, "single_input", 0, 3, states_0, - "\004\050\340\000\002\000\000\000\005\237\204\003\131\002\010\001\000\140\110\224\017\041"}, + "\004\050\340\000\002\000\000\000\012\076\011\007\262\004\020\002\000\300\220\050\037\102"}, {257, "file_input", 0, 2, states_1, - "\204\050\340\000\002\000\000\000\005\237\204\003\131\002\010\001\000\140\110\224\017\041"}, + "\204\050\340\000\002\000\000\000\012\076\011\007\262\004\020\002\000\300\220\050\037\102"}, {258, "eval_input", 0, 3, states_2, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\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, @@ -1902,170 +1926,172 @@ static dfa dfas[85] = { {268, "vfpdef", 0, 2, states_12, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {269, "stmt", 0, 2, states_13, - "\000\050\340\000\002\000\000\000\005\237\204\003\131\002\010\001\000\140\110\224\017\041"}, + "\000\050\340\000\002\000\000\000\012\076\011\007\262\004\020\002\000\300\220\050\037\102"}, {270, "simple_stmt", 0, 4, states_14, - "\000\040\200\000\002\000\000\000\005\237\204\003\000\000\010\001\000\140\110\224\017\040"}, + "\000\040\200\000\002\000\000\000\012\076\011\007\000\000\020\002\000\300\220\050\037\100"}, {271, "small_stmt", 0, 2, states_15, - "\000\040\200\000\002\000\000\000\005\237\204\003\000\000\010\001\000\140\110\224\017\040"}, + "\000\040\200\000\002\000\000\000\012\076\011\007\000\000\020\002\000\300\220\050\037\100"}, {272, "expr_stmt", 0, 6, states_16, - "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {273, "testlist_star_expr", 0, 3, states_17, - "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {274, "augassign", 0, 2, states_18, - "\000\000\000\000\000\000\370\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {275, "del_stmt", 0, 3, states_19, - "\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {276, "pass_stmt", 0, 2, states_20, - "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {277, "flow_stmt", 0, 2, states_21, - "\000\000\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\040"}, - {278, "break_stmt", 0, 2, states_22, - "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"}, - {279, "continue_stmt", 0, 2, states_23, + "\000\040\200\000\002\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {273, "annassign", 0, 5, states_17, + "\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {274, "testlist_star_expr", 0, 3, states_18, + "\000\040\200\000\002\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {275, "augassign", 0, 2, states_19, + "\000\000\000\000\000\000\360\377\001\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {276, "del_stmt", 0, 3, states_20, + "\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {277, "pass_stmt", 0, 2, states_21, + "\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {278, "flow_stmt", 0, 2, states_22, + "\000\000\000\000\000\000\000\000\000\036\000\000\000\000\000\000\000\000\000\000\000\100"}, + {279, "break_stmt", 0, 2, states_23, "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000"}, - {280, "return_stmt", 0, 3, states_24, + {280, "continue_stmt", 0, 2, states_24, "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"}, - {281, "yield_stmt", 0, 2, states_25, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"}, - {282, "raise_stmt", 0, 5, states_26, + {281, "return_stmt", 0, 3, states_25, "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"}, - {283, "import_stmt", 0, 2, states_27, - "\000\000\000\000\000\000\000\000\000\220\000\000\000\000\000\000\000\000\000\000\000\000"}, - {284, "import_name", 0, 3, states_28, - "\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"}, - {285, "import_from", 0, 8, states_29, + {282, "yield_stmt", 0, 2, states_26, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"}, + {283, "raise_stmt", 0, 5, states_27, "\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"}, - {286, "import_as_name", 0, 4, states_30, + {284, "import_stmt", 0, 2, states_28, + "\000\000\000\000\000\000\000\000\000\040\001\000\000\000\000\000\000\000\000\000\000\000"}, + {285, "import_name", 0, 3, states_29, + "\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"}, + {286, "import_from", 0, 8, states_30, + "\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"}, + {287, "import_as_name", 0, 4, states_31, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {287, "dotted_as_name", 0, 4, states_31, + {288, "dotted_as_name", 0, 4, states_32, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {288, "import_as_names", 0, 3, states_32, + {289, "import_as_names", 0, 3, states_33, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {289, "dotted_as_names", 0, 2, states_33, + {290, "dotted_as_names", 0, 2, states_34, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {290, "dotted_name", 0, 2, states_34, + {291, "dotted_name", 0, 2, states_35, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {291, "global_stmt", 0, 3, states_35, - "\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000"}, - {292, "nonlocal_stmt", 0, 3, states_36, + {292, "global_stmt", 0, 3, states_36, "\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000"}, - {293, "assert_stmt", 0, 5, states_37, + {293, "nonlocal_stmt", 0, 3, states_37, "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000"}, - {294, "compound_stmt", 0, 2, states_38, - "\000\010\140\000\000\000\000\000\000\000\000\000\131\002\000\000\000\000\000\000\000\001"}, - {295, "async_stmt", 0, 3, states_39, + {294, "assert_stmt", 0, 5, states_38, + "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000"}, + {295, "compound_stmt", 0, 2, states_39, + "\000\010\140\000\000\000\000\000\000\000\000\000\262\004\000\000\000\000\000\000\000\002"}, + {296, "async_stmt", 0, 3, states_40, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {296, "if_stmt", 0, 8, 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, "while_stmt", 0, 8, states_41, - "\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, - {298, "for_stmt", 0, 10, states_42, + {297, "if_stmt", 0, 8, states_41, + "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, + {298, "while_stmt", 0, 8, states_42, "\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, - {299, "try_stmt", 0, 13, states_43, - "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, - {300, "with_stmt", 0, 5, states_44, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, - {301, "with_item", 0, 4, states_45, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {302, "except_clause", 0, 5, states_46, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000"}, - {303, "suite", 0, 5, states_47, - "\004\040\200\000\002\000\000\000\005\237\204\003\000\000\010\001\000\140\110\224\017\040"}, - {304, "test", 0, 6, states_48, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {305, "test_nocond", 0, 2, states_49, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {306, "lambdef", 0, 5, states_50, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"}, - {307, "lambdef_nocond", 0, 5, states_51, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"}, - {308, "or_test", 0, 2, states_52, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\001\000\140\110\224\017\000"}, - {309, "and_test", 0, 2, states_53, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\001\000\140\110\224\017\000"}, - {310, "not_test", 0, 3, states_54, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\001\000\140\110\224\017\000"}, - {311, "comparison", 0, 2, states_55, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {312, "comp_op", 0, 4, states_56, - "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\371\007\000\000\000\000\000"}, - {313, "star_expr", 0, 3, states_57, + {299, "for_stmt", 0, 10, states_43, + "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, + {300, "try_stmt", 0, 13, states_44, + "\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"}, + {301, "with_stmt", 0, 5, states_45, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000"}, + {302, "with_item", 0, 4, states_46, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {303, "except_clause", 0, 5, states_47, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"}, + {304, "suite", 0, 5, states_48, + "\004\040\200\000\002\000\000\000\012\076\011\007\000\000\020\002\000\300\220\050\037\100"}, + {305, "test", 0, 6, states_49, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {306, "test_nocond", 0, 2, states_50, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {307, "lambdef", 0, 5, states_51, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000"}, + {308, "lambdef_nocond", 0, 5, states_52, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000"}, + {309, "or_test", 0, 2, states_53, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\002\000\300\220\050\037\000"}, + {310, "and_test", 0, 2, states_54, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\002\000\300\220\050\037\000"}, + {311, "not_test", 0, 3, states_55, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\002\000\300\220\050\037\000"}, + {312, "comparison", 0, 2, states_56, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {313, "comp_op", 0, 4, states_57, + "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\362\017\000\000\000\000\000"}, + {314, "star_expr", 0, 3, states_58, "\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {314, "expr", 0, 2, states_58, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {315, "xor_expr", 0, 2, states_59, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {316, "and_expr", 0, 2, states_60, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {317, "shift_expr", 0, 2, states_61, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {318, "arith_expr", 0, 2, states_62, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {319, "term", 0, 2, states_63, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {320, "factor", 0, 3, states_64, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {321, "power", 0, 4, states_65, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\100\224\017\000"}, - {322, "atom_expr", 0, 3, states_66, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\100\224\017\000"}, - {323, "atom", 0, 9, states_67, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\224\017\000"}, - {324, "testlist_comp", 0, 5, states_68, - "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {325, "trailer", 0, 7, states_69, - "\000\040\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\004\000\000"}, - {326, "subscriptlist", 0, 3, states_70, - "\000\040\200\010\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {327, "subscript", 0, 5, states_71, - "\000\040\200\010\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {328, "sliceop", 0, 3, states_72, + {315, "expr", 0, 2, states_59, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {316, "xor_expr", 0, 2, states_60, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {317, "and_expr", 0, 2, states_61, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {318, "shift_expr", 0, 2, states_62, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {319, "arith_expr", 0, 2, states_63, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {320, "term", 0, 2, states_64, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {321, "factor", 0, 3, states_65, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {322, "power", 0, 4, states_66, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\200\050\037\000"}, + {323, "atom_expr", 0, 3, states_67, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\200\050\037\000"}, + {324, "atom", 0, 9, states_68, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\050\037\000"}, + {325, "testlist_comp", 0, 5, states_69, + "\000\040\200\000\002\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {326, "trailer", 0, 7, states_70, + "\000\040\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\010\000\000"}, + {327, "subscriptlist", 0, 3, states_71, + "\000\040\200\010\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {328, "subscript", 0, 5, states_72, + "\000\040\200\010\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {329, "sliceop", 0, 3, states_73, "\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {329, "exprlist", 0, 3, states_73, - "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, - {330, "testlist", 0, 3, states_74, - "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {331, "dictorsetmaker", 0, 14, states_75, - "\000\040\200\000\006\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {332, "classdef", 0, 8, states_76, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, - {333, "arglist", 0, 3, states_77, - "\000\040\200\000\006\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {334, "argument", 0, 4, states_78, - "\000\040\200\000\006\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, - {335, "comp_iter", 0, 2, states_79, - "\000\000\000\000\000\000\000\000\000\000\000\000\021\000\000\000\000\000\000\000\000\000"}, - {336, "comp_for", 0, 6, states_80, - "\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, - {337, "comp_if", 0, 4, states_81, - "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"}, - {338, "encoding_decl", 0, 2, states_82, + {330, "exprlist", 0, 3, states_74, + "\000\040\200\000\002\000\000\000\000\000\010\000\000\000\000\000\000\300\220\050\037\000"}, + {331, "testlist", 0, 3, states_75, + "\000\040\200\000\000\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {332, "dictorsetmaker", 0, 14, states_76, + "\000\040\200\000\006\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {333, "classdef", 0, 8, states_77, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002"}, + {334, "arglist", 0, 3, states_78, + "\000\040\200\000\006\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {335, "argument", 0, 4, states_79, + "\000\040\200\000\006\000\000\000\000\000\010\000\000\000\020\002\000\300\220\050\037\000"}, + {336, "comp_iter", 0, 2, states_80, + "\000\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"}, + {337, "comp_for", 0, 6, states_81, + "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, + {338, "comp_if", 0, 4, states_82, + "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, + {339, "encoding_decl", 0, 2, states_83, "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {339, "yield_expr", 0, 3, states_83, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"}, - {340, "yield_arg", 0, 3, states_84, - "\000\040\200\000\000\000\000\000\000\020\004\000\000\000\010\001\000\140\110\224\017\000"}, + {340, "yield_expr", 0, 3, states_84, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"}, + {341, "yield_arg", 0, 3, states_85, + "\000\040\200\000\000\000\000\000\000\040\010\000\000\000\020\002\000\300\220\050\037\000"}, }; -static label labels[175] = { +static label labels[176] = { {0, "EMPTY"}, {256, 0}, {4, 0}, {270, 0}, - {294, 0}, + {295, 0}, {257, 0}, {269, 0}, {0, 0}, {258, 0}, - {330, 0}, + {331, 0}, {259, 0}, {49, 0}, - {290, 0}, + {291, 0}, {7, 0}, - {333, 0}, + {334, 0}, {8, 0}, {260, 0}, {261, 0}, - {332, 0}, + {333, 0}, {263, 0}, {262, 0}, {55, 0}, @@ -2073,9 +2099,9 @@ static label labels[175] = { {1, 0}, {264, 0}, {51, 0}, - {304, 0}, + {305, 0}, {11, 0}, - {303, 0}, + {304, 0}, {265, 0}, {266, 0}, {22, 0}, @@ -2087,17 +2113,18 @@ static label labels[175] = { {271, 0}, {13, 0}, {272, 0}, - {275, 0}, {276, 0}, {277, 0}, - {283, 0}, - {291, 0}, + {278, 0}, + {284, 0}, {292, 0}, {293, 0}, - {273, 0}, + {294, 0}, {274, 0}, - {339, 0}, - {313, 0}, + {273, 0}, + {275, 0}, + {340, 0}, + {314, 0}, {36, 0}, {37, 0}, {38, 0}, @@ -2112,37 +2139,37 @@ static label labels[175] = { {46, 0}, {48, 0}, {1, "del"}, - {329, 0}, + {330, 0}, {1, "pass"}, - {278, 0}, {279, 0}, {280, 0}, - {282, 0}, {281, 0}, + {283, 0}, + {282, 0}, {1, "break"}, {1, "continue"}, {1, "return"}, {1, "raise"}, {1, "from"}, - {284, 0}, {285, 0}, + {286, 0}, {1, "import"}, - {289, 0}, + {290, 0}, {23, 0}, {52, 0}, - {288, 0}, - {286, 0}, - {1, "as"}, + {289, 0}, {287, 0}, + {1, "as"}, + {288, 0}, {1, "global"}, {1, "nonlocal"}, {1, "assert"}, - {296, 0}, {297, 0}, {298, 0}, {299, 0}, {300, 0}, - {295, 0}, + {301, 0}, + {296, 0}, {1, "if"}, {1, "elif"}, {1, "else"}, @@ -2150,26 +2177,26 @@ static label labels[175] = { {1, "for"}, {1, "in"}, {1, "try"}, - {302, 0}, + {303, 0}, {1, "finally"}, {1, "with"}, - {301, 0}, - {314, 0}, + {302, 0}, + {315, 0}, {1, "except"}, {5, 0}, {6, 0}, - {308, 0}, - {306, 0}, - {305, 0}, + {309, 0}, {307, 0}, + {306, 0}, + {308, 0}, {1, "lambda"}, - {309, 0}, - {1, "or"}, {310, 0}, + {1, "or"}, + {311, 0}, {1, "and"}, {1, "not"}, - {311, 0}, {312, 0}, + {313, 0}, {20, 0}, {21, 0}, {27, 0}, @@ -2178,54 +2205,54 @@ static label labels[175] = { {28, 0}, {28, 0}, {1, "is"}, - {315, 0}, - {18, 0}, {316, 0}, - {32, 0}, + {18, 0}, {317, 0}, - {19, 0}, + {32, 0}, {318, 0}, + {19, 0}, + {319, 0}, {33, 0}, {34, 0}, - {319, 0}, + {320, 0}, {14, 0}, {15, 0}, - {320, 0}, + {321, 0}, {17, 0}, {24, 0}, {47, 0}, {31, 0}, - {321, 0}, {322, 0}, - {54, 0}, {323, 0}, - {325, 0}, + {54, 0}, {324, 0}, + {326, 0}, + {325, 0}, {9, 0}, {10, 0}, {25, 0}, - {331, 0}, + {332, 0}, {26, 0}, {2, 0}, {3, 0}, {1, "None"}, {1, "True"}, {1, "False"}, - {336, 0}, - {326, 0}, + {337, 0}, {327, 0}, {328, 0}, + {329, 0}, {1, "class"}, - {334, 0}, {335, 0}, - {337, 0}, + {336, 0}, {338, 0}, + {339, 0}, {1, "yield"}, - {340, 0}, + {341, 0}, }; grammar _PyParser_Grammar = { - 85, + 86, dfas, - {175, labels}, + {176, labels}, 256 }; diff --git a/Python/importlib_external.h b/Python/importlib_external.h index ce51981..7ffb25e 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -242,7 +242,7 @@ const unsigned char _Py_M__importlib_external[] = { 101,95,97,116,111,109,105,99,106,0,0,0,115,26,0,0, 0,0,5,16,1,6,1,26,1,2,3,14,1,20,1,16, 1,14,1,2,1,14,1,14,1,6,1,114,58,0,0,0, - 105,45,13,0,0,233,2,0,0,0,114,15,0,0,0,115, + 105,47,13,0,0,233,2,0,0,0,114,15,0,0,0,115, 2,0,0,0,13,10,90,11,95,95,112,121,99,97,99,104, 101,95,95,122,4,111,112,116,45,122,3,46,112,121,122,4, 46,112,121,99,78,41,1,218,12,111,112,116,105,109,105,122, @@ -346,7 +346,7 @@ const unsigned char _Py_M__importlib_external[] = { 103,90,15,97,108,109,111,115,116,95,102,105,108,101,110,97, 109,101,114,4,0,0,0,114,4,0,0,0,114,6,0,0, 0,218,17,99,97,99,104,101,95,102,114,111,109,95,115,111, - 117,114,99,101,1,1,0,0,115,48,0,0,0,0,18,8, + 117,114,99,101,3,1,0,0,115,48,0,0,0,0,18,8, 1,6,1,6,1,8,1,4,1,8,1,12,1,10,1,12, 1,16,1,8,1,8,1,8,1,24,1,8,1,12,1,6, 2,8,1,8,1,8,1,8,1,14,1,14,1,114,83,0, @@ -420,7 +420,7 @@ const unsigned char _Py_M__importlib_external[] = { 112,116,95,108,101,118,101,108,90,13,98,97,115,101,95,102, 105,108,101,110,97,109,101,114,4,0,0,0,114,4,0,0, 0,114,6,0,0,0,218,17,115,111,117,114,99,101,95,102, - 114,111,109,95,99,97,99,104,101,46,1,0,0,115,46,0, + 114,111,109,95,99,97,99,104,101,48,1,0,0,115,46,0, 0,0,0,9,12,1,8,1,10,1,12,1,12,1,8,1, 6,1,10,1,10,1,8,1,6,1,10,1,8,1,16,1, 10,1,6,1,8,1,16,1,8,1,6,1,8,1,14,1, @@ -456,7 +456,7 @@ const unsigned char _Py_M__importlib_external[] = { 115,105,111,110,218,11,115,111,117,114,99,101,95,112,97,116, 104,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, 218,15,95,103,101,116,95,115,111,117,114,99,101,102,105,108, - 101,80,1,0,0,115,20,0,0,0,0,7,12,1,4,1, + 101,82,1,0,0,115,20,0,0,0,0,7,12,1,4,1, 16,1,26,1,4,1,2,1,12,1,18,1,18,1,114,95, 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, 11,0,0,0,67,0,0,0,115,74,0,0,0,124,0,106, @@ -469,7 +469,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,114,83,0,0,0,114,70,0,0,0,114,78,0,0, 0,41,1,218,8,102,105,108,101,110,97,109,101,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,218,11,95,103, - 101,116,95,99,97,99,104,101,100,99,1,0,0,115,16,0, + 101,116,95,99,97,99,104,101,100,101,1,0,0,115,16,0, 0,0,0,1,14,1,2,1,8,1,14,1,8,1,14,1, 6,2,114,99,0,0,0,99,1,0,0,0,0,0,0,0, 2,0,0,0,11,0,0,0,67,0,0,0,115,52,0,0, @@ -483,7 +483,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,233,128,0,0,0,41,3,114,41,0,0,0,114,43,0, 0,0,114,42,0,0,0,41,2,114,37,0,0,0,114,44, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,10,95,99,97,108,99,95,109,111,100,101,111,1, + 0,0,218,10,95,99,97,108,99,95,109,111,100,101,113,1, 0,0,115,12,0,0,0,0,2,2,1,14,1,14,1,10, 3,8,1,114,101,0,0,0,99,1,0,0,0,0,0,0, 0,3,0,0,0,11,0,0,0,3,0,0,0,115,68,0, @@ -521,7 +521,7 @@ const unsigned char _Py_M__importlib_external[] = { 115,90,6,107,119,97,114,103,115,41,1,218,6,109,101,116, 104,111,100,114,4,0,0,0,114,6,0,0,0,218,19,95, 99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,112, - 101,114,131,1,0,0,115,12,0,0,0,0,1,8,1,8, + 101,114,133,1,0,0,115,12,0,0,0,0,1,8,1,8, 1,10,1,4,1,20,1,122,40,95,99,104,101,99,107,95, 110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,99, 104,101,99,107,95,110,97,109,101,95,119,114,97,112,112,101, @@ -541,7 +541,7 @@ const unsigned char _Py_M__importlib_external[] = { 116,116,114,218,8,95,95,100,105,99,116,95,95,218,6,117, 112,100,97,116,101,41,3,90,3,110,101,119,90,3,111,108, 100,114,55,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,218,5,95,119,114,97,112,142,1,0,0, + 114,6,0,0,0,218,5,95,119,114,97,112,144,1,0,0, 115,8,0,0,0,0,1,10,1,10,1,22,1,122,26,95, 99,104,101,99,107,95,110,97,109,101,46,60,108,111,99,97, 108,115,62,46,95,119,114,97,112,41,1,78,41,3,218,10, @@ -549,7 +549,7 @@ const unsigned char _Py_M__importlib_external[] = { 9,78,97,109,101,69,114,114,111,114,41,3,114,106,0,0, 0,114,107,0,0,0,114,117,0,0,0,114,4,0,0,0, 41,1,114,106,0,0,0,114,6,0,0,0,218,11,95,99, - 104,101,99,107,95,110,97,109,101,123,1,0,0,115,14,0, + 104,101,99,107,95,110,97,109,101,125,1,0,0,115,14,0, 0,0,0,8,14,7,2,1,10,1,14,2,14,5,10,1, 114,120,0,0,0,99,2,0,0,0,0,0,0,0,5,0, 0,0,4,0,0,0,67,0,0,0,115,60,0,0,0,124, @@ -577,7 +577,7 @@ const unsigned char _Py_M__importlib_external[] = { 101,218,6,108,111,97,100,101,114,218,8,112,111,114,116,105, 111,110,115,218,3,109,115,103,114,4,0,0,0,114,4,0, 0,0,114,6,0,0,0,218,17,95,102,105,110,100,95,109, - 111,100,117,108,101,95,115,104,105,109,151,1,0,0,115,10, + 111,100,117,108,101,95,115,104,105,109,153,1,0,0,115,10, 0,0,0,0,10,14,1,16,1,4,1,22,1,114,127,0, 0,0,99,4,0,0,0,0,0,0,0,11,0,0,0,19, 0,0,0,67,0,0,0,115,128,1,0,0,105,0,125,4, @@ -657,7 +657,7 @@ const unsigned char _Py_M__importlib_external[] = { 111,117,114,99,101,95,115,105,122,101,114,4,0,0,0,114, 4,0,0,0,114,6,0,0,0,218,25,95,118,97,108,105, 100,97,116,101,95,98,121,116,101,99,111,100,101,95,104,101, - 97,100,101,114,168,1,0,0,115,76,0,0,0,0,11,4, + 97,100,101,114,170,1,0,0,115,76,0,0,0,0,11,4, 1,8,1,10,3,4,1,8,1,8,1,12,1,12,1,12, 1,8,1,12,1,12,1,12,1,12,1,10,1,12,1,10, 1,12,1,10,1,12,1,8,1,10,1,2,1,16,1,14, @@ -686,7 +686,7 @@ const unsigned char _Py_M__importlib_external[] = { 5,114,56,0,0,0,114,102,0,0,0,114,93,0,0,0, 114,94,0,0,0,218,4,99,111,100,101,114,4,0,0,0, 114,4,0,0,0,114,6,0,0,0,218,17,95,99,111,109, - 112,105,108,101,95,98,121,116,101,99,111,100,101,223,1,0, + 112,105,108,101,95,98,121,116,101,99,111,100,101,225,1,0, 0,115,16,0,0,0,0,2,10,1,10,1,12,1,8,1, 12,1,6,2,12,1,114,145,0,0,0,114,62,0,0,0, 99,3,0,0,0,0,0,0,0,4,0,0,0,3,0,0, @@ -705,7 +705,7 @@ const unsigned char _Py_M__importlib_external[] = { 115,41,4,114,144,0,0,0,114,130,0,0,0,114,138,0, 0,0,114,56,0,0,0,114,4,0,0,0,114,4,0,0, 0,114,6,0,0,0,218,17,95,99,111,100,101,95,116,111, - 95,98,121,116,101,99,111,100,101,235,1,0,0,115,10,0, + 95,98,121,116,101,99,111,100,101,237,1,0,0,115,10,0, 0,0,0,3,8,1,14,1,14,1,16,1,114,148,0,0, 0,99,1,0,0,0,0,0,0,0,5,0,0,0,4,0, 0,0,67,0,0,0,115,62,0,0,0,100,1,100,2,108, @@ -732,7 +732,7 @@ const unsigned char _Py_M__importlib_external[] = { 101,218,8,101,110,99,111,100,105,110,103,90,15,110,101,119, 108,105,110,101,95,100,101,99,111,100,101,114,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,218,13,100,101,99, - 111,100,101,95,115,111,117,114,99,101,245,1,0,0,115,10, + 111,100,101,95,115,111,117,114,99,101,247,1,0,0,115,10, 0,0,0,0,5,8,1,12,1,10,1,12,1,114,153,0, 0,0,41,2,114,124,0,0,0,218,26,115,117,98,109,111, 100,117,108,101,95,115,101,97,114,99,104,95,108,111,99,97, @@ -794,7 +794,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,90,7,100,105,114,110,97,109,101,114,4,0,0,0, 114,4,0,0,0,114,6,0,0,0,218,23,115,112,101,99, 95,102,114,111,109,95,102,105,108,101,95,108,111,99,97,116, - 105,111,110,6,2,0,0,115,62,0,0,0,0,12,8,4, + 105,111,110,8,2,0,0,115,62,0,0,0,0,12,8,4, 4,1,10,2,2,1,14,1,14,1,8,2,10,8,18,1, 6,3,8,1,16,1,14,1,10,1,6,1,6,2,4,3, 8,2,10,1,2,1,14,1,14,1,6,2,4,1,8,2, @@ -830,7 +830,7 @@ const unsigned char _Py_M__importlib_external[] = { 72,75,69,89,95,76,79,67,65,76,95,77,65,67,72,73, 78,69,41,2,218,3,99,108,115,114,5,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,218,14,95, - 111,112,101,110,95,114,101,103,105,115,116,114,121,86,2,0, + 111,112,101,110,95,114,101,103,105,115,116,114,121,88,2,0, 0,115,8,0,0,0,0,2,2,1,14,1,14,1,122,36, 87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70, 105,110,100,101,114,46,95,111,112,101,110,95,114,101,103,105, @@ -856,7 +856,7 @@ const unsigned char _Py_M__importlib_external[] = { 114,121,95,107,101,121,114,5,0,0,0,90,4,104,107,101, 121,218,8,102,105,108,101,112,97,116,104,114,4,0,0,0, 114,4,0,0,0,114,6,0,0,0,218,16,95,115,101,97, - 114,99,104,95,114,101,103,105,115,116,114,121,93,2,0,0, + 114,99,104,95,114,101,103,105,115,116,114,121,95,2,0,0, 115,22,0,0,0,0,2,6,1,8,2,6,1,10,1,22, 1,2,1,12,1,26,1,14,1,6,1,122,38,87,105,110, 100,111,119,115,82,101,103,105,115,116,114,121,70,105,110,100, @@ -878,7 +878,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,114,37,0,0,0,218,6,116,97,114,103,101,116, 114,174,0,0,0,114,124,0,0,0,114,164,0,0,0,114, 162,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,218,9,102,105,110,100,95,115,112,101,99,108,2, + 0,0,0,218,9,102,105,110,100,95,115,112,101,99,110,2, 0,0,115,26,0,0,0,0,2,10,1,8,1,4,1,2, 1,12,1,14,1,6,1,16,1,14,1,6,1,10,1,8, 1,122,31,87,105,110,100,111,119,115,82,101,103,105,115,116, @@ -897,7 +897,7 @@ const unsigned char _Py_M__importlib_external[] = { 78,41,2,114,178,0,0,0,114,124,0,0,0,41,4,114, 168,0,0,0,114,123,0,0,0,114,37,0,0,0,114,162, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,124, + 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,126, 2,0,0,115,8,0,0,0,0,7,12,1,8,1,8,2, 122,33,87,105,110,100,111,119,115,82,101,103,105,115,116,114, 121,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, @@ -907,7 +907,7 @@ const unsigned char _Py_M__importlib_external[] = { 11,99,108,97,115,115,109,101,116,104,111,100,114,169,0,0, 0,114,175,0,0,0,114,178,0,0,0,114,179,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,114,166,0,0,0,74,2,0,0,115,20,0, + 6,0,0,0,114,166,0,0,0,76,2,0,0,115,20,0, 0,0,8,2,4,3,4,3,4,2,4,2,12,7,12,15, 2,1,12,15,2,1,114,166,0,0,0,99,0,0,0,0, 0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,0, @@ -942,7 +942,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,114,123,0,0,0,114,98,0,0,0,90,13,102,105,108, 101,110,97,109,101,95,98,97,115,101,90,9,116,97,105,108, 95,110,97,109,101,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,114,157,0,0,0,143,2,0,0,115,8,0, + 6,0,0,0,114,157,0,0,0,145,2,0,0,115,8,0, 0,0,0,3,18,1,16,1,14,1,122,24,95,76,111,97, 100,101,114,66,97,115,105,99,115,46,105,115,95,112,97,99, 107,97,103,101,99,2,0,0,0,0,0,0,0,2,0,0, @@ -953,7 +953,7 @@ const unsigned char _Py_M__importlib_external[] = { 78,114,4,0,0,0,41,2,114,104,0,0,0,114,162,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, 0,218,13,99,114,101,97,116,101,95,109,111,100,117,108,101, - 151,2,0,0,115,0,0,0,0,122,27,95,76,111,97,100, + 153,2,0,0,115,0,0,0,0,122,27,95,76,111,97,100, 101,114,66,97,115,105,99,115,46,99,114,101,97,116,101,95, 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,3, 0,0,0,4,0,0,0,67,0,0,0,115,56,0,0,0, @@ -972,7 +972,7 @@ const unsigned char _Py_M__importlib_external[] = { 100,218,4,101,120,101,99,114,115,0,0,0,41,3,114,104, 0,0,0,218,6,109,111,100,117,108,101,114,144,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,218, - 11,101,120,101,99,95,109,111,100,117,108,101,154,2,0,0, + 11,101,120,101,99,95,109,111,100,117,108,101,156,2,0,0, 115,10,0,0,0,0,2,12,1,8,1,6,1,10,1,122, 25,95,76,111,97,100,101,114,66,97,115,105,99,115,46,101, 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, @@ -984,13 +984,13 @@ const unsigned char _Py_M__importlib_external[] = { 117,108,101,95,115,104,105,109,41,2,114,104,0,0,0,114, 123,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, - 162,2,0,0,115,2,0,0,0,0,2,122,25,95,76,111, + 164,2,0,0,115,2,0,0,0,0,2,122,25,95,76,111, 97,100,101,114,66,97,115,105,99,115,46,108,111,97,100,95, 109,111,100,117,108,101,78,41,8,114,109,0,0,0,114,108, 0,0,0,114,110,0,0,0,114,111,0,0,0,114,157,0, 0,0,114,183,0,0,0,114,188,0,0,0,114,190,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,181,0,0,0,138,2,0,0,115,10, + 114,6,0,0,0,114,181,0,0,0,140,2,0,0,115,10, 0,0,0,8,3,4,2,8,8,8,3,8,8,114,181,0, 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, 0,0,0,64,0,0,0,115,74,0,0,0,101,0,90,1, @@ -1016,7 +1016,7 @@ const unsigned char _Py_M__importlib_external[] = { 1,218,7,73,79,69,114,114,111,114,41,2,114,104,0,0, 0,114,37,0,0,0,114,4,0,0,0,114,4,0,0,0, 114,6,0,0,0,218,10,112,97,116,104,95,109,116,105,109, - 101,169,2,0,0,115,2,0,0,0,0,6,122,23,83,111, + 101,171,2,0,0,115,2,0,0,0,0,6,122,23,83,111, 117,114,99,101,76,111,97,100,101,114,46,112,97,116,104,95, 109,116,105,109,101,99,2,0,0,0,0,0,0,0,2,0, 0,0,3,0,0,0,67,0,0,0,115,14,0,0,0,100, @@ -1051,7 +1051,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,41,1,114,193,0,0,0,41,2,114,104,0,0, 0,114,37,0,0,0,114,4,0,0,0,114,4,0,0,0, 114,6,0,0,0,218,10,112,97,116,104,95,115,116,97,116, - 115,177,2,0,0,115,2,0,0,0,0,11,122,23,83,111, + 115,179,2,0,0,115,2,0,0,0,0,11,122,23,83,111, 117,114,99,101,76,111,97,100,101,114,46,112,97,116,104,95, 115,116,97,116,115,99,4,0,0,0,0,0,0,0,4,0, 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,124, @@ -1074,7 +1074,7 @@ const unsigned char _Py_M__importlib_external[] = { 4,114,104,0,0,0,114,94,0,0,0,90,10,99,97,99, 104,101,95,112,97,116,104,114,56,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,218,15,95,99,97, - 99,104,101,95,98,121,116,101,99,111,100,101,190,2,0,0, + 99,104,101,95,98,121,116,101,99,111,100,101,192,2,0,0, 115,2,0,0,0,0,8,122,28,83,111,117,114,99,101,76, 111,97,100,101,114,46,95,99,97,99,104,101,95,98,121,116, 101,99,111,100,101,99,3,0,0,0,0,0,0,0,3,0, @@ -1091,7 +1091,7 @@ const unsigned char _Py_M__importlib_external[] = { 108,101,115,46,10,32,32,32,32,32,32,32,32,78,114,4, 0,0,0,41,3,114,104,0,0,0,114,37,0,0,0,114, 56,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,195,0,0,0,200,2,0,0,115,0,0,0, + 0,0,0,114,195,0,0,0,202,2,0,0,115,0,0,0, 0,122,21,83,111,117,114,99,101,76,111,97,100,101,114,46, 115,101,116,95,100,97,116,97,99,2,0,0,0,0,0,0, 0,5,0,0,0,16,0,0,0,67,0,0,0,115,84,0, @@ -1112,7 +1112,7 @@ const unsigned char _Py_M__importlib_external[] = { 104,0,0,0,114,123,0,0,0,114,37,0,0,0,114,151, 0,0,0,218,3,101,120,99,114,4,0,0,0,114,4,0, 0,0,114,6,0,0,0,218,10,103,101,116,95,115,111,117, - 114,99,101,207,2,0,0,115,14,0,0,0,0,2,10,1, + 114,99,101,209,2,0,0,115,14,0,0,0,0,2,10,1, 2,1,14,1,16,1,6,1,28,1,122,23,83,111,117,114, 99,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, 114,99,101,114,31,0,0,0,41,1,218,9,95,111,112,116, @@ -1134,7 +1134,7 @@ const unsigned char _Py_M__importlib_external[] = { 104,0,0,0,114,56,0,0,0,114,37,0,0,0,114,200, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, 0,0,218,14,115,111,117,114,99,101,95,116,111,95,99,111, - 100,101,217,2,0,0,115,4,0,0,0,0,5,14,1,122, + 100,101,219,2,0,0,115,4,0,0,0,0,5,14,1,122, 27,83,111,117,114,99,101,76,111,97,100,101,114,46,115,111, 117,114,99,101,95,116,111,95,99,111,100,101,99,2,0,0, 0,0,0,0,0,10,0,0,0,43,0,0,0,67,0,0, @@ -1190,7 +1190,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,218,2,115,116,114,56,0,0,0,218,10,98,121,116, 101,115,95,100,97,116,97,114,151,0,0,0,90,11,99,111, 100,101,95,111,98,106,101,99,116,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,184,0,0,0,225,2,0, + 0,0,0,114,6,0,0,0,114,184,0,0,0,227,2,0, 0,115,78,0,0,0,0,7,10,1,4,1,2,1,12,1, 14,1,10,2,2,1,14,1,14,1,6,2,12,1,2,1, 14,1,14,1,6,2,2,1,6,1,8,1,12,1,18,1, @@ -1202,7 +1202,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,114,193,0,0,0,114,194,0,0,0,114,196,0,0, 0,114,195,0,0,0,114,199,0,0,0,114,203,0,0,0, 114,184,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,114,191,0,0,0,167,2, + 4,0,0,0,114,6,0,0,0,114,191,0,0,0,169,2, 0,0,115,14,0,0,0,8,2,8,8,8,13,8,10,8, 7,8,10,14,8,114,191,0,0,0,99,0,0,0,0,0, 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,115, @@ -1229,7 +1229,7 @@ const unsigned char _Py_M__importlib_external[] = { 78,41,2,114,102,0,0,0,114,37,0,0,0,41,3,114, 104,0,0,0,114,123,0,0,0,114,37,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,182,0, - 0,0,26,3,0,0,115,4,0,0,0,0,3,6,1,122, + 0,0,28,3,0,0,115,4,0,0,0,0,3,6,1,122, 19,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, 105,116,95,95,99,2,0,0,0,0,0,0,0,2,0,0, 0,2,0,0,0,67,0,0,0,115,24,0,0,0,124,0, @@ -1238,7 +1238,7 @@ const unsigned char _Py_M__importlib_external[] = { 108,97,115,115,95,95,114,115,0,0,0,41,2,114,104,0, 0,0,218,5,111,116,104,101,114,114,4,0,0,0,114,4, 0,0,0,114,6,0,0,0,218,6,95,95,101,113,95,95, - 32,3,0,0,115,4,0,0,0,0,1,12,1,122,17,70, + 34,3,0,0,115,4,0,0,0,0,1,12,1,122,17,70, 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, 99,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0, 0,67,0,0,0,115,20,0,0,0,116,0,124,0,106,1, @@ -1246,7 +1246,7 @@ const unsigned char _Py_M__importlib_external[] = { 78,41,3,218,4,104,97,115,104,114,102,0,0,0,114,37, 0,0,0,41,1,114,104,0,0,0,114,4,0,0,0,114, 4,0,0,0,114,6,0,0,0,218,8,95,95,104,97,115, - 104,95,95,36,3,0,0,115,2,0,0,0,0,1,122,19, + 104,95,95,38,3,0,0,115,2,0,0,0,0,1,122,19, 70,105,108,101,76,111,97,100,101,114,46,95,95,104,97,115, 104,95,95,99,2,0,0,0,0,0,0,0,2,0,0,0, 3,0,0,0,3,0,0,0,115,16,0,0,0,116,0,116, @@ -1260,7 +1260,7 @@ const unsigned char _Py_M__importlib_external[] = { 32,32,32,32,32,41,3,218,5,115,117,112,101,114,114,207, 0,0,0,114,190,0,0,0,41,2,114,104,0,0,0,114, 123,0,0,0,41,1,114,208,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,190,0,0,0,39,3,0,0,115,2, + 114,6,0,0,0,114,190,0,0,0,41,3,0,0,115,2, 0,0,0,0,10,122,22,70,105,108,101,76,111,97,100,101, 114,46,108,111,97,100,95,109,111,100,117,108,101,99,2,0, 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, @@ -1271,7 +1271,7 @@ const unsigned char _Py_M__importlib_external[] = { 116,104,101,32,102,105,110,100,101,114,46,41,1,114,37,0, 0,0,41,2,114,104,0,0,0,114,123,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,155,0, - 0,0,51,3,0,0,115,2,0,0,0,0,3,122,23,70, + 0,0,53,3,0,0,115,2,0,0,0,0,3,122,23,70, 105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105, 108,101,110,97,109,101,99,2,0,0,0,0,0,0,0,3, 0,0,0,9,0,0,0,67,0,0,0,115,32,0,0,0, @@ -1283,14 +1283,14 @@ const unsigned char _Py_M__importlib_external[] = { 3,114,52,0,0,0,114,53,0,0,0,90,4,114,101,97, 100,41,3,114,104,0,0,0,114,37,0,0,0,114,57,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,197,0,0,0,56,3,0,0,115,4,0,0,0,0, + 0,114,197,0,0,0,58,3,0,0,115,4,0,0,0,0, 2,14,1,122,19,70,105,108,101,76,111,97,100,101,114,46, 103,101,116,95,100,97,116,97,41,11,114,109,0,0,0,114, 108,0,0,0,114,110,0,0,0,114,111,0,0,0,114,182, 0,0,0,114,210,0,0,0,114,212,0,0,0,114,120,0, 0,0,114,190,0,0,0,114,155,0,0,0,114,197,0,0, 0,114,4,0,0,0,114,4,0,0,0,41,1,114,208,0, - 0,0,114,6,0,0,0,114,207,0,0,0,21,3,0,0, + 0,0,114,6,0,0,0,114,207,0,0,0,23,3,0,0, 115,14,0,0,0,8,3,4,2,8,6,8,4,8,3,16, 12,12,5,114,207,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,3,0,0,0,64,0,0,0,115,46,0, @@ -1312,7 +1312,7 @@ const unsigned char _Py_M__importlib_external[] = { 8,115,116,95,109,116,105,109,101,90,7,115,116,95,115,105, 122,101,41,3,114,104,0,0,0,114,37,0,0,0,114,205, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,194,0,0,0,66,3,0,0,115,4,0,0,0, + 0,0,114,194,0,0,0,68,3,0,0,115,4,0,0,0, 0,2,8,1,122,27,83,111,117,114,99,101,70,105,108,101, 76,111,97,100,101,114,46,112,97,116,104,95,115,116,97,116, 115,99,4,0,0,0,0,0,0,0,5,0,0,0,5,0, @@ -1322,7 +1322,7 @@ const unsigned char _Py_M__importlib_external[] = { 2,114,101,0,0,0,114,195,0,0,0,41,5,114,104,0, 0,0,114,94,0,0,0,114,93,0,0,0,114,56,0,0, 0,114,44,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,196,0,0,0,71,3,0,0,115,4, + 114,6,0,0,0,114,196,0,0,0,73,3,0,0,115,4, 0,0,0,0,2,8,1,122,32,83,111,117,114,99,101,70, 105,108,101,76,111,97,100,101,114,46,95,99,97,99,104,101, 95,98,121,116,101,99,111,100,101,105,182,1,0,0,41,1, @@ -1357,7 +1357,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,114,217,0,0,0,218,6,112,97,114,101,110,116,114,98, 0,0,0,114,29,0,0,0,114,25,0,0,0,114,198,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,195,0,0,0,76,3,0,0,115,42,0,0,0,0, + 0,114,195,0,0,0,78,3,0,0,115,42,0,0,0,0, 2,12,1,4,2,16,1,12,1,14,2,14,1,10,1,2, 1,14,1,14,2,6,1,16,3,6,1,8,1,20,1,2, 1,12,1,16,1,16,2,8,1,122,25,83,111,117,114,99, @@ -1366,7 +1366,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,114,110,0,0,0,114,111,0,0,0,114,194,0,0,0, 114,196,0,0,0,114,195,0,0,0,114,4,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,215, - 0,0,0,62,3,0,0,115,8,0,0,0,8,2,4,2, + 0,0,0,64,3,0,0,115,8,0,0,0,8,2,4,2, 8,5,8,5,114,215,0,0,0,99,0,0,0,0,0,0, 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,32, 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, @@ -1386,7 +1386,7 @@ const unsigned char _Py_M__importlib_external[] = { 145,0,0,0,41,5,114,104,0,0,0,114,123,0,0,0, 114,37,0,0,0,114,56,0,0,0,114,206,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,184, - 0,0,0,111,3,0,0,115,8,0,0,0,0,1,10,1, + 0,0,0,113,3,0,0,115,8,0,0,0,0,1,10,1, 10,1,18,1,122,29,83,111,117,114,99,101,108,101,115,115, 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,99, 111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,0, @@ -1396,13 +1396,13 @@ const unsigned char _Py_M__importlib_external[] = { 115,111,117,114,99,101,32,99,111,100,101,46,78,114,4,0, 0,0,41,2,114,104,0,0,0,114,123,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,199,0, - 0,0,117,3,0,0,115,2,0,0,0,0,2,122,31,83, + 0,0,119,3,0,0,115,2,0,0,0,0,2,122,31,83, 111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,97, 100,101,114,46,103,101,116,95,115,111,117,114,99,101,78,41, 6,114,109,0,0,0,114,108,0,0,0,114,110,0,0,0, 114,111,0,0,0,114,184,0,0,0,114,199,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,220,0,0,0,107,3,0,0,115,6,0,0, + 0,0,0,114,220,0,0,0,109,3,0,0,115,6,0,0, 0,8,2,4,2,8,6,114,220,0,0,0,99,0,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, 0,115,92,0,0,0,101,0,90,1,100,0,90,2,100,1, @@ -1424,7 +1424,7 @@ const unsigned char _Py_M__importlib_external[] = { 83,0,41,1,78,41,2,114,102,0,0,0,114,37,0,0, 0,41,3,114,104,0,0,0,114,102,0,0,0,114,37,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,182,0,0,0,134,3,0,0,115,4,0,0,0,0, + 0,114,182,0,0,0,136,3,0,0,115,4,0,0,0,0, 1,6,1,122,28,69,120,116,101,110,115,105,111,110,70,105, 108,101,76,111,97,100,101,114,46,95,95,105,110,105,116,95, 95,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0, @@ -1433,7 +1433,7 @@ const unsigned char _Py_M__importlib_external[] = { 2,83,0,41,1,78,41,2,114,208,0,0,0,114,115,0, 0,0,41,2,114,104,0,0,0,114,209,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,210,0, - 0,0,138,3,0,0,115,4,0,0,0,0,1,12,1,122, + 0,0,140,3,0,0,115,4,0,0,0,0,1,12,1,122, 26,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, 97,100,101,114,46,95,95,101,113,95,95,99,1,0,0,0, 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, @@ -1441,7 +1441,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,106,2,131,1,65,0,83,0,41,1,78,41,3,114,211, 0,0,0,114,102,0,0,0,114,37,0,0,0,41,1,114, 104,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,212,0,0,0,142,3,0,0,115,2,0,0, + 0,0,0,114,212,0,0,0,144,3,0,0,115,2,0,0, 0,0,1,122,28,69,120,116,101,110,115,105,111,110,70,105, 108,101,76,111,97,100,101,114,46,95,95,104,97,115,104,95, 95,99,2,0,0,0,0,0,0,0,3,0,0,0,4,0, @@ -1458,7 +1458,7 @@ const unsigned char _Py_M__importlib_external[] = { 105,99,114,133,0,0,0,114,102,0,0,0,114,37,0,0, 0,41,3,114,104,0,0,0,114,162,0,0,0,114,187,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,183,0,0,0,145,3,0,0,115,10,0,0,0,0, + 0,114,183,0,0,0,147,3,0,0,115,10,0,0,0,0, 2,4,1,10,1,6,1,12,1,122,33,69,120,116,101,110, 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,99, 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, @@ -1475,7 +1475,7 @@ const unsigned char _Py_M__importlib_external[] = { 121,110,97,109,105,99,114,133,0,0,0,114,102,0,0,0, 114,37,0,0,0,41,2,114,104,0,0,0,114,187,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 114,188,0,0,0,153,3,0,0,115,6,0,0,0,0,2, + 114,188,0,0,0,155,3,0,0,115,6,0,0,0,0,2, 14,1,6,1,122,31,69,120,116,101,110,115,105,111,110,70, 105,108,101,76,111,97,100,101,114,46,101,120,101,99,95,109, 111,100,117,108,101,99,2,0,0,0,0,0,0,0,2,0, @@ -1492,7 +1492,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,41,2,114,182,0,0,0,78,114,4,0,0,0,41,2, 114,24,0,0,0,218,6,115,117,102,102,105,120,41,1,218, 9,102,105,108,101,95,110,97,109,101,114,4,0,0,0,114, - 6,0,0,0,250,9,60,103,101,110,101,120,112,114,62,162, + 6,0,0,0,250,9,60,103,101,110,101,120,112,114,62,164, 3,0,0,115,2,0,0,0,4,1,122,49,69,120,116,101, 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, 105,115,95,112,97,99,107,97,103,101,46,60,108,111,99,97, @@ -1501,7 +1501,7 @@ const unsigned char _Py_M__importlib_external[] = { 69,88,84,69,78,83,73,79,78,95,83,85,70,70,73,88, 69,83,41,2,114,104,0,0,0,114,123,0,0,0,114,4, 0,0,0,41,1,114,223,0,0,0,114,6,0,0,0,114, - 157,0,0,0,159,3,0,0,115,6,0,0,0,0,2,14, + 157,0,0,0,161,3,0,0,115,6,0,0,0,0,2,14, 1,12,1,122,30,69,120,116,101,110,115,105,111,110,70,105, 108,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, 97,103,101,99,2,0,0,0,0,0,0,0,2,0,0,0, @@ -1512,7 +1512,7 @@ const unsigned char _Py_M__importlib_external[] = { 114,101,97,116,101,32,97,32,99,111,100,101,32,111,98,106, 101,99,116,46,78,114,4,0,0,0,41,2,114,104,0,0, 0,114,123,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,184,0,0,0,165,3,0,0,115,2, + 114,6,0,0,0,114,184,0,0,0,167,3,0,0,115,2, 0,0,0,0,2,122,28,69,120,116,101,110,115,105,111,110, 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,99, 111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,0, @@ -1523,7 +1523,7 @@ const unsigned char _Py_M__importlib_external[] = { 117,114,99,101,32,99,111,100,101,46,78,114,4,0,0,0, 41,2,114,104,0,0,0,114,123,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,114,199,0,0,0, - 169,3,0,0,115,2,0,0,0,0,2,122,30,69,120,116, + 171,3,0,0,115,2,0,0,0,0,2,122,30,69,120,116, 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, 46,103,101,116,95,115,111,117,114,99,101,99,2,0,0,0, 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, @@ -1534,7 +1534,7 @@ const unsigned char _Py_M__importlib_external[] = { 101,32,102,105,110,100,101,114,46,41,1,114,37,0,0,0, 41,2,114,104,0,0,0,114,123,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,114,155,0,0,0, - 173,3,0,0,115,2,0,0,0,0,3,122,32,69,120,116, + 175,3,0,0,115,2,0,0,0,0,3,122,32,69,120,116, 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, 46,103,101,116,95,102,105,108,101,110,97,109,101,78,41,14, 114,109,0,0,0,114,108,0,0,0,114,110,0,0,0,114, @@ -1542,7 +1542,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,114,183,0,0,0,114,188,0,0,0,114,157,0, 0,0,114,184,0,0,0,114,199,0,0,0,114,120,0,0, 0,114,155,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,114,221,0,0,0,126, + 114,4,0,0,0,114,6,0,0,0,114,221,0,0,0,128, 3,0,0,115,20,0,0,0,8,6,4,2,8,4,8,4, 8,3,8,8,8,6,8,6,8,4,8,4,114,221,0,0, 0,99,0,0,0,0,0,0,0,0,0,0,0,0,2,0, @@ -1584,7 +1584,7 @@ const unsigned char _Py_M__importlib_external[] = { 114,41,4,114,104,0,0,0,114,102,0,0,0,114,37,0, 0,0,218,11,112,97,116,104,95,102,105,110,100,101,114,114, 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,182, - 0,0,0,186,3,0,0,115,8,0,0,0,0,1,6,1, + 0,0,0,188,3,0,0,115,8,0,0,0,0,1,6,1, 6,1,14,1,122,23,95,78,97,109,101,115,112,97,99,101, 80,97,116,104,46,95,95,105,110,105,116,95,95,99,1,0, 0,0,0,0,0,0,4,0,0,0,3,0,0,0,67,0, @@ -1602,7 +1602,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,218,3,100,111,116,90,2,109,101,114,4,0,0,0, 114,4,0,0,0,114,6,0,0,0,218,23,95,102,105,110, 100,95,112,97,114,101,110,116,95,112,97,116,104,95,110,97, - 109,101,115,192,3,0,0,115,8,0,0,0,0,2,18,1, + 109,101,115,194,3,0,0,115,8,0,0,0,0,2,18,1, 8,2,4,3,122,38,95,78,97,109,101,115,112,97,99,101, 80,97,116,104,46,95,102,105,110,100,95,112,97,114,101,110, 116,95,112,97,116,104,95,110,97,109,101,115,99,1,0,0, @@ -1614,7 +1614,7 @@ const unsigned char _Py_M__importlib_external[] = { 3,114,104,0,0,0,90,18,112,97,114,101,110,116,95,109, 111,100,117,108,101,95,110,97,109,101,90,14,112,97,116,104, 95,97,116,116,114,95,110,97,109,101,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,114,230,0,0,0,202,3, + 4,0,0,0,114,6,0,0,0,114,230,0,0,0,204,3, 0,0,115,4,0,0,0,0,1,12,1,122,31,95,78,97, 109,101,115,112,97,99,101,80,97,116,104,46,95,103,101,116, 95,112,97,114,101,110,116,95,112,97,116,104,99,1,0,0, @@ -1630,7 +1630,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,41,3,114,104,0,0,0,90,11,112,97,114,101, 110,116,95,112,97,116,104,114,162,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,218,12,95,114,101, - 99,97,108,99,117,108,97,116,101,206,3,0,0,115,16,0, + 99,97,108,99,117,108,97,116,101,208,3,0,0,115,16,0, 0,0,0,2,12,1,10,1,14,3,18,1,6,1,8,1, 6,1,122,27,95,78,97,109,101,115,112,97,99,101,80,97, 116,104,46,95,114,101,99,97,108,99,117,108,97,116,101,99, @@ -1639,7 +1639,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,131,1,83,0,41,1,78,41,2,218,4,105,116,101,114, 114,237,0,0,0,41,1,114,104,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,218,8,95,95,105, - 116,101,114,95,95,219,3,0,0,115,2,0,0,0,0,1, + 116,101,114,95,95,221,3,0,0,115,2,0,0,0,0,1, 122,23,95,78,97,109,101,115,112,97,99,101,80,97,116,104, 46,95,95,105,116,101,114,95,95,99,3,0,0,0,0,0, 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,14, @@ -1647,7 +1647,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,41,1,78,41,1,114,229,0,0,0,41,3,114,104,0, 0,0,218,5,105,110,100,101,120,114,37,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,218,11,95, - 95,115,101,116,105,116,101,109,95,95,222,3,0,0,115,2, + 95,115,101,116,105,116,101,109,95,95,224,3,0,0,115,2, 0,0,0,0,1,122,26,95,78,97,109,101,115,112,97,99, 101,80,97,116,104,46,95,95,115,101,116,105,116,101,109,95, 95,99,1,0,0,0,0,0,0,0,1,0,0,0,2,0, @@ -1655,7 +1655,7 @@ const unsigned char _Py_M__importlib_external[] = { 1,131,0,131,1,83,0,41,1,78,41,2,114,33,0,0, 0,114,237,0,0,0,41,1,114,104,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,218,7,95,95, - 108,101,110,95,95,225,3,0,0,115,2,0,0,0,0,1, + 108,101,110,95,95,227,3,0,0,115,2,0,0,0,0,1, 122,22,95,78,97,109,101,115,112,97,99,101,80,97,116,104, 46,95,95,108,101,110,95,95,99,1,0,0,0,0,0,0, 0,1,0,0,0,2,0,0,0,67,0,0,0,115,12,0, @@ -1664,7 +1664,7 @@ const unsigned char _Py_M__importlib_external[] = { 104,40,123,33,114,125,41,41,2,114,50,0,0,0,114,229, 0,0,0,41,1,114,104,0,0,0,114,4,0,0,0,114, 4,0,0,0,114,6,0,0,0,218,8,95,95,114,101,112, - 114,95,95,228,3,0,0,115,2,0,0,0,0,1,122,23, + 114,95,95,230,3,0,0,115,2,0,0,0,0,1,122,23, 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, 95,114,101,112,114,95,95,99,2,0,0,0,0,0,0,0, 2,0,0,0,2,0,0,0,67,0,0,0,115,12,0,0, @@ -1672,7 +1672,7 @@ const unsigned char _Py_M__importlib_external[] = { 41,1,114,237,0,0,0,41,2,114,104,0,0,0,218,4, 105,116,101,109,114,4,0,0,0,114,4,0,0,0,114,6, 0,0,0,218,12,95,95,99,111,110,116,97,105,110,115,95, - 95,231,3,0,0,115,2,0,0,0,0,1,122,27,95,78, + 95,233,3,0,0,115,2,0,0,0,0,1,122,27,95,78, 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,99, 111,110,116,97,105,110,115,95,95,99,2,0,0,0,0,0, 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,16, @@ -1680,7 +1680,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,83,0,41,1,78,41,2,114,229,0,0,0,114,161,0, 0,0,41,2,114,104,0,0,0,114,244,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,161,0, - 0,0,234,3,0,0,115,2,0,0,0,0,1,122,21,95, + 0,0,236,3,0,0,115,2,0,0,0,0,1,122,21,95, 78,97,109,101,115,112,97,99,101,80,97,116,104,46,97,112, 112,101,110,100,78,41,14,114,109,0,0,0,114,108,0,0, 0,114,110,0,0,0,114,111,0,0,0,114,182,0,0,0, @@ -1688,7 +1688,7 @@ const unsigned char _Py_M__importlib_external[] = { 239,0,0,0,114,241,0,0,0,114,242,0,0,0,114,243, 0,0,0,114,245,0,0,0,114,161,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,227,0,0,0,179,3,0,0,115,22,0,0,0,8, + 0,114,227,0,0,0,181,3,0,0,115,22,0,0,0,8, 5,4,2,8,6,8,10,8,4,8,13,8,3,8,3,8, 3,8,3,8,3,114,227,0,0,0,99,0,0,0,0,0, 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, @@ -1704,7 +1704,7 @@ const unsigned char _Py_M__importlib_external[] = { 100,0,83,0,41,1,78,41,2,114,227,0,0,0,114,229, 0,0,0,41,4,114,104,0,0,0,114,102,0,0,0,114, 37,0,0,0,114,233,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,182,0,0,0,240,3,0, + 0,0,0,114,6,0,0,0,114,182,0,0,0,242,3,0, 0,115,2,0,0,0,0,1,122,25,95,78,97,109,101,115, 112,97,99,101,76,111,97,100,101,114,46,95,95,105,110,105, 116,95,95,99,2,0,0,0,0,0,0,0,2,0,0,0, @@ -1721,14 +1721,14 @@ const unsigned char _Py_M__importlib_external[] = { 110,97,109,101,115,112,97,99,101,41,62,41,2,114,50,0, 0,0,114,109,0,0,0,41,2,114,168,0,0,0,114,187, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,11,109,111,100,117,108,101,95,114,101,112,114,243, + 0,0,218,11,109,111,100,117,108,101,95,114,101,112,114,245, 3,0,0,115,2,0,0,0,0,7,122,28,95,78,97,109, 101,115,112,97,99,101,76,111,97,100,101,114,46,109,111,100, 117,108,101,95,114,101,112,114,99,2,0,0,0,0,0,0, 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, 0,0,100,1,83,0,41,2,78,84,114,4,0,0,0,41, 2,114,104,0,0,0,114,123,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,114,157,0,0,0,252, + 114,4,0,0,0,114,6,0,0,0,114,157,0,0,0,254, 3,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, 101,115,112,97,99,101,76,111,97,100,101,114,46,105,115,95, 112,97,99,107,97,103,101,99,2,0,0,0,0,0,0,0, @@ -1736,7 +1736,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,100,1,83,0,41,2,78,114,32,0,0,0,114,4,0, 0,0,41,2,114,104,0,0,0,114,123,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,199,0, - 0,0,255,3,0,0,115,2,0,0,0,0,1,122,27,95, + 0,0,1,4,0,0,115,2,0,0,0,0,1,122,27,95, 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, 0,0,0,2,0,0,0,6,0,0,0,67,0,0,0,115, @@ -1745,7 +1745,7 @@ const unsigned char _Py_M__importlib_external[] = { 60,115,116,114,105,110,103,62,114,186,0,0,0,114,201,0, 0,0,84,41,1,114,202,0,0,0,41,2,114,104,0,0, 0,114,123,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,184,0,0,0,2,4,0,0,115,2, + 114,6,0,0,0,114,184,0,0,0,4,4,0,0,115,2, 0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,99, 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, @@ -1755,14 +1755,14 @@ const unsigned char _Py_M__importlib_external[] = { 108,101,32,99,114,101,97,116,105,111,110,46,78,114,4,0, 0,0,41,2,114,104,0,0,0,114,162,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,183,0, - 0,0,5,4,0,0,115,0,0,0,0,122,30,95,78,97, + 0,0,7,4,0,0,115,0,0,0,0,122,30,95,78,97, 109,101,115,112,97,99,101,76,111,97,100,101,114,46,99,114, 101,97,116,101,95,109,111,100,117,108,101,99,2,0,0,0, 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, 115,4,0,0,0,100,0,83,0,41,1,78,114,4,0,0, 0,41,2,114,104,0,0,0,114,187,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,114,188,0,0, - 0,8,4,0,0,115,2,0,0,0,0,1,122,28,95,78, + 0,10,4,0,0,115,2,0,0,0,0,1,122,28,95,78, 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, @@ -1780,7 +1780,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,114,133,0,0,0,114,229,0,0,0,114,189,0, 0,0,41,2,114,104,0,0,0,114,123,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,190,0, - 0,0,11,4,0,0,115,6,0,0,0,0,7,6,1,8, + 0,0,13,4,0,0,115,6,0,0,0,0,7,6,1,8, 1,122,28,95,78,97,109,101,115,112,97,99,101,76,111,97, 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,78, 41,12,114,109,0,0,0,114,108,0,0,0,114,110,0,0, @@ -1788,7 +1788,7 @@ const unsigned char _Py_M__importlib_external[] = { 114,157,0,0,0,114,199,0,0,0,114,184,0,0,0,114, 183,0,0,0,114,188,0,0,0,114,190,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,246,0,0,0,239,3,0,0,115,16,0,0,0, + 0,0,114,246,0,0,0,241,3,0,0,115,16,0,0,0, 8,1,8,3,12,9,8,3,8,3,8,3,8,3,8,3, 114,246,0,0,0,99,0,0,0,0,0,0,0,0,0,0, 0,0,4,0,0,0,64,0,0,0,115,106,0,0,0,101, @@ -1822,7 +1822,7 @@ const unsigned char _Py_M__importlib_external[] = { 108,117,101,115,114,112,0,0,0,114,249,0,0,0,41,2, 114,168,0,0,0,218,6,102,105,110,100,101,114,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,114,249,0,0, - 0,29,4,0,0,115,6,0,0,0,0,4,16,1,10,1, + 0,31,4,0,0,115,6,0,0,0,0,4,16,1,10,1, 122,28,80,97,116,104,70,105,110,100,101,114,46,105,110,118, 97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,2, 0,0,0,0,0,0,0,3,0,0,0,12,0,0,0,67, @@ -1841,7 +1841,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,114,64,0,0,0,114,122,0,0,0,114,103,0,0, 0,41,3,114,168,0,0,0,114,37,0,0,0,90,4,104, 111,111,107,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,11,95,112,97,116,104,95,104,111,111,107,115,37, + 0,0,218,11,95,112,97,116,104,95,104,111,111,107,115,39, 4,0,0,115,16,0,0,0,0,3,18,1,12,1,12,1, 2,1,8,1,14,1,12,2,122,22,80,97,116,104,70,105, 110,100,101,114,46,95,112,97,116,104,95,104,111,111,107,115, @@ -1873,7 +1873,7 @@ const unsigned char _Py_M__importlib_external[] = { 3,114,168,0,0,0,114,37,0,0,0,114,252,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,218, 20,95,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,50,4,0,0,115,22,0,0,0,0,8, + 99,97,99,104,101,52,4,0,0,115,22,0,0,0,0,8, 8,1,2,1,12,1,14,3,6,1,2,1,14,1,14,1, 10,1,16,1,122,31,80,97,116,104,70,105,110,100,101,114, 46,95,112,97,116,104,95,105,109,112,111,114,116,101,114,95, @@ -1890,7 +1890,7 @@ const unsigned char _Py_M__importlib_external[] = { 114,168,0,0,0,114,123,0,0,0,114,252,0,0,0,114, 124,0,0,0,114,125,0,0,0,114,162,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,6,0,0,0,218,16,95, - 108,101,103,97,99,121,95,103,101,116,95,115,112,101,99,72, + 108,101,103,97,99,121,95,103,101,116,95,115,112,101,99,74, 4,0,0,115,18,0,0,0,0,4,10,1,16,2,10,1, 4,1,8,1,12,1,12,1,6,1,122,27,80,97,116,104, 70,105,110,100,101,114,46,95,108,101,103,97,99,121,95,103, @@ -1922,7 +1922,7 @@ const unsigned char _Py_M__importlib_external[] = { 95,112,97,116,104,90,5,101,110,116,114,121,114,252,0,0, 0,114,162,0,0,0,114,125,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,6,0,0,0,218,9,95,103,101,116, - 95,115,112,101,99,87,4,0,0,115,40,0,0,0,0,5, + 95,115,112,101,99,89,4,0,0,115,40,0,0,0,0,5, 4,1,10,1,14,1,2,1,10,1,8,1,10,1,14,2, 12,1,8,1,2,1,10,1,4,1,6,1,8,1,8,5, 14,2,12,1,6,1,122,20,80,97,116,104,70,105,110,100, @@ -1950,7 +1950,7 @@ const unsigned char _Py_M__importlib_external[] = { 41,6,114,168,0,0,0,114,123,0,0,0,114,37,0,0, 0,114,177,0,0,0,114,162,0,0,0,114,3,1,0,0, 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,114, - 178,0,0,0,119,4,0,0,115,26,0,0,0,0,6,8, + 178,0,0,0,121,4,0,0,115,26,0,0,0,0,6,8, 1,6,1,14,1,8,1,6,1,10,1,6,1,4,3,6, 1,16,1,6,2,6,2,122,20,80,97,116,104,70,105,110, 100,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0, @@ -1971,7 +1971,7 @@ const unsigned char _Py_M__importlib_external[] = { 32,32,32,78,41,2,114,178,0,0,0,114,124,0,0,0, 41,4,114,168,0,0,0,114,123,0,0,0,114,37,0,0, 0,114,162,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,179,0,0,0,143,4,0,0,115,8, + 114,6,0,0,0,114,179,0,0,0,145,4,0,0,115,8, 0,0,0,0,8,12,1,8,1,4,1,122,22,80,97,116, 104,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, 117,108,101,41,1,78,41,2,78,78,41,1,78,41,12,114, @@ -1980,7 +1980,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,114,0,1,0,0,114,1,1,0,0,114,4,1,0, 0,114,178,0,0,0,114,179,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,114, - 248,0,0,0,25,4,0,0,115,22,0,0,0,8,2,4, + 248,0,0,0,27,4,0,0,115,22,0,0,0,8,2,4, 2,12,8,12,13,12,22,12,15,2,1,12,31,2,1,12, 23,2,1,114,248,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,3,0,0,0,64,0,0,0,115,90,0, @@ -2024,7 +2024,7 @@ const unsigned char _Py_M__importlib_external[] = { 1,0,113,2,100,0,83,0,41,1,78,114,4,0,0,0, 41,2,114,24,0,0,0,114,222,0,0,0,41,1,114,124, 0,0,0,114,4,0,0,0,114,6,0,0,0,114,224,0, - 0,0,172,4,0,0,115,2,0,0,0,4,0,122,38,70, + 0,0,174,4,0,0,115,2,0,0,0,4,0,122,38,70, 105,108,101,70,105,110,100,101,114,46,95,95,105,110,105,116, 95,95,46,60,108,111,99,97,108,115,62,46,60,103,101,110, 101,120,112,114,62,114,61,0,0,0,114,31,0,0,0,78, @@ -2036,7 +2036,7 @@ const unsigned char _Py_M__importlib_external[] = { 5,114,104,0,0,0,114,37,0,0,0,218,14,108,111,97, 100,101,114,95,100,101,116,97,105,108,115,90,7,108,111,97, 100,101,114,115,114,164,0,0,0,114,4,0,0,0,41,1, - 114,124,0,0,0,114,6,0,0,0,114,182,0,0,0,166, + 114,124,0,0,0,114,6,0,0,0,114,182,0,0,0,168, 4,0,0,115,16,0,0,0,0,4,4,1,14,1,28,1, 6,2,10,1,6,1,8,1,122,19,70,105,108,101,70,105, 110,100,101,114,46,95,95,105,110,105,116,95,95,99,1,0, @@ -2047,7 +2047,7 @@ const unsigned char _Py_M__importlib_external[] = { 105,109,101,46,114,31,0,0,0,78,114,91,0,0,0,41, 1,114,7,1,0,0,41,1,114,104,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,114,249,0,0, - 0,180,4,0,0,115,2,0,0,0,0,2,122,28,70,105, + 0,182,4,0,0,115,2,0,0,0,0,2,122,28,70,105, 108,101,70,105,110,100,101,114,46,105,110,118,97,108,105,100, 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, 0,0,0,3,0,0,0,2,0,0,0,67,0,0,0,115, @@ -2069,7 +2069,7 @@ const unsigned char _Py_M__importlib_external[] = { 32,32,32,32,32,32,32,78,41,3,114,178,0,0,0,114, 124,0,0,0,114,154,0,0,0,41,3,114,104,0,0,0, 114,123,0,0,0,114,162,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,114,121,0,0,0,186,4, + 4,0,0,0,114,6,0,0,0,114,121,0,0,0,188,4, 0,0,115,8,0,0,0,0,7,10,1,8,1,8,1,122, 22,70,105,108,101,70,105,110,100,101,114,46,102,105,110,100, 95,108,111,97,100,101,114,99,6,0,0,0,0,0,0,0, @@ -2080,7 +2080,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,41,7,114,104,0,0,0,114,163,0,0,0,114, 123,0,0,0,114,37,0,0,0,90,4,115,109,115,108,114, 177,0,0,0,114,124,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,4,1,0,0,198,4,0, + 0,0,0,114,6,0,0,0,114,4,1,0,0,200,4,0, 0,115,6,0,0,0,0,1,10,1,12,1,122,20,70,105, 108,101,70,105,110,100,101,114,46,95,103,101,116,95,115,112, 101,99,78,99,3,0,0,0,0,0,0,0,14,0,0,0, @@ -2135,7 +2135,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,90,13,105,110,105,116,95,102,105,108,101,110,97, 109,101,90,9,102,117,108,108,95,112,97,116,104,114,162,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,178,0,0,0,203,4,0,0,115,70,0,0,0,0, + 0,114,178,0,0,0,205,4,0,0,115,70,0,0,0,0, 5,4,1,14,1,2,1,24,1,14,1,10,1,10,1,8, 1,6,2,6,1,6,1,10,2,6,1,4,2,8,1,12, 1,16,1,8,1,10,1,8,1,24,4,8,2,16,1,16, @@ -2166,7 +2166,7 @@ const unsigned char _Py_M__importlib_external[] = { 125,1,124,1,106,0,131,0,146,2,113,4,83,0,114,4, 0,0,0,41,1,114,92,0,0,0,41,2,114,24,0,0, 0,90,2,102,110,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,250,9,60,115,101,116,99,111,109,112,62,24, + 6,0,0,0,250,9,60,115,101,116,99,111,109,112,62,26, 5,0,0,115,2,0,0,0,6,0,122,41,70,105,108,101, 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, 104,101,46,60,108,111,99,97,108,115,62,46,60,115,101,116, @@ -2184,7 +2184,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,114,102,0,0,0,114,234,0,0,0,114,222,0, 0,0,90,8,110,101,119,95,110,97,109,101,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,114,12,1,0,0, - 251,4,0,0,115,34,0,0,0,0,2,6,1,2,1,22, + 253,4,0,0,115,34,0,0,0,0,2,6,1,2,1,22, 1,20,3,10,3,12,1,12,7,6,1,10,1,16,1,4, 1,18,2,4,1,14,1,6,1,12,1,122,22,70,105,108, 101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,97, @@ -2221,7 +2221,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,114,103,0,0,0,41,1,114,37,0,0,0,41,2,114, 168,0,0,0,114,11,1,0,0,114,4,0,0,0,114,6, 0,0,0,218,24,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,36,5,0, + 111,114,95,70,105,108,101,70,105,110,100,101,114,38,5,0, 0,115,6,0,0,0,0,2,8,1,14,1,122,54,70,105, 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, 111,107,46,60,108,111,99,97,108,115,62,46,112,97,116,104, @@ -2229,7 +2229,7 @@ const unsigned char _Py_M__importlib_external[] = { 110,100,101,114,114,4,0,0,0,41,3,114,168,0,0,0, 114,11,1,0,0,114,17,1,0,0,114,4,0,0,0,41, 2,114,168,0,0,0,114,11,1,0,0,114,6,0,0,0, - 218,9,112,97,116,104,95,104,111,111,107,26,5,0,0,115, + 218,9,112,97,116,104,95,104,111,111,107,28,5,0,0,115, 4,0,0,0,0,10,14,6,122,20,70,105,108,101,70,105, 110,100,101,114,46,112,97,116,104,95,104,111,111,107,99,1, 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, @@ -2238,7 +2238,7 @@ const unsigned char _Py_M__importlib_external[] = { 100,101,114,40,123,33,114,125,41,41,2,114,50,0,0,0, 114,37,0,0,0,41,1,114,104,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,6,0,0,0,114,243,0,0,0, - 44,5,0,0,115,2,0,0,0,0,1,122,19,70,105,108, + 46,5,0,0,115,2,0,0,0,0,1,122,19,70,105,108, 101,70,105,110,100,101,114,46,95,95,114,101,112,114,95,95, 41,1,78,41,15,114,109,0,0,0,114,108,0,0,0,114, 110,0,0,0,114,111,0,0,0,114,182,0,0,0,114,249, @@ -2246,7 +2246,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,114,4,1,0,0,114,178,0,0,0,114,12,1,0, 0,114,180,0,0,0,114,18,1,0,0,114,243,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,114,5,1,0,0,157,4,0,0,115,20,0, + 6,0,0,0,114,5,1,0,0,159,4,0,0,115,20,0, 0,0,8,7,4,2,8,14,8,4,4,2,8,12,8,5, 10,48,8,31,12,18,114,5,1,0,0,99,4,0,0,0, 0,0,0,0,6,0,0,0,11,0,0,0,67,0,0,0, @@ -2269,7 +2269,7 @@ const unsigned char _Py_M__importlib_external[] = { 112,97,116,104,110,97,109,101,90,9,99,112,97,116,104,110, 97,109,101,114,124,0,0,0,114,162,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,218,14,95,102, - 105,120,95,117,112,95,109,111,100,117,108,101,50,5,0,0, + 105,120,95,117,112,95,109,111,100,117,108,101,52,5,0,0, 115,34,0,0,0,0,2,10,1,10,1,4,1,4,1,8, 1,8,1,12,2,10,1,4,1,16,1,2,1,8,1,8, 1,8,1,12,1,14,2,114,23,1,0,0,99,0,0,0, @@ -2289,7 +2289,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,41,3,90,10,101,120,116,101,110,115,105,111,110, 115,90,6,115,111,117,114,99,101,90,8,98,121,116,101,99, 111,100,101,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,159,0,0,0,73,5,0,0,115,8,0,0,0, + 0,0,114,159,0,0,0,75,5,0,0,115,8,0,0,0, 0,5,12,1,8,1,8,1,114,159,0,0,0,99,1,0, 0,0,0,0,0,0,12,0,0,0,12,0,0,0,67,0, 0,0,115,188,1,0,0,124,0,97,0,116,0,106,1,97, @@ -2342,7 +2342,7 @@ const unsigned char _Py_M__importlib_external[] = { 83,0,41,2,114,31,0,0,0,78,41,1,114,33,0,0, 0,41,2,114,24,0,0,0,114,81,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,6,0,0,0,114,224,0,0, - 0,109,5,0,0,115,2,0,0,0,4,0,122,25,95,115, + 0,111,5,0,0,115,2,0,0,0,4,0,122,25,95,115, 101,116,117,112,46,60,108,111,99,97,108,115,62,46,60,103, 101,110,101,120,112,114,62,114,62,0,0,0,122,30,105,109, 112,111,114,116,108,105,98,32,114,101,113,117,105,114,101,115, @@ -2372,7 +2372,7 @@ const unsigned char _Py_M__importlib_external[] = { 101,90,14,119,101,97,107,114,101,102,95,109,111,100,117,108, 101,90,13,119,105,110,114,101,103,95,109,111,100,117,108,101, 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,218, - 6,95,115,101,116,117,112,84,5,0,0,115,82,0,0,0, + 6,95,115,101,116,117,112,86,5,0,0,115,82,0,0,0, 0,8,4,1,6,1,6,3,10,1,10,1,10,1,12,2, 10,1,16,3,22,1,14,2,22,1,8,1,10,1,10,1, 4,2,2,1,10,1,6,1,14,1,12,2,8,1,12,1, @@ -2396,7 +2396,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,114,215,0,0,0,41,2,114,31,1,0,0,90,17,115, 117,112,112,111,114,116,101,100,95,108,111,97,100,101,114,115, 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,218, - 8,95,105,110,115,116,97,108,108,152,5,0,0,115,16,0, + 8,95,105,110,115,116,97,108,108,154,5,0,0,115,16,0, 0,0,0,2,8,1,6,1,20,1,10,1,12,1,12,4, 6,1,114,34,1,0,0,41,1,122,3,119,105,110,41,2, 114,1,0,0,0,114,2,0,0,0,41,1,114,49,0,0, @@ -2430,7 +2430,7 @@ const unsigned char _Py_M__importlib_external[] = { 0,0,0,114,4,0,0,0,114,6,0,0,0,218,8,60, 109,111,100,117,108,101,62,8,0,0,0,115,108,0,0,0, 4,16,4,1,4,1,2,1,6,3,8,17,8,5,8,5, - 8,6,8,12,8,10,8,9,8,5,8,7,10,22,10,117, + 8,6,8,12,8,10,8,9,8,5,8,7,10,22,10,119, 16,1,12,2,4,1,4,2,6,2,6,2,8,2,16,45, 8,34,8,19,8,12,8,12,8,28,8,17,10,55,10,12, 10,10,8,14,6,3,4,1,14,67,14,64,14,29,16,110, diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 9337474..270ae5d 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -84,7 +84,7 @@ static void *opcode_targets[256] = { &&TARGET_WITH_CLEANUP_FINISH, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, - &&_unknown_opcode, + &&TARGET_SETUP_ANNOTATIONS, &&TARGET_YIELD_VALUE, &&TARGET_POP_BLOCK, &&TARGET_END_FINALLY, @@ -126,7 +126,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FAST, &&TARGET_STORE_FAST, &&TARGET_DELETE_FAST, - &&_unknown_opcode, + &&TARGET_STORE_ANNOTATION, &&_unknown_opcode, &&_unknown_opcode, &&TARGET_RAISE_VARARGS, diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1a68255..a2399ed 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -937,11 +937,17 @@ Py_GetPythonHome(void) static void initmain(PyInterpreterState *interp) { - PyObject *m, *d, *loader; + PyObject *m, *d, *loader, *ann_dict; m = PyImport_AddModule("__main__"); if (m == NULL) Py_FatalError("can't create __main__ module"); d = PyModule_GetDict(m); + ann_dict = PyDict_New(); + if ((ann_dict == NULL) || + (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) { + Py_FatalError("Failed to initialize __main__.__annotations__"); + } + Py_DECREF(ann_dict); if (PyDict_GetItemString(d, "__builtins__") == NULL) { PyObject *bimod = PyImport_ImportModule("builtins"); if (bimod == NULL) { diff --git a/Python/symtable.c b/Python/symtable.c index 45a8c2c..b8d9398 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1201,6 +1201,44 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, expr, s->v.Assign.targets); VISIT(st, expr, s->v.Assign.value); break; + case AnnAssign_kind: + if (s->v.AnnAssign.target->kind == Name_kind) { + expr_ty e_name = s->v.AnnAssign.target; + long cur = symtable_lookup(st, e_name->v.Name.id); + if (cur < 0) { + VISIT_QUIT(st, 0); + } + if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) + && s->v.AnnAssign.simple) { + PyErr_Format(PyExc_SyntaxError, + "annotated name '%U' can't be %s", + e_name->v.Name.id, + cur & DEF_GLOBAL ? "global" : "nonlocal"); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); + } + if (s->v.AnnAssign.simple && + !symtable_add_def(st, e_name->v.Name.id, + DEF_ANNOT | DEF_LOCAL)) { + VISIT_QUIT(st, 0); + } + else { + if (s->v.AnnAssign.value + && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) { + VISIT_QUIT(st, 0); + } + } + } + else { + VISIT(st, expr, s->v.AnnAssign.target); + } + VISIT(st, expr, s->v.AnnAssign.annotation); + if (s->v.AnnAssign.value) { + VISIT(st, expr, s->v.AnnAssign.value); + } + break; case AugAssign_kind: VISIT(st, expr, s->v.AugAssign.target); VISIT(st, expr, s->v.AugAssign.value); @@ -1258,6 +1296,15 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) long cur = symtable_lookup(st, name); if (cur < 0) VISIT_QUIT(st, 0); + if (cur & DEF_ANNOT) { + PyErr_Format(PyExc_SyntaxError, + "annotated name '%U' can't be global", + name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); + } if (cur & (DEF_LOCAL | USE)) { char buf[256]; char *c_name = _PyUnicode_AsString(name); @@ -1289,6 +1336,15 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) long cur = symtable_lookup(st, name); if (cur < 0) VISIT_QUIT(st, 0); + if (cur & DEF_ANNOT) { + PyErr_Format(PyExc_SyntaxError, + "annotated name '%U' can't be nonlocal", + name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset); + VISIT_QUIT(st, 0); + } if (cur & (DEF_LOCAL | USE)) { char buf[256]; char *c_name = _PyUnicode_AsString(name); diff --git a/Tools/parser/com2ann.py b/Tools/parser/com2ann.py new file mode 100644 index 0000000..1f46e73 --- /dev/null +++ b/Tools/parser/com2ann.py @@ -0,0 +1,308 @@ +"""Helper module to tranlate 3.5 type comments to 3.6 variable annotations.""" +import re +import os +import ast +import argparse +import tokenize +from collections import defaultdict +from textwrap import dedent +from io import BytesIO + +__all__ = ['com2ann', 'TYPE_COM'] + +TYPE_COM = re.compile('\s*#\s*type\s*:.*$', flags=re.DOTALL) +TRAIL_OR_COM = re.compile('\s*$|\s*#.*$', flags=re.DOTALL) + + +class _Data: + """Internal class describing global data on file.""" + def __init__(self, lines, tokens): + self.lines = lines + self.tokens = tokens + ttab = defaultdict(list) # maps line number to token numbers + for i, tok in enumerate(tokens): + ttab[tok.start[0]].append(i) + self.ttab = ttab + self.success = [] # list of lines where type comments where processed + self.fail = [] # list of lines where type comments where rejected + + +def skip_blank(d, lno): + while d.lines[lno].strip() == '': + lno += 1 + return lno + + +def find_start(d, lcom): + """Find first char of the assignment target.""" + i = d.ttab[lcom + 1][-2] # index of type comment token in tokens list + while ((d.tokens[i].exact_type != tokenize.NEWLINE) and + (d.tokens[i].exact_type != tokenize.ENCODING)): + i -= 1 + lno = d.tokens[i].start[0] + return skip_blank(d, lno) + + +def check_target(stmt): + if len(stmt.body): + assign = stmt.body[0] + else: + return False + if isinstance(assign, ast.Assign) and len(assign.targets) == 1: + targ = assign.targets[0] + else: + return False + if (isinstance(targ, ast.Name) or isinstance(targ, ast.Attribute) + or isinstance(targ, ast.Subscript)): + return True + return False + + +def find_eq(d, lstart): + """Find equal sign starting from lstart taking care about d[f(x=1)] = 5.""" + col = pars = 0 + lno = lstart + while d.lines[lno][col] != '=' or pars != 0: + ch = d.lines[lno][col] + if ch in '([{': + pars += 1 + elif ch in ')]}': + pars -= 1 + if ch == '#' or col == len(d.lines[lno])-1: + lno = skip_blank(d, lno+1) + col = 0 + else: + col += 1 + return lno, col + + +def find_val(d, poseq): + """Find position of first char of assignment value starting from poseq.""" + lno, col = poseq + while (d.lines[lno][col].isspace() or d.lines[lno][col] in '=\\'): + if col == len(d.lines[lno])-1: + lno += 1 + col = 0 + else: + col += 1 + return lno, col + + +def find_targ(d, poseq): + """Find position of last char of target (annotation goes here).""" + lno, col = poseq + while (d.lines[lno][col].isspace() or d.lines[lno][col] in '=\\'): + if col == 0: + lno -= 1 + col = len(d.lines[lno])-1 + else: + col -= 1 + return lno, col+1 + + +def trim(new_lines, string, ltarg, poseq, lcom, ccom): + """Remove None or Ellipsis from assignment value. + + Also remove parens if one has (None), (...) etc. + string -- 'None' or '...' + ltarg -- line where last char of target is located + poseq -- position of equal sign + lcom, ccom -- position of type comment + """ + nopars = lambda s: s.replace('(', '').replace(')', '') + leq, ceq = poseq + end = ccom if leq == lcom else len(new_lines[leq]) + subline = new_lines[leq][:ceq] + if leq == ltarg: + subline = subline.rstrip() + new_lines[leq] = subline + (new_lines[leq][end:] if leq == lcom + else new_lines[leq][ceq+1:end]) + + for lno in range(leq+1,lcom): + new_lines[lno] = nopars(new_lines[lno]) + + if lcom != leq: + subline = nopars(new_lines[lcom][:ccom]).replace(string, '') + if (not subline.isspace()): + subline = subline.rstrip() + new_lines[lcom] = subline + new_lines[lcom][ccom:] + + +def _com2ann(d, drop_None, drop_Ellipsis): + new_lines = d.lines[:] + for lcom, line in enumerate(d.lines): + match = re.search(TYPE_COM, line) + if match: + # strip " # type : annotation \n" -> "annotation \n" + tp = match.group().lstrip()[1:].lstrip()[4:].lstrip()[1:].lstrip() + submatch = re.search(TRAIL_OR_COM, tp) + subcom = '' + if submatch and submatch.group(): + subcom = submatch.group() + tp = tp[:submatch.start()] + if tp == 'ignore': + continue + ccom = match.start() + if not any(d.tokens[i].exact_type == tokenize.COMMENT + for i in d.ttab[lcom + 1]): + d.fail.append(lcom) + continue # type comment inside string + lstart = find_start(d, lcom) + stmt_str = dedent(''.join(d.lines[lstart:lcom+1])) + try: + stmt = ast.parse(stmt_str) + except SyntaxError: + d.fail.append(lcom) + continue # for or with statements + if not check_target(stmt): + d.fail.append(lcom) + continue + + d.success.append(lcom) + val = stmt.body[0].value + + # writing output now + poseq = find_eq(d, lstart) + lval, cval = find_val(d, poseq) + ltarg, ctarg = find_targ(d, poseq) + + op_par = '' + cl_par = '' + if isinstance(val, ast.Tuple): + if d.lines[lval][cval] != '(': + op_par = '(' + cl_par = ')' + # write the comment first + new_lines[lcom] = d.lines[lcom][:ccom].rstrip() + cl_par + subcom + ccom = len(d.lines[lcom][:ccom].rstrip()) + + string = False + if isinstance(val, ast.Tuple): + # t = 1, 2 -> t = (1, 2); only latter is allowed with annotation + free_place = int(new_lines[lval][cval-2:cval] == ' ') + new_lines[lval] = (new_lines[lval][:cval-free_place] + + op_par + new_lines[lval][cval:]) + elif isinstance(val, ast.Ellipsis) and drop_Ellipsis: + string = '...' + elif (isinstance(val, ast.NameConstant) and + val.value is None and drop_None): + string = 'None' + if string: + trim(new_lines, string, ltarg, poseq, lcom, ccom) + + # finally write an annotation + new_lines[ltarg] = (new_lines[ltarg][:ctarg] + + ': ' + tp + new_lines[ltarg][ctarg:]) + return ''.join(new_lines) + + +def com2ann(code, *, drop_None=False, drop_Ellipsis=False, silent=False): + """Translate type comments to type annotations in code. + + Take code as string and return this string where:: + + variable = value # type: annotation # real comment + + is translated to:: + + variable: annotation = value # real comment + + For unsupported syntax cases, the type comments are + left intact. If drop_None is True or if drop_Ellipsis + is True translate correcpondingly:: + + variable = None # type: annotation + variable = ... # type: annotation + + into:: + + variable: annotation + + The tool tries to preserve code formatting as much as + possible, but an exact translation is not guarateed. + A summary of translated comments id printed by default. + """ + try: + ast.parse(code) # we want to work only with file without syntax errors + except SyntaxError: + return None + lines = code.splitlines(keepends=True) + rl = BytesIO(code.encode('utf-8')).readline + tokens = list(tokenize.tokenize(rl)) + + data = _Data(lines, tokens) + new_code = _com2ann(data, drop_None, drop_Ellipsis) + + if not silent: + if data.success: + print('Comments translated on lines:', + ', '.join(str(lno+1) for lno in data.success)) + if data.fail: + print('Comments rejected on lines:', + ', '.join(str(lno+1) for lno in data.fail)) + if not data.success and not data.fail: + print('No type comments found') + + return new_code + + +def translate_file(infile, outfile, dnone, dell, silent): + try: + descr = tokenize.open(infile) + except SyntaxError: + print("Cannot open", infile) + return + with descr as f: + code = f.read() + enc = f.encoding + if not silent: + print('File:', infile) + new_code = com2ann(code, drop_None=dnone, + drop_Ellipsis=dell, + silent=silent) + if new_code is None: + print("SyntaxError in", infile) + return + with open(outfile, 'wb') as f: + f.write((new_code).encode(enc)) + + +if __name__ == '__main__': + + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("-o", "--outfile", + help="output file, will be overwritten if exists,\n" + "defaults to input file") + parser.add_argument("infile", + help="input file or directory for translation, must\n" + "contain no syntax errors, for directory\n" + "the outfile is ignored and translation is\n" + "made in place") + parser.add_argument("-s", "--silent", + help="Do not print summary for line numbers of\n" + "translated and rejected comments", + action="store_true") + parser.add_argument("-n", "--drop-none", + help="drop any None as assignment value during\n" + "translation if it is annotated by a type coment", + action="store_true") + parser.add_argument("-e", "--drop-ellipsis", + help="drop any Ellipsis (...) as assignment value during\n" + "translation if it is annotated by a type coment", + action="store_true") + args = parser.parse_args() + if args.outfile is None: + args.outfile = args.infile + + if os.path.isfile(args.infile): + translate_file(args.infile, args.outfile, + args.drop_none, args.drop_ellipsis, args.silent) + else: + for root, dirs, files in os.walk(args.infile): + for afile in files: + _, ext = os.path.splitext(afile) + if ext == '.py' or ext == '.pyi': + fname = os.path.join(root, afile) + translate_file(fname, fname, + args.drop_none, args.drop_ellipsis, + args.silent) diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py index 7203057..6c296bd 100644 --- a/Tools/parser/unparse.py +++ b/Tools/parser/unparse.py @@ -104,6 +104,19 @@ class Unparser: self.write(" "+self.binop[t.op.__class__.__name__]+"= ") self.dispatch(t.value) + def _AnnAssign(self, t): + self.fill() + if not t.simple and isinstance(t.target, ast.Name): + self.write('(') + self.dispatch(t.target) + if not t.simple and isinstance(t.target, ast.Name): + self.write(')') + self.write(": ") + self.dispatch(t.annotation) + if t.value: + self.write(" = ") + self.dispatch(t.value) + def _Return(self, t): self.fill("return") if t.value: |