You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10465 lines
350 KiB

Merged revisions 53623-53858 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r53624 | peter.astrand | 2007-02-02 20:06:36 +0100 (Fri, 02 Feb 2007) | 1 line We had several if statements checking the value of a fd. This is unsafe, since valid fds might be zero. We should check for not None instead. ........ r53635 | kurt.kaiser | 2007-02-05 07:03:18 +0100 (Mon, 05 Feb 2007) | 2 lines Add 'raw' support to configHandler. Patch 1650174 Tal Einat. ........ r53641 | kurt.kaiser | 2007-02-06 00:02:16 +0100 (Tue, 06 Feb 2007) | 5 lines 1. Calltips now 'handle' tuples in the argument list (display '<tuple>' :) Suggested solution by Christos Georgiou, Bug 791968. 2. Clean up tests, were not failing when they should have been. 4. Remove some camelcase and an unneeded try/except block. ........ r53644 | kurt.kaiser | 2007-02-06 04:21:40 +0100 (Tue, 06 Feb 2007) | 2 lines Clean up ModifiedInterpreter.runcode() structure ........ r53646 | peter.astrand | 2007-02-06 16:37:50 +0100 (Tue, 06 Feb 2007) | 1 line Applied patch 1124861.3.patch to solve bug #1124861: Automatically create pipes on Windows, if GetStdHandle fails. Will backport. ........ r53648 | lars.gustaebel | 2007-02-06 19:38:13 +0100 (Tue, 06 Feb 2007) | 4 lines Patch #1652681: create nonexistent files in append mode and allow appending to empty files. ........ r53649 | kurt.kaiser | 2007-02-06 20:09:43 +0100 (Tue, 06 Feb 2007) | 4 lines Updated patch (CodeContext.061217.patch) to [ 1362975 ] CodeContext - Improved text indentation Tal Einat 16Dec06 ........ r53650 | kurt.kaiser | 2007-02-06 20:21:19 +0100 (Tue, 06 Feb 2007) | 2 lines narrow exception per [ 1540849 ] except too broad ........ r53653 | kurt.kaiser | 2007-02-07 04:39:41 +0100 (Wed, 07 Feb 2007) | 4 lines [ 1621265 ] Auto-completion list placement Move AC window below input line unless not enough space, then put it above. Patch: Tal Einat ........ r53654 | kurt.kaiser | 2007-02-07 09:07:13 +0100 (Wed, 07 Feb 2007) | 2 lines Handle AttributeError during calltip lookup ........ r53656 | raymond.hettinger | 2007-02-07 21:08:22 +0100 (Wed, 07 Feb 2007) | 3 lines SF #1615701: make d.update(m) honor __getitem__() and keys() in dict subclasses ........ r53658 | raymond.hettinger | 2007-02-07 22:04:20 +0100 (Wed, 07 Feb 2007) | 1 line SF: 1397711 Set docs conflated immutable and hashable ........ r53660 | raymond.hettinger | 2007-02-07 22:42:17 +0100 (Wed, 07 Feb 2007) | 1 line Check for a common user error with defaultdict(). ........ r53662 | raymond.hettinger | 2007-02-07 23:24:07 +0100 (Wed, 07 Feb 2007) | 1 line Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict. ........ r53664 | raymond.hettinger | 2007-02-08 00:49:03 +0100 (Thu, 08 Feb 2007) | 1 line Silence compiler warning ........ r53666 | raymond.hettinger | 2007-02-08 01:07:32 +0100 (Thu, 08 Feb 2007) | 1 line Do not let overflows in enumerate() and count() pass silently. ........ r53668 | raymond.hettinger | 2007-02-08 01:50:39 +0100 (Thu, 08 Feb 2007) | 1 line Bypass set specific optimizations for set and frozenset subclasses. ........ r53670 | raymond.hettinger | 2007-02-08 02:42:35 +0100 (Thu, 08 Feb 2007) | 1 line Fix docstring bug ........ r53671 | martin.v.loewis | 2007-02-08 10:13:36 +0100 (Thu, 08 Feb 2007) | 3 lines Bug #1653736: Complain about keyword arguments to time.isoformat. Will backport to 2.5. ........ r53679 | kurt.kaiser | 2007-02-08 23:58:18 +0100 (Thu, 08 Feb 2007) | 6 lines Corrected some bugs in AutoComplete. Also, Page Up/Down in ACW implemented; mouse and cursor selection in ACWindow implemented; double Tab inserts current selection and closes ACW (similar to double-click and Return); scroll wheel now works in ACW. Added AutoComplete instructions to IDLE Help. ........ r53689 | martin.v.loewis | 2007-02-09 13:19:32 +0100 (Fri, 09 Feb 2007) | 3 lines Bug #1653736: Properly discard third argument to slot_nb_inplace_power. Will backport. ........ r53691 | martin.v.loewis | 2007-02-09 13:36:48 +0100 (Fri, 09 Feb 2007) | 4 lines Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, on "linux" and "gnu" systems. Will backport. ........ r53693 | martin.v.loewis | 2007-02-09 13:58:49 +0100 (Fri, 09 Feb 2007) | 2 lines Update broken link. Will backport to 2.5. ........ r53697 | georg.brandl | 2007-02-09 19:48:41 +0100 (Fri, 09 Feb 2007) | 2 lines Bug #1656078: typo in in profile docs. ........ r53731 | brett.cannon | 2007-02-11 06:36:00 +0100 (Sun, 11 Feb 2007) | 3 lines Change a very minor inconsistency (that is purely cosmetic) in the AST definition. ........ r53735 | skip.montanaro | 2007-02-11 19:24:37 +0100 (Sun, 11 Feb 2007) | 1 line fix trace.py --ignore-dir ........ r53741 | brett.cannon | 2007-02-11 20:44:41 +0100 (Sun, 11 Feb 2007) | 3 lines Check in changed Python-ast.c from a cosmetic change to Python.asdl (in r53731). ........ r53751 | brett.cannon | 2007-02-12 04:51:02 +0100 (Mon, 12 Feb 2007) | 5 lines Modify Parser/asdl_c.py so that the __version__ number for Python/Python-ast.c is specified at the top of the file. Also add a note that Python/Python-ast.c needs to be committed separately after a change to the AST grammar to capture the revision number of the change (which is what __version__ is set to). ........ r53752 | lars.gustaebel | 2007-02-12 10:25:53 +0100 (Mon, 12 Feb 2007) | 3 lines Bug #1656581: Point out that external file objects are supposed to be at position 0. ........ r53754 | martin.v.loewis | 2007-02-12 13:21:10 +0100 (Mon, 12 Feb 2007) | 3 lines Patch 1463026: Support default namespace in XMLGenerator. Fixes #847665. Will backport. ........ r53757 | armin.rigo | 2007-02-12 17:23:24 +0100 (Mon, 12 Feb 2007) | 4 lines Fix the line to what is my guess at the original author's meaning. (The line has no effect anyway, but is present because it's customary call the base class __init__). ........ r53763 | martin.v.loewis | 2007-02-13 09:34:45 +0100 (Tue, 13 Feb 2007) | 3 lines Patch #685268: Consider a package's __path__ in imputil. Will backport. ........ r53765 | martin.v.loewis | 2007-02-13 10:49:38 +0100 (Tue, 13 Feb 2007) | 2 lines Patch #698833: Support file decryption in zipfile. ........ r53766 | martin.v.loewis | 2007-02-13 11:10:39 +0100 (Tue, 13 Feb 2007) | 3 lines Patch #1517891: Make 'a' create the file if it doesn't exist. Fixes #1514451. ........ r53767 | martin.v.loewis | 2007-02-13 13:08:24 +0100 (Tue, 13 Feb 2007) | 3 lines Bug #1658794: Remove extraneous 'this'. Will backport to 2.5. ........ r53769 | martin.v.loewis | 2007-02-13 13:14:19 +0100 (Tue, 13 Feb 2007) | 3 lines Patch #1657276: Make NETLINK_DNRTMSG conditional. Will backport. ........ r53771 | lars.gustaebel | 2007-02-13 17:09:24 +0100 (Tue, 13 Feb 2007) | 4 lines Patch #1647484: Renamed GzipFile's filename attribute to name. The filename attribute is still accessible as a property that emits a DeprecationWarning. ........ r53772 | lars.gustaebel | 2007-02-13 17:24:00 +0100 (Tue, 13 Feb 2007) | 3 lines Strip the '.gz' extension from the filename that is written to the gzip header. ........ r53774 | martin.v.loewis | 2007-02-14 11:07:37 +0100 (Wed, 14 Feb 2007) | 2 lines Patch #1432399: Add HCI sockets. ........ r53775 | martin.v.loewis | 2007-02-14 12:30:07 +0100 (Wed, 14 Feb 2007) | 2 lines Update 1432399 to removal of _BT_SOCKADDR_MEMB. ........ r53776 | martin.v.loewis | 2007-02-14 12:30:56 +0100 (Wed, 14 Feb 2007) | 3 lines Ignore directory time stamps when considering whether to rerun libffi configure. ........ r53778 | lars.gustaebel | 2007-02-14 15:45:12 +0100 (Wed, 14 Feb 2007) | 4 lines A missing binary mode in AppendTest caused failures in Windows Buildbot. ........ r53782 | martin.v.loewis | 2007-02-15 10:51:35 +0100 (Thu, 15 Feb 2007) | 2 lines Patch #1397848: add the reasoning behind no-resize-on-shrinkage. ........ r53783 | georg.brandl | 2007-02-15 11:37:59 +0100 (Thu, 15 Feb 2007) | 2 lines Make functools.wraps() docs a bit clearer. ........ r53785 | georg.brandl | 2007-02-15 12:29:04 +0100 (Thu, 15 Feb 2007) | 2 lines Patch #1494140: Add documentation for the new struct.Struct object. ........ r53787 | georg.brandl | 2007-02-15 12:29:55 +0100 (Thu, 15 Feb 2007) | 2 lines Add missing \versionadded. ........ r53800 | brett.cannon | 2007-02-15 23:54:39 +0100 (Thu, 15 Feb 2007) | 11 lines Update the encoding package's search function to use absolute imports when calling __import__. This helps make the expected search locations for encoding modules be more explicit. One could use an explicit value for __path__ when making the call to __import__ to force the exact location searched for encodings. This would give the most strict search path possible if one is worried about malicious code being imported. The unfortunate side-effect of that is that if __path__ was modified on 'encodings' on purpose in a safe way it would not be picked up in future __import__ calls. ........ r53801 | brett.cannon | 2007-02-16 20:33:01 +0100 (Fri, 16 Feb 2007) | 2 lines Make the __import__ call in encodings.__init__ absolute with a level 0 call. ........ r53809 | vinay.sajip | 2007-02-16 23:36:24 +0100 (Fri, 16 Feb 2007) | 1 line Minor fix for currentframe (SF #1652788). ........ r53818 | raymond.hettinger | 2007-02-19 03:03:19 +0100 (Mon, 19 Feb 2007) | 3 lines Extend work on revision 52962: Eliminate redundant calls to PyObject_Hash(). ........ r53820 | raymond.hettinger | 2007-02-19 05:08:43 +0100 (Mon, 19 Feb 2007) | 1 line Add merge() function to heapq. ........ r53821 | raymond.hettinger | 2007-02-19 06:28:28 +0100 (Mon, 19 Feb 2007) | 1 line Add tie-breaker count to preserve sort stability. ........ r53822 | raymond.hettinger | 2007-02-19 07:59:32 +0100 (Mon, 19 Feb 2007) | 1 line Use C heapreplace() instead of slower _siftup() in pure python. ........ r53823 | raymond.hettinger | 2007-02-19 08:30:21 +0100 (Mon, 19 Feb 2007) | 1 line Add test for merge stability ........ r53824 | raymond.hettinger | 2007-02-19 10:14:10 +0100 (Mon, 19 Feb 2007) | 1 line Provide an example of defaultdict with non-zero constant factory function. ........ r53825 | lars.gustaebel | 2007-02-19 10:54:47 +0100 (Mon, 19 Feb 2007) | 2 lines Moved misplaced news item. ........ r53826 | martin.v.loewis | 2007-02-19 11:55:19 +0100 (Mon, 19 Feb 2007) | 3 lines Patch #1490190: posixmodule now includes os.chflags() and os.lchflags() functions on platforms where the underlying system calls are available. ........ r53827 | raymond.hettinger | 2007-02-19 19:15:04 +0100 (Mon, 19 Feb 2007) | 1 line Fixup docstrings for merge(). ........ r53829 | raymond.hettinger | 2007-02-19 21:44:04 +0100 (Mon, 19 Feb 2007) | 1 line Fixup set/dict interoperability. ........ r53837 | raymond.hettinger | 2007-02-21 06:20:38 +0100 (Wed, 21 Feb 2007) | 1 line Add itertools.izip_longest(). ........ r53838 | raymond.hettinger | 2007-02-21 18:22:05 +0100 (Wed, 21 Feb 2007) | 1 line Remove filler struct item and fix leak. ........
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
Merged revisions 56154-56264 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r56155 | neal.norwitz | 2007-07-03 08:59:08 +0300 (Tue, 03 Jul 2007) | 1 line Get this test working after converting map to return an iterator ................ r56202 | neal.norwitz | 2007-07-09 04:30:09 +0300 (Mon, 09 Jul 2007) | 37 lines Merged revisions 56124-56201 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r56129 | georg.brandl | 2007-06-30 04:01:01 -0700 (Sat, 30 Jun 2007) | 2 lines Document smtp.SMTPAuthenticationError. ........ r56137 | georg.brandl | 2007-07-01 01:11:35 -0700 (Sun, 01 Jul 2007) | 2 lines Fix a few webbrowser.py problems. ........ r56143 | georg.brandl | 2007-07-02 04:54:28 -0700 (Mon, 02 Jul 2007) | 2 lines Remove duplicate sentence from alarm() doc. ........ r56170 | mark.hammond | 2007-07-03 19:03:10 -0700 (Tue, 03 Jul 2007) | 3 lines copy built files to the PCBuild directory, where tools like distutils or external build processes can find them. ........ r56176 | kurt.kaiser | 2007-07-05 15:03:39 -0700 (Thu, 05 Jul 2007) | 10 lines Many calls to tk.call involve an arglist containing a single tuple. Calls using METH_OLDARGS unpack this tuple; calls using METH_VARARG don't. Tcl's concatenation of args was affected; IDLE doesn't start. Modify Tkapp_Call() to unpack single tuple arglists. Bug 1733943 Ref http://mail.python.org/pipermail/python-checkins/2007-May/060454.html ........ r56177 | neal.norwitz | 2007-07-05 21:13:39 -0700 (Thu, 05 Jul 2007) | 1 line Fix typo in comment ........ ................ r56251 | neal.norwitz | 2007-07-11 10:01:01 +0300 (Wed, 11 Jul 2007) | 1 line Get working with map returning an iterator (had to fix whitespace too) ................ r56255 | thomas.wouters | 2007-07-11 13:41:37 +0300 (Wed, 11 Jul 2007) | 6 lines Clean up merge glitch or copy-paste error (the entire module was duplicated, except the first half even had some more copy-paste errors, referring to listcomps and genexps instead of setcomps) ................ r56256 | thomas.wouters | 2007-07-11 15:16:01 +0300 (Wed, 11 Jul 2007) | 14 lines Dict comprehensions. Still needs doc changes (like many python-3000 features ;-). It generates bytecode similar to: x = {} for k, v in (generator here): x[k] = v except there is no tuple-packing and -unpacking involved. Trivial measurement suggests it's significantly faster than dict(generator here) (in the order of 2 to 3 times as fast) but I have not done extensive measurements. ................ r56263 | guido.van.rossum | 2007-07-11 15:36:26 +0300 (Wed, 11 Jul 2007) | 3 lines Patch 1724999 by Ali Gholami Rudi -- avoid complaints about dict size change during iter in destroy call. ................
19 years ago
Merged revisions 55225-55227,55229-55269 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r55238 | guido.van.rossum | 2007-05-10 16:46:05 -0700 (Thu, 10 May 2007) | 9 lines Merged revisions 55227 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r55227 | guido.van.rossum | 2007-05-10 10:20:15 -0700 (Thu, 10 May 2007) | 2 lines Fix a bug in test_c_api() that caused a negative refcount. ........ ................ r55246 | neal.norwitz | 2007-05-11 00:01:52 -0700 (Fri, 11 May 2007) | 1 line Remove commands.getstatus() it is obsolete. ................ r55248 | neal.norwitz | 2007-05-11 00:29:05 -0700 (Fri, 11 May 2007) | 2 lines Remove bsddb185 support. ................ r55249 | neal.norwitz | 2007-05-11 00:29:50 -0700 (Fri, 11 May 2007) | 1 line Remove bsddb185 module too ................ r55250 | neal.norwitz | 2007-05-11 00:32:13 -0700 (Fri, 11 May 2007) | 1 line bsddb185: Gotta remove from the file checked in, not Setup ................ r55251 | neal.norwitz | 2007-05-11 00:53:26 -0700 (Fri, 11 May 2007) | 1 line Remove obsolete IRIX modules (as much as I could find, there is probably more) ................ r55252 | neal.norwitz | 2007-05-11 00:55:35 -0700 (Fri, 11 May 2007) | 1 line Remove SGI turd. ................ r55254 | georg.brandl | 2007-05-11 03:11:01 -0700 (Fri, 11 May 2007) | 2 lines Add a case for set comprehensions to the "cannot assign to" switch. ................ r55255 | georg.brandl | 2007-05-11 03:11:25 -0700 (Fri, 11 May 2007) | 2 lines Fix wrong imports. ................ r55261 | georg.brandl | 2007-05-11 07:37:48 -0700 (Fri, 11 May 2007) | 2 lines Remove removed tex files. ................ r55262 | georg.brandl | 2007-05-11 08:28:41 -0700 (Fri, 11 May 2007) | 2 lines Commit PEP 3132 implementation. ................ r55264 | georg.brandl | 2007-05-11 08:50:19 -0700 (Fri, 11 May 2007) | 2 lines Check in the inevitable AST version number and format Py_ssize_t with %zd. ................ r55265 | neal.norwitz | 2007-05-11 09:12:22 -0700 (Fri, 11 May 2007) | 1 line Remove mention of os.popen* and popen2.* since these will be removed. ................ r55266 | neal.norwitz | 2007-05-11 09:19:57 -0700 (Fri, 11 May 2007) | 1 line Get doc to build again (almost, the doc is fine) ................ r55267 | neal.norwitz | 2007-05-11 09:21:02 -0700 (Fri, 11 May 2007) | 1 line Really get doc to build (remove use of string module) ................ r55269 | neal.norwitz | 2007-05-11 09:29:43 -0700 (Fri, 11 May 2007) | 1 line Add some notes to cleanup later ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
14 years ago
14 years ago
14 years ago
Merged revisions 61440-61441,61443,61445-61448,61451-61452,61455-61457,61459-61464,61466-61467,61469-61470,61476-61477,61479,61481-61482,61485,61487,61490,61493-61494,61497,61499-61502,61505-61506,61508,61511-61514,61519,61521-61522,61530-61531,61533-61537,61541-61555,61557-61558,61561-61562,61566-61569,61572-61574,61578-61579,61583-61584,61588-61589,61592,61594,61598-61601,61603-61604,61607-61612,61617,61619-61620,61624,61626,61628-61630,61635-61638,61640-61643,61645,61648,61653-61655,61659-61662,61664,61666,61668-61671,61673,61675,61679-61680,61682,61685-61686,61689-61695,61697-61699,61701-61703,61706,61710,61713,61717,61723,61726-61730,61736,61738,61740,61742,61745-61752,61754-61760,61762-61764,61768,61770-61772,61774-61775,61784-61787,61789-61792,61794-61795,61797-61806,61808-61809,61811-61812,61814-61819,61824,61826-61833,61835-61840,61843-61845,61848,61850,61854-61862,61865-61866,61868,61872-61873,61876-61877,61883-61888,61890-61891,61893-61899,61901-61903,61905-61912,61914,61917,61920-61921,61927,61930,61932-61934,61939,61941-61942,61944-61951,61955,61960-61963,61980,61982-61983,61991,61994-61996,62001-62003,62008-62010,62016-62017,62022,62024,62027,62031-62034,62041,62045-62046,62048,62050-62051,62055-62066,62068-62074,62076-62078 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r62048 | georg.brandl | 2008-03-29 23:53:55 -0700 (Sat, 29 Mar 2008) | 2 lines Adapt test_ast to the new ExceptHandler type. ........ r62050 | georg.brandl | 2008-03-30 00:09:22 -0700 (Sun, 30 Mar 2008) | 2 lines Convert test_ast to unittest and add a test for r62049. ........ r62051 | georg.brandl | 2008-03-30 12:00:49 -0700 (Sun, 30 Mar 2008) | 2 lines Make _fields attr for no fields consistent with _attributes attr. ........ r62059 | georg.brandl | 2008-03-30 13:20:39 -0700 (Sun, 30 Mar 2008) | 2 lines Make AST nodes pickleable. ........
18 years ago
Merged revisions 61440-61441,61443,61445-61448,61451-61452,61455-61457,61459-61464,61466-61467,61469-61470,61476-61477,61479,61481-61482,61485,61487,61490,61493-61494,61497,61499-61502,61505-61506,61508,61511-61514,61519,61521-61522,61530-61531,61533-61537,61541-61555,61557-61558,61561-61562,61566-61569,61572-61574,61578-61579,61583-61584,61588-61589,61592,61594,61598-61601,61603-61604,61607-61612,61617,61619-61620,61624,61626,61628-61630,61635-61638,61640-61643,61645,61648,61653-61655,61659-61662,61664,61666,61668-61671,61673,61675,61679-61680,61682,61685-61686,61689-61695,61697-61699,61701-61703,61706,61710,61713,61717,61723,61726-61730,61736,61738,61740,61742,61745-61752,61754-61760,61762-61764,61768,61770-61772,61774-61775,61784-61787,61789-61792,61794-61795,61797-61806,61808-61809,61811-61812,61814-61819,61824,61826-61833,61835-61840,61843-61845,61848,61850,61854-61862,61865-61866,61868,61872-61873,61876-61877,61883-61888,61890-61891,61893-61899,61901-61903,61905-61912,61914,61917,61920-61921,61927,61930,61932-61934,61939,61941-61942,61944-61951,61955,61960-61963,61980,61982-61983,61991,61994-61996,62001-62003,62008-62010,62016-62017,62022,62024,62027,62031-62034,62041,62045-62046,62048,62050-62051,62055-62066,62068-62074,62076-62078 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r62048 | georg.brandl | 2008-03-29 23:53:55 -0700 (Sat, 29 Mar 2008) | 2 lines Adapt test_ast to the new ExceptHandler type. ........ r62050 | georg.brandl | 2008-03-30 00:09:22 -0700 (Sun, 30 Mar 2008) | 2 lines Convert test_ast to unittest and add a test for r62049. ........ r62051 | georg.brandl | 2008-03-30 12:00:49 -0700 (Sun, 30 Mar 2008) | 2 lines Make _fields attr for no fields consistent with _attributes attr. ........ r62059 | georg.brandl | 2008-03-30 13:20:39 -0700 (Sun, 30 Mar 2008) | 2 lines Make AST nodes pickleable. ........
18 years ago
Merged revisions 61440-61441,61443,61445-61448,61451-61452,61455-61457,61459-61464,61466-61467,61469-61470,61476-61477,61479,61481-61482,61485,61487,61490,61493-61494,61497,61499-61502,61505-61506,61508,61511-61514,61519,61521-61522,61530-61531,61533-61537,61541-61555,61557-61558,61561-61562,61566-61569,61572-61574,61578-61579,61583-61584,61588-61589,61592,61594,61598-61601,61603-61604,61607-61612,61617,61619-61620,61624,61626,61628-61630,61635-61638,61640-61643,61645,61648,61653-61655,61659-61662,61664,61666,61668-61671,61673,61675,61679-61680,61682,61685-61686,61689-61695,61697-61699,61701-61703,61706,61710,61713,61717,61723,61726-61730,61736,61738,61740,61742,61745-61752,61754-61760,61762-61764,61768,61770-61772,61774-61775,61784-61787,61789-61792,61794-61795,61797-61806,61808-61809,61811-61812,61814-61819,61824,61826-61833,61835-61840,61843-61845,61848,61850,61854-61862,61865-61866,61868,61872-61873,61876-61877,61883-61888,61890-61891,61893-61899,61901-61903,61905-61912,61914,61917,61920-61921,61927,61930,61932-61934,61939,61941-61942,61944-61951,61955,61960-61963,61980,61982-61983,61991,61994-61996,62001-62003,62008-62010,62016-62017,62022,62024,62027,62031-62034,62041,62045-62046,62048,62050-62051,62055-62066,62068-62074,62076-62078 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r62048 | georg.brandl | 2008-03-29 23:53:55 -0700 (Sat, 29 Mar 2008) | 2 lines Adapt test_ast to the new ExceptHandler type. ........ r62050 | georg.brandl | 2008-03-30 00:09:22 -0700 (Sun, 30 Mar 2008) | 2 lines Convert test_ast to unittest and add a test for r62049. ........ r62051 | georg.brandl | 2008-03-30 12:00:49 -0700 (Sun, 30 Mar 2008) | 2 lines Make _fields attr for no fields consistent with _attributes attr. ........ r62059 | georg.brandl | 2008-03-30 13:20:39 -0700 (Sun, 30 Mar 2008) | 2 lines Make AST nodes pickleable. ........
18 years ago
Merged revisions 61440-61441,61443,61445-61448,61451-61452,61455-61457,61459-61464,61466-61467,61469-61470,61476-61477,61479,61481-61482,61485,61487,61490,61493-61494,61497,61499-61502,61505-61506,61508,61511-61514,61519,61521-61522,61530-61531,61533-61537,61541-61555,61557-61558,61561-61562,61566-61569,61572-61574,61578-61579,61583-61584,61588-61589,61592,61594,61598-61601,61603-61604,61607-61612,61617,61619-61620,61624,61626,61628-61630,61635-61638,61640-61643,61645,61648,61653-61655,61659-61662,61664,61666,61668-61671,61673,61675,61679-61680,61682,61685-61686,61689-61695,61697-61699,61701-61703,61706,61710,61713,61717,61723,61726-61730,61736,61738,61740,61742,61745-61752,61754-61760,61762-61764,61768,61770-61772,61774-61775,61784-61787,61789-61792,61794-61795,61797-61806,61808-61809,61811-61812,61814-61819,61824,61826-61833,61835-61840,61843-61845,61848,61850,61854-61862,61865-61866,61868,61872-61873,61876-61877,61883-61888,61890-61891,61893-61899,61901-61903,61905-61912,61914,61917,61920-61921,61927,61930,61932-61934,61939,61941-61942,61944-61951,61955,61960-61963,61980,61982-61983,61991,61994-61996,62001-62003,62008-62010,62016-62017,62022,62024,62027,62031-62034,62041,62045-62046,62048,62050-62051,62055-62066,62068-62074,62076-62078 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r62048 | georg.brandl | 2008-03-29 23:53:55 -0700 (Sat, 29 Mar 2008) | 2 lines Adapt test_ast to the new ExceptHandler type. ........ r62050 | georg.brandl | 2008-03-30 00:09:22 -0700 (Sun, 30 Mar 2008) | 2 lines Convert test_ast to unittest and add a test for r62049. ........ r62051 | georg.brandl | 2008-03-30 12:00:49 -0700 (Sun, 30 Mar 2008) | 2 lines Make _fields attr for no fields consistent with _attributes attr. ........ r62059 | georg.brandl | 2008-03-30 13:20:39 -0700 (Sun, 30 Mar 2008) | 2 lines Make AST nodes pickleable. ........
18 years ago
Merged revisions 61440-61441,61443,61445-61448,61451-61452,61455-61457,61459-61464,61466-61467,61469-61470,61476-61477,61479,61481-61482,61485,61487,61490,61493-61494,61497,61499-61502,61505-61506,61508,61511-61514,61519,61521-61522,61530-61531,61533-61537,61541-61555,61557-61558,61561-61562,61566-61569,61572-61574,61578-61579,61583-61584,61588-61589,61592,61594,61598-61601,61603-61604,61607-61612,61617,61619-61620,61624,61626,61628-61630,61635-61638,61640-61643,61645,61648,61653-61655,61659-61662,61664,61666,61668-61671,61673,61675,61679-61680,61682,61685-61686,61689-61695,61697-61699,61701-61703,61706,61710,61713,61717,61723,61726-61730,61736,61738,61740,61742,61745-61752,61754-61760,61762-61764,61768,61770-61772,61774-61775,61784-61787,61789-61792,61794-61795,61797-61806,61808-61809,61811-61812,61814-61819,61824,61826-61833,61835-61840,61843-61845,61848,61850,61854-61862,61865-61866,61868,61872-61873,61876-61877,61883-61888,61890-61891,61893-61899,61901-61903,61905-61912,61914,61917,61920-61921,61927,61930,61932-61934,61939,61941-61942,61944-61951,61955,61960-61963,61980,61982-61983,61991,61994-61996,62001-62003,62008-62010,62016-62017,62022,62024,62027,62031-62034,62041,62045-62046,62048,62050-62051,62055-62066,62068-62074,62076-62078 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r62048 | georg.brandl | 2008-03-29 23:53:55 -0700 (Sat, 29 Mar 2008) | 2 lines Adapt test_ast to the new ExceptHandler type. ........ r62050 | georg.brandl | 2008-03-30 00:09:22 -0700 (Sun, 30 Mar 2008) | 2 lines Convert test_ast to unittest and add a test for r62049. ........ r62051 | georg.brandl | 2008-03-30 12:00:49 -0700 (Sun, 30 Mar 2008) | 2 lines Make _fields attr for no fields consistent with _attributes attr. ........ r62059 | georg.brandl | 2008-03-30 13:20:39 -0700 (Sun, 30 Mar 2008) | 2 lines Make AST nodes pickleable. ........
18 years ago
Merged revisions 66974,66977,66984,66989,66992,66994-66996,66998-67000,67007,67015 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r66974 | benjamin.peterson | 2008-10-19 08:59:01 -0500 (Sun, 19 Oct 2008) | 1 line fix compiler warning ........ r66977 | benjamin.peterson | 2008-10-19 14:39:16 -0500 (Sun, 19 Oct 2008) | 1 line mention -n ........ r66984 | armin.ronacher | 2008-10-20 16:29:08 -0500 (Mon, 20 Oct 2008) | 3 lines Fixed #4062, added import for _ast.__version__ to ast to match the documented behavior. ........ r66989 | matthias.klose | 2008-10-21 04:12:25 -0500 (Tue, 21 Oct 2008) | 2 lines - install versioned manpage ........ r66992 | benjamin.peterson | 2008-10-21 15:51:13 -0500 (Tue, 21 Oct 2008) | 1 line make sure to call iteritems() ........ r66994 | amaury.forgeotdarc | 2008-10-21 17:01:38 -0500 (Tue, 21 Oct 2008) | 6 lines #4157 move two test functions out of platform.py. Turn them into unit tests, and correct an obvious typo: (("a", "b") ("c", "d") ("e", "f")) compiles even with the missing commas, but does not execute very well... ........ r66995 | benjamin.peterson | 2008-10-21 17:18:29 -0500 (Tue, 21 Oct 2008) | 1 line return ArgInfo from inspect.getargvalues #4092 ........ r66996 | benjamin.peterson | 2008-10-21 17:20:31 -0500 (Tue, 21 Oct 2008) | 1 line add NEWs note for last change ........ r66998 | benjamin.peterson | 2008-10-22 15:57:43 -0500 (Wed, 22 Oct 2008) | 1 line fix a few typos ........ r66999 | benjamin.peterson | 2008-10-22 16:05:30 -0500 (Wed, 22 Oct 2008) | 1 line and another typo... ........ r67000 | benjamin.peterson | 2008-10-22 16:16:34 -0500 (Wed, 22 Oct 2008) | 1 line fix #4150: pdb's up command didn't work for generators in post-mortem ........ r67007 | benjamin.peterson | 2008-10-23 16:43:48 -0500 (Thu, 23 Oct 2008) | 1 line only nonempty __slots__ don't work ........ r67015 | georg.brandl | 2008-10-25 02:00:52 -0500 (Sat, 25 Oct 2008) | 2 lines Typo fix. ........
17 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
Merged revisions 56154-56264 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r56155 | neal.norwitz | 2007-07-03 08:59:08 +0300 (Tue, 03 Jul 2007) | 1 line Get this test working after converting map to return an iterator ................ r56202 | neal.norwitz | 2007-07-09 04:30:09 +0300 (Mon, 09 Jul 2007) | 37 lines Merged revisions 56124-56201 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r56129 | georg.brandl | 2007-06-30 04:01:01 -0700 (Sat, 30 Jun 2007) | 2 lines Document smtp.SMTPAuthenticationError. ........ r56137 | georg.brandl | 2007-07-01 01:11:35 -0700 (Sun, 01 Jul 2007) | 2 lines Fix a few webbrowser.py problems. ........ r56143 | georg.brandl | 2007-07-02 04:54:28 -0700 (Mon, 02 Jul 2007) | 2 lines Remove duplicate sentence from alarm() doc. ........ r56170 | mark.hammond | 2007-07-03 19:03:10 -0700 (Tue, 03 Jul 2007) | 3 lines copy built files to the PCBuild directory, where tools like distutils or external build processes can find them. ........ r56176 | kurt.kaiser | 2007-07-05 15:03:39 -0700 (Thu, 05 Jul 2007) | 10 lines Many calls to tk.call involve an arglist containing a single tuple. Calls using METH_OLDARGS unpack this tuple; calls using METH_VARARG don't. Tcl's concatenation of args was affected; IDLE doesn't start. Modify Tkapp_Call() to unpack single tuple arglists. Bug 1733943 Ref http://mail.python.org/pipermail/python-checkins/2007-May/060454.html ........ r56177 | neal.norwitz | 2007-07-05 21:13:39 -0700 (Thu, 05 Jul 2007) | 1 line Fix typo in comment ........ ................ r56251 | neal.norwitz | 2007-07-11 10:01:01 +0300 (Wed, 11 Jul 2007) | 1 line Get working with map returning an iterator (had to fix whitespace too) ................ r56255 | thomas.wouters | 2007-07-11 13:41:37 +0300 (Wed, 11 Jul 2007) | 6 lines Clean up merge glitch or copy-paste error (the entire module was duplicated, except the first half even had some more copy-paste errors, referring to listcomps and genexps instead of setcomps) ................ r56256 | thomas.wouters | 2007-07-11 15:16:01 +0300 (Wed, 11 Jul 2007) | 14 lines Dict comprehensions. Still needs doc changes (like many python-3000 features ;-). It generates bytecode similar to: x = {} for k, v in (generator here): x[k] = v except there is no tuple-packing and -unpacking involved. Trivial measurement suggests it's significantly faster than dict(generator here) (in the order of 2 to 3 times as fast) but I have not done extensive measurements. ................ r56263 | guido.van.rossum | 2007-07-11 15:36:26 +0300 (Wed, 11 Jul 2007) | 3 lines Patch 1724999 by Ali Gholami Rudi -- avoid complaints about dict size change during iter in destroy call. ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
Merged revisions 56154-56264 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r56155 | neal.norwitz | 2007-07-03 08:59:08 +0300 (Tue, 03 Jul 2007) | 1 line Get this test working after converting map to return an iterator ................ r56202 | neal.norwitz | 2007-07-09 04:30:09 +0300 (Mon, 09 Jul 2007) | 37 lines Merged revisions 56124-56201 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r56129 | georg.brandl | 2007-06-30 04:01:01 -0700 (Sat, 30 Jun 2007) | 2 lines Document smtp.SMTPAuthenticationError. ........ r56137 | georg.brandl | 2007-07-01 01:11:35 -0700 (Sun, 01 Jul 2007) | 2 lines Fix a few webbrowser.py problems. ........ r56143 | georg.brandl | 2007-07-02 04:54:28 -0700 (Mon, 02 Jul 2007) | 2 lines Remove duplicate sentence from alarm() doc. ........ r56170 | mark.hammond | 2007-07-03 19:03:10 -0700 (Tue, 03 Jul 2007) | 3 lines copy built files to the PCBuild directory, where tools like distutils or external build processes can find them. ........ r56176 | kurt.kaiser | 2007-07-05 15:03:39 -0700 (Thu, 05 Jul 2007) | 10 lines Many calls to tk.call involve an arglist containing a single tuple. Calls using METH_OLDARGS unpack this tuple; calls using METH_VARARG don't. Tcl's concatenation of args was affected; IDLE doesn't start. Modify Tkapp_Call() to unpack single tuple arglists. Bug 1733943 Ref http://mail.python.org/pipermail/python-checkins/2007-May/060454.html ........ r56177 | neal.norwitz | 2007-07-05 21:13:39 -0700 (Thu, 05 Jul 2007) | 1 line Fix typo in comment ........ ................ r56251 | neal.norwitz | 2007-07-11 10:01:01 +0300 (Wed, 11 Jul 2007) | 1 line Get working with map returning an iterator (had to fix whitespace too) ................ r56255 | thomas.wouters | 2007-07-11 13:41:37 +0300 (Wed, 11 Jul 2007) | 6 lines Clean up merge glitch or copy-paste error (the entire module was duplicated, except the first half even had some more copy-paste errors, referring to listcomps and genexps instead of setcomps) ................ r56256 | thomas.wouters | 2007-07-11 15:16:01 +0300 (Wed, 11 Jul 2007) | 14 lines Dict comprehensions. Still needs doc changes (like many python-3000 features ;-). It generates bytecode similar to: x = {} for k, v in (generator here): x[k] = v except there is no tuple-packing and -unpacking involved. Trivial measurement suggests it's significantly faster than dict(generator here) (in the order of 2 to 3 times as fast) but I have not done extensive measurements. ................ r56263 | guido.van.rossum | 2007-07-11 15:36:26 +0300 (Wed, 11 Jul 2007) | 3 lines Patch 1724999 by Ali Gholami Rudi -- avoid complaints about dict size change during iter in destroy call. ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
Merged revisions 56154-56264 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r56155 | neal.norwitz | 2007-07-03 08:59:08 +0300 (Tue, 03 Jul 2007) | 1 line Get this test working after converting map to return an iterator ................ r56202 | neal.norwitz | 2007-07-09 04:30:09 +0300 (Mon, 09 Jul 2007) | 37 lines Merged revisions 56124-56201 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r56129 | georg.brandl | 2007-06-30 04:01:01 -0700 (Sat, 30 Jun 2007) | 2 lines Document smtp.SMTPAuthenticationError. ........ r56137 | georg.brandl | 2007-07-01 01:11:35 -0700 (Sun, 01 Jul 2007) | 2 lines Fix a few webbrowser.py problems. ........ r56143 | georg.brandl | 2007-07-02 04:54:28 -0700 (Mon, 02 Jul 2007) | 2 lines Remove duplicate sentence from alarm() doc. ........ r56170 | mark.hammond | 2007-07-03 19:03:10 -0700 (Tue, 03 Jul 2007) | 3 lines copy built files to the PCBuild directory, where tools like distutils or external build processes can find them. ........ r56176 | kurt.kaiser | 2007-07-05 15:03:39 -0700 (Thu, 05 Jul 2007) | 10 lines Many calls to tk.call involve an arglist containing a single tuple. Calls using METH_OLDARGS unpack this tuple; calls using METH_VARARG don't. Tcl's concatenation of args was affected; IDLE doesn't start. Modify Tkapp_Call() to unpack single tuple arglists. Bug 1733943 Ref http://mail.python.org/pipermail/python-checkins/2007-May/060454.html ........ r56177 | neal.norwitz | 2007-07-05 21:13:39 -0700 (Thu, 05 Jul 2007) | 1 line Fix typo in comment ........ ................ r56251 | neal.norwitz | 2007-07-11 10:01:01 +0300 (Wed, 11 Jul 2007) | 1 line Get working with map returning an iterator (had to fix whitespace too) ................ r56255 | thomas.wouters | 2007-07-11 13:41:37 +0300 (Wed, 11 Jul 2007) | 6 lines Clean up merge glitch or copy-paste error (the entire module was duplicated, except the first half even had some more copy-paste errors, referring to listcomps and genexps instead of setcomps) ................ r56256 | thomas.wouters | 2007-07-11 15:16:01 +0300 (Wed, 11 Jul 2007) | 14 lines Dict comprehensions. Still needs doc changes (like many python-3000 features ;-). It generates bytecode similar to: x = {} for k, v in (generator here): x[k] = v except there is no tuple-packing and -unpacking involved. Trivial measurement suggests it's significantly faster than dict(generator here) (in the order of 2 to 3 times as fast) but I have not done extensive measurements. ................ r56263 | guido.van.rossum | 2007-07-11 15:36:26 +0300 (Wed, 11 Jul 2007) | 3 lines Patch 1724999 by Ali Gholami Rudi -- avoid complaints about dict size change during iter in destroy call. ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
Merged revisions 55225-55227,55229-55269 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r55238 | guido.van.rossum | 2007-05-10 16:46:05 -0700 (Thu, 10 May 2007) | 9 lines Merged revisions 55227 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r55227 | guido.van.rossum | 2007-05-10 10:20:15 -0700 (Thu, 10 May 2007) | 2 lines Fix a bug in test_c_api() that caused a negative refcount. ........ ................ r55246 | neal.norwitz | 2007-05-11 00:01:52 -0700 (Fri, 11 May 2007) | 1 line Remove commands.getstatus() it is obsolete. ................ r55248 | neal.norwitz | 2007-05-11 00:29:05 -0700 (Fri, 11 May 2007) | 2 lines Remove bsddb185 support. ................ r55249 | neal.norwitz | 2007-05-11 00:29:50 -0700 (Fri, 11 May 2007) | 1 line Remove bsddb185 module too ................ r55250 | neal.norwitz | 2007-05-11 00:32:13 -0700 (Fri, 11 May 2007) | 1 line bsddb185: Gotta remove from the file checked in, not Setup ................ r55251 | neal.norwitz | 2007-05-11 00:53:26 -0700 (Fri, 11 May 2007) | 1 line Remove obsolete IRIX modules (as much as I could find, there is probably more) ................ r55252 | neal.norwitz | 2007-05-11 00:55:35 -0700 (Fri, 11 May 2007) | 1 line Remove SGI turd. ................ r55254 | georg.brandl | 2007-05-11 03:11:01 -0700 (Fri, 11 May 2007) | 2 lines Add a case for set comprehensions to the "cannot assign to" switch. ................ r55255 | georg.brandl | 2007-05-11 03:11:25 -0700 (Fri, 11 May 2007) | 2 lines Fix wrong imports. ................ r55261 | georg.brandl | 2007-05-11 07:37:48 -0700 (Fri, 11 May 2007) | 2 lines Remove removed tex files. ................ r55262 | georg.brandl | 2007-05-11 08:28:41 -0700 (Fri, 11 May 2007) | 2 lines Commit PEP 3132 implementation. ................ r55264 | georg.brandl | 2007-05-11 08:50:19 -0700 (Fri, 11 May 2007) | 2 lines Check in the inevitable AST version number and format Py_ssize_t with %zd. ................ r55265 | neal.norwitz | 2007-05-11 09:12:22 -0700 (Fri, 11 May 2007) | 1 line Remove mention of os.popen* and popen2.* since these will be removed. ................ r55266 | neal.norwitz | 2007-05-11 09:19:57 -0700 (Fri, 11 May 2007) | 1 line Get doc to build again (almost, the doc is fine) ................ r55267 | neal.norwitz | 2007-05-11 09:21:02 -0700 (Fri, 11 May 2007) | 1 line Really get doc to build (remove use of string module) ................ r55269 | neal.norwitz | 2007-05-11 09:29:43 -0700 (Fri, 11 May 2007) | 1 line Add some notes to cleanup later ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
Merged revisions 55225-55227,55229-55269 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r55238 | guido.van.rossum | 2007-05-10 16:46:05 -0700 (Thu, 10 May 2007) | 9 lines Merged revisions 55227 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r55227 | guido.van.rossum | 2007-05-10 10:20:15 -0700 (Thu, 10 May 2007) | 2 lines Fix a bug in test_c_api() that caused a negative refcount. ........ ................ r55246 | neal.norwitz | 2007-05-11 00:01:52 -0700 (Fri, 11 May 2007) | 1 line Remove commands.getstatus() it is obsolete. ................ r55248 | neal.norwitz | 2007-05-11 00:29:05 -0700 (Fri, 11 May 2007) | 2 lines Remove bsddb185 support. ................ r55249 | neal.norwitz | 2007-05-11 00:29:50 -0700 (Fri, 11 May 2007) | 1 line Remove bsddb185 module too ................ r55250 | neal.norwitz | 2007-05-11 00:32:13 -0700 (Fri, 11 May 2007) | 1 line bsddb185: Gotta remove from the file checked in, not Setup ................ r55251 | neal.norwitz | 2007-05-11 00:53:26 -0700 (Fri, 11 May 2007) | 1 line Remove obsolete IRIX modules (as much as I could find, there is probably more) ................ r55252 | neal.norwitz | 2007-05-11 00:55:35 -0700 (Fri, 11 May 2007) | 1 line Remove SGI turd. ................ r55254 | georg.brandl | 2007-05-11 03:11:01 -0700 (Fri, 11 May 2007) | 2 lines Add a case for set comprehensions to the "cannot assign to" switch. ................ r55255 | georg.brandl | 2007-05-11 03:11:25 -0700 (Fri, 11 May 2007) | 2 lines Fix wrong imports. ................ r55261 | georg.brandl | 2007-05-11 07:37:48 -0700 (Fri, 11 May 2007) | 2 lines Remove removed tex files. ................ r55262 | georg.brandl | 2007-05-11 08:28:41 -0700 (Fri, 11 May 2007) | 2 lines Commit PEP 3132 implementation. ................ r55264 | georg.brandl | 2007-05-11 08:50:19 -0700 (Fri, 11 May 2007) | 2 lines Check in the inevitable AST version number and format Py_ssize_t with %zd. ................ r55265 | neal.norwitz | 2007-05-11 09:12:22 -0700 (Fri, 11 May 2007) | 1 line Remove mention of os.popen* and popen2.* since these will be removed. ................ r55266 | neal.norwitz | 2007-05-11 09:19:57 -0700 (Fri, 11 May 2007) | 1 line Get doc to build again (almost, the doc is fine) ................ r55267 | neal.norwitz | 2007-05-11 09:21:02 -0700 (Fri, 11 May 2007) | 1 line Really get doc to build (remove use of string module) ................ r55269 | neal.norwitz | 2007-05-11 09:29:43 -0700 (Fri, 11 May 2007) | 1 line Add some notes to cleanup later ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
Merged revisions 55225-55227,55229-55269 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r55238 | guido.van.rossum | 2007-05-10 16:46:05 -0700 (Thu, 10 May 2007) | 9 lines Merged revisions 55227 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r55227 | guido.van.rossum | 2007-05-10 10:20:15 -0700 (Thu, 10 May 2007) | 2 lines Fix a bug in test_c_api() that caused a negative refcount. ........ ................ r55246 | neal.norwitz | 2007-05-11 00:01:52 -0700 (Fri, 11 May 2007) | 1 line Remove commands.getstatus() it is obsolete. ................ r55248 | neal.norwitz | 2007-05-11 00:29:05 -0700 (Fri, 11 May 2007) | 2 lines Remove bsddb185 support. ................ r55249 | neal.norwitz | 2007-05-11 00:29:50 -0700 (Fri, 11 May 2007) | 1 line Remove bsddb185 module too ................ r55250 | neal.norwitz | 2007-05-11 00:32:13 -0700 (Fri, 11 May 2007) | 1 line bsddb185: Gotta remove from the file checked in, not Setup ................ r55251 | neal.norwitz | 2007-05-11 00:53:26 -0700 (Fri, 11 May 2007) | 1 line Remove obsolete IRIX modules (as much as I could find, there is probably more) ................ r55252 | neal.norwitz | 2007-05-11 00:55:35 -0700 (Fri, 11 May 2007) | 1 line Remove SGI turd. ................ r55254 | georg.brandl | 2007-05-11 03:11:01 -0700 (Fri, 11 May 2007) | 2 lines Add a case for set comprehensions to the "cannot assign to" switch. ................ r55255 | georg.brandl | 2007-05-11 03:11:25 -0700 (Fri, 11 May 2007) | 2 lines Fix wrong imports. ................ r55261 | georg.brandl | 2007-05-11 07:37:48 -0700 (Fri, 11 May 2007) | 2 lines Remove removed tex files. ................ r55262 | georg.brandl | 2007-05-11 08:28:41 -0700 (Fri, 11 May 2007) | 2 lines Commit PEP 3132 implementation. ................ r55264 | georg.brandl | 2007-05-11 08:50:19 -0700 (Fri, 11 May 2007) | 2 lines Check in the inevitable AST version number and format Py_ssize_t with %zd. ................ r55265 | neal.norwitz | 2007-05-11 09:12:22 -0700 (Fri, 11 May 2007) | 1 line Remove mention of os.popen* and popen2.* since these will be removed. ................ r55266 | neal.norwitz | 2007-05-11 09:19:57 -0700 (Fri, 11 May 2007) | 1 line Get doc to build again (almost, the doc is fine) ................ r55267 | neal.norwitz | 2007-05-11 09:21:02 -0700 (Fri, 11 May 2007) | 1 line Really get doc to build (remove use of string module) ................ r55269 | neal.norwitz | 2007-05-11 09:29:43 -0700 (Fri, 11 May 2007) | 1 line Add some notes to cleanup later ................
19 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-35224: PEP 572 Implementation (#10497) * Add tokenization of := - Add token to Include/token.h. Add token to documentation in Doc/library/token.rst. - Run `./python Lib/token.py` to regenerate Lib/token.py. - Update Parser/tokenizer.c: add case to handle `:=`. * Add initial usage of := in grammar. * Update Python.asdl to match the grammar updates. Regenerated Include/Python-ast.h and Python/Python-ast.c * Update AST and compiler files in Python/ast.c and Python/compile.c. Basic functionality, this isn't scoped properly * Regenerate Lib/symbol.py using `./python Lib/symbol.py` * Tests - Fix failing tests in test_parser.py due to changes in token numbers for internal representation * Tests - Add simple test for := token * Tests - Add simple tests for named expressions using expr and suite * Tests - Update number of levels for nested expressions to prevent stack overflow * Update symbol table to handle NamedExpr * Update Grammar to allow assignment expressions in if statements. Regenerate Python/graminit.c accordingly using `make regen-grammar` * Tests - Add additional tests for named expressions in RoundtripLegalSyntaxTestCase, based on examples and information directly from PEP 572 Note: failing tests are currently commented out (4 out of 24 tests currently fail) * Tests - Add temporary syntax test failure tests in test_parser.py Note: There is an outstanding TODO for this -- syntax tests need to be moved to a different file (presumably test_syntax.py), but this is covering what needs to be tested at the moment, and it's more convenient to run a single test for the time being * Add support for allowing assignment expressions as function argument annotations. Uncomment tests for these cases because they all pass now! * Tests - Move existing syntax tests out of test_parser.py and into test_named_expressions.py. Refactor syntax tests to use unittest * Add TargetScopeError exception to extend SyntaxError Note: This simply creates the TargetScopeError exception, it is not yet used anywhere * Tests - Update tests per PEP 572 Continue refactoring test suite: The named expression test suite now checks for any invalid cases that throw exceptions (no longer limited to SyntaxErrors), assignment tests to ensure that variables are properly assigned, and scope tests to ensure that variable availability and values are correct Note: - There are still tests that are marked to skip, as they are not yet implemented - There are approximately 300 lines of the PEP that have not yet been addressed, though these may be deferred * Documentation - Small updates to XXX/todo comments - Remove XXX from child description in ast.c - Add comment with number of previously supported nested expressions for 3.7.X in test_parser.py * Fix assert in seq_for_testlist() * Cleanup - Denote "Not implemented -- No keyword args" on failing test case. Fix PEP8 error for blank lines at beginning of test classes in test_parser.py * Tests - Wrap all file opens in `with...as` to ensure files are closed * WIP: handle f(a := 1) * Tests and Cleanup - No longer skips keyword arg test. Keyword arg test now uses a simpler test case and does not rely on an external file. Remove print statements from ast.c * Tests - Refactor last remaining test case that relied on on external file to use a simpler test case without the dependency * Tests - Add better description of remaning skipped tests. Add test checking scope when using assignment expression in a function argument * Tests - Add test for nested comprehension, testing value and scope. Fix variable name in skipped comprehension scope test * Handle restriction of LHS for named expressions - can only assign to LHS of type NAME. Specifically, restrict assignment to tuples This adds an alternative set_context specifically for named expressions, set_namedexpr_context. Thus, context is now set differently for standard assignment versus assignment for named expressions in order to handle restrictions. * Tests - Update negative test case for assigning to lambda to match new error message. Add negative test case for assigning to tuple * Tests - Reorder test cases to group invalid syntax cases and named assignment target errors * Tests - Update test case for named expression in function argument - check that result and variable are set correctly * Todo - Add todo for TargetScopeError based on Guido's comment (https://github.com/python/cpython/commit/2b3acd37bdfc2d35e5094228c6684050d2aa8b0a#r30472562) * Tests - Add named expression tests for assignment operator in function arguments Note: One of two tests are skipped, as function arguments are currently treating an assignment expression inside of parenthesis as one child, which does not properly catch the named expression, nor does it count arguments properly * Add NamedStore to expr_context. Regenerate related code with `make regen-ast` * Add usage of NamedStore to ast_for_named_expr in ast.c. Update occurances of checking for Store to also handle NamedStore where appropriate * Add ste_comprehension to _symtable_entry to track if the namespace is a comprehension. Initialize ste_comprehension to 0. Set set_comprehension to 1 in symtable_handle_comprehension * s/symtable_add_def/symtable_add_def_helper. Add symtable_add_def to handle grabbing st->st_cur and passing it to symtable_add_def_helper. This now allows us to call the original code from symtable_add_def by instead calling symtable_add_def_helper with a different ste. * Refactor symtable_record_directive to take lineno and col_offset as arguments instead of stmt_ty. This allows symtable_record_directive to be used for stmt_ty and expr_ty * Handle elevating scope for named expressions in comprehensions. * Handle error for usage of named expression inside a class block * Tests - No longer skip scope tests. Add additional scope tests * Cleanup - Update error message for named expression within a comprehension within a class. Update comments. Add assert for symtable_extend_namedexpr_scope to validate that we always find at least a ModuleScope if we don't find a Class or FunctionScope * Cleanup - Add missing case for NamedStore in expr_context_name. Remove unused var in set_namedexpr_content * Refactor - Consolidate set_context and set_namedexpr_context to reduce duplicated code. Special cases for named expressions are handled by checking if ctx is NamedStore * Cleanup - Add additional use cases for ast_for_namedexpr in usage comment. Fix multiple blank lines in test_named_expressions * Tests - Remove unnecessary test case. Renumber test case function names * Remove TargetScopeError for now. Will add back if needed * Cleanup - Small comment nit for consistency * Handle positional argument check with named expression * Add TargetScopeError exception definition. Add documentation for TargetScopeError in c-api docs. Throw TargetScopeError instead of SyntaxError when using a named expression in a comprehension within a class scope * Increase stack size for parser by 200. This is a minimal change (approx. 5kb) and should not have an impact on any systems. Update parser test to allow 99 nested levels again * Add TargetScopeError to exception_hierarchy.txt for test_baseexception.py_ * Tests - Major update for named expression tests, both in test_named_expressions and test_parser - Add test for TargetScopeError - Add tests for named expressions in comprehension scope and edge cases - Add tests for named expressions in function arguments (declarations and call sites) - Reorganize tests to group them more logically * Cleanup - Remove unnecessary comment * Cleanup - Comment nitpicks * Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0) - Add check for LHS types to detect a parenthesis then a name (see note) - Add test for this scenario - Update tests for changed error message for named assignment to a tuple (also, see note) Note: This caused issues with the previous error handling for named assignment to a LHS that contained an expression, such as a tuple. Thus, the check for the LHS of a named expression must be changed to be more specific if we wish to maintain the previous error messages * Cleanup - Wrap lines more strictly in test file * Revert "Explicitly disallow assignment expressions to a name inside parentheses, e.g.: ((x) := 0)" This reverts commit f1531400ca7d7a2d148830c8ac703f041740896d. * Add NEWS.d entry * Tests - Fix error in test_pickle.test_exceptions by adding TargetScopeError to list of exceptions * Tests - Update error message tests to reflect improved messaging convention (s/can't/cannot) * Remove cases that cannot be reached in compile.c. Small linting update. * Update Grammar/Tokens to add COLONEQUAL. Regenerate all files * Update TargetScopeError PRE_INIT and POST_INIT, as this was purposefully left out when fixing rebase conflicts * Add NamedStore back and regenerate files * Pass along line number and end col info for named expression * Simplify News entry * Fix compiler warning and explicity mark fallthrough
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
bpo-33416: Add end positions to Python AST (GH-11605) The majority of this PR is tediously passing `end_lineno` and `end_col_offset` everywhere. Here are non-trivial points: * It is not possible to reconstruct end positions in AST "on the fly", some information is lost after an AST node is constructed, so we need two more attributes for every AST node `end_lineno` and `end_col_offset`. * I add end position information to both CST and AST. Although it may be technically possible to avoid adding end positions to CST, the code becomes more cumbersome and less efficient. * Since the end position is not known for non-leaf CST nodes while the next token is added, this requires a bit of extra care (see `_PyNode_FinalizeEndPos`). Unless I made some mistake, the algorithm should be linear. * For statements, I "trim" the end position of suites to not include the terminal newlines and dedent (this seems to be what people would expect), for example in ```python class C: pass pass ``` the end line and end column for the class definition is (2, 8). * For `end_col_offset` I use the common Python convention for indexing, for example for `pass` the `end_col_offset` is 4 (not 3), so that `[0:4]` gives one the source code that corresponds to the node. * I added a helper function `ast.get_source_segment()`, to get source text segment corresponding to a given AST node. It is also useful for testing. An (inevitable) downside of this PR is that AST now takes almost 25% more memory. I think however it is probably justified by the benefits.
7 years ago
  1. /* File automatically generated by Parser/asdl_c.py. */
  2. #include <stddef.h>
  3. #include "Python.h"
  4. #include "Python-ast.h"
  5. #include "structmember.h" // PyMemberDef
  6. typedef struct {
  7. int initialized;
  8. PyObject *AST_type;
  9. PyObject *Add_singleton;
  10. PyObject *Add_type;
  11. PyObject *And_singleton;
  12. PyObject *And_type;
  13. PyObject *AnnAssign_type;
  14. PyObject *Assert_type;
  15. PyObject *Assign_type;
  16. PyObject *AsyncFor_type;
  17. PyObject *AsyncFunctionDef_type;
  18. PyObject *AsyncWith_type;
  19. PyObject *Attribute_type;
  20. PyObject *AugAssign_type;
  21. PyObject *Await_type;
  22. PyObject *BinOp_type;
  23. PyObject *BitAnd_singleton;
  24. PyObject *BitAnd_type;
  25. PyObject *BitOr_singleton;
  26. PyObject *BitOr_type;
  27. PyObject *BitXor_singleton;
  28. PyObject *BitXor_type;
  29. PyObject *BoolOp_type;
  30. PyObject *Break_type;
  31. PyObject *Call_type;
  32. PyObject *ClassDef_type;
  33. PyObject *Compare_type;
  34. PyObject *Constant_type;
  35. PyObject *Continue_type;
  36. PyObject *Del_singleton;
  37. PyObject *Del_type;
  38. PyObject *Delete_type;
  39. PyObject *DictComp_type;
  40. PyObject *Dict_type;
  41. PyObject *Div_singleton;
  42. PyObject *Div_type;
  43. PyObject *Eq_singleton;
  44. PyObject *Eq_type;
  45. PyObject *ExceptHandler_type;
  46. PyObject *Expr_type;
  47. PyObject *Expression_type;
  48. PyObject *FloorDiv_singleton;
  49. PyObject *FloorDiv_type;
  50. PyObject *For_type;
  51. PyObject *FormattedValue_type;
  52. PyObject *FunctionDef_type;
  53. PyObject *FunctionType_type;
  54. PyObject *GeneratorExp_type;
  55. PyObject *Global_type;
  56. PyObject *GtE_singleton;
  57. PyObject *GtE_type;
  58. PyObject *Gt_singleton;
  59. PyObject *Gt_type;
  60. PyObject *IfExp_type;
  61. PyObject *If_type;
  62. PyObject *ImportFrom_type;
  63. PyObject *Import_type;
  64. PyObject *In_singleton;
  65. PyObject *In_type;
  66. PyObject *Interactive_type;
  67. PyObject *Invert_singleton;
  68. PyObject *Invert_type;
  69. PyObject *IsNot_singleton;
  70. PyObject *IsNot_type;
  71. PyObject *Is_singleton;
  72. PyObject *Is_type;
  73. PyObject *JoinedStr_type;
  74. PyObject *LShift_singleton;
  75. PyObject *LShift_type;
  76. PyObject *Lambda_type;
  77. PyObject *ListComp_type;
  78. PyObject *List_type;
  79. PyObject *Load_singleton;
  80. PyObject *Load_type;
  81. PyObject *LtE_singleton;
  82. PyObject *LtE_type;
  83. PyObject *Lt_singleton;
  84. PyObject *Lt_type;
  85. PyObject *MatMult_singleton;
  86. PyObject *MatMult_type;
  87. PyObject *Mod_singleton;
  88. PyObject *Mod_type;
  89. PyObject *Module_type;
  90. PyObject *Mult_singleton;
  91. PyObject *Mult_type;
  92. PyObject *Name_type;
  93. PyObject *NamedExpr_type;
  94. PyObject *Nonlocal_type;
  95. PyObject *NotEq_singleton;
  96. PyObject *NotEq_type;
  97. PyObject *NotIn_singleton;
  98. PyObject *NotIn_type;
  99. PyObject *Not_singleton;
  100. PyObject *Not_type;
  101. PyObject *Or_singleton;
  102. PyObject *Or_type;
  103. PyObject *Pass_type;
  104. PyObject *Pow_singleton;
  105. PyObject *Pow_type;
  106. PyObject *RShift_singleton;
  107. PyObject *RShift_type;
  108. PyObject *Raise_type;
  109. PyObject *Return_type;
  110. PyObject *SetComp_type;
  111. PyObject *Set_type;
  112. PyObject *Slice_type;
  113. PyObject *Starred_type;
  114. PyObject *Store_singleton;
  115. PyObject *Store_type;
  116. PyObject *Sub_singleton;
  117. PyObject *Sub_type;
  118. PyObject *Subscript_type;
  119. PyObject *Try_type;
  120. PyObject *Tuple_type;
  121. PyObject *TypeIgnore_type;
  122. PyObject *UAdd_singleton;
  123. PyObject *UAdd_type;
  124. PyObject *USub_singleton;
  125. PyObject *USub_type;
  126. PyObject *UnaryOp_type;
  127. PyObject *While_type;
  128. PyObject *With_type;
  129. PyObject *YieldFrom_type;
  130. PyObject *Yield_type;
  131. PyObject *__dict__;
  132. PyObject *__doc__;
  133. PyObject *__module__;
  134. PyObject *_attributes;
  135. PyObject *_fields;
  136. PyObject *alias_type;
  137. PyObject *annotation;
  138. PyObject *arg;
  139. PyObject *arg_type;
  140. PyObject *args;
  141. PyObject *argtypes;
  142. PyObject *arguments_type;
  143. PyObject *asname;
  144. PyObject *ast;
  145. PyObject *attr;
  146. PyObject *bases;
  147. PyObject *body;
  148. PyObject *boolop_type;
  149. PyObject *cause;
  150. PyObject *cmpop_type;
  151. PyObject *col_offset;
  152. PyObject *comparators;
  153. PyObject *comprehension_type;
  154. PyObject *context_expr;
  155. PyObject *conversion;
  156. PyObject *ctx;
  157. PyObject *decorator_list;
  158. PyObject *defaults;
  159. PyObject *elt;
  160. PyObject *elts;
  161. PyObject *end_col_offset;
  162. PyObject *end_lineno;
  163. PyObject *exc;
  164. PyObject *excepthandler_type;
  165. PyObject *expr_context_type;
  166. PyObject *expr_type;
  167. PyObject *finalbody;
  168. PyObject *format_spec;
  169. PyObject *func;
  170. PyObject *generators;
  171. PyObject *handlers;
  172. PyObject *id;
  173. PyObject *ifs;
  174. PyObject *is_async;
  175. PyObject *items;
  176. PyObject *iter;
  177. PyObject *key;
  178. PyObject *keys;
  179. PyObject *keyword_type;
  180. PyObject *keywords;
  181. PyObject *kind;
  182. PyObject *kw_defaults;
  183. PyObject *kwarg;
  184. PyObject *kwonlyargs;
  185. PyObject *left;
  186. PyObject *level;
  187. PyObject *lineno;
  188. PyObject *lower;
  189. PyObject *mod_type;
  190. PyObject *module;
  191. PyObject *msg;
  192. PyObject *name;
  193. PyObject *names;
  194. PyObject *op;
  195. PyObject *operand;
  196. PyObject *operator_type;
  197. PyObject *ops;
  198. PyObject *optional_vars;
  199. PyObject *orelse;
  200. PyObject *posonlyargs;
  201. PyObject *returns;
  202. PyObject *right;
  203. PyObject *simple;
  204. PyObject *slice;
  205. PyObject *step;
  206. PyObject *stmt_type;
  207. PyObject *tag;
  208. PyObject *target;
  209. PyObject *targets;
  210. PyObject *test;
  211. PyObject *type;
  212. PyObject *type_comment;
  213. PyObject *type_ignore_type;
  214. PyObject *type_ignores;
  215. PyObject *unaryop_type;
  216. PyObject *upper;
  217. PyObject *value;
  218. PyObject *values;
  219. PyObject *vararg;
  220. PyObject *withitem_type;
  221. } astmodulestate;
  222. #define astmodulestate(o) ((astmodulestate *)PyModule_GetState(o))
  223. static int astmodule_clear(PyObject *module)
  224. {
  225. Py_CLEAR(astmodulestate(module)->AST_type);
  226. Py_CLEAR(astmodulestate(module)->Add_singleton);
  227. Py_CLEAR(astmodulestate(module)->Add_type);
  228. Py_CLEAR(astmodulestate(module)->And_singleton);
  229. Py_CLEAR(astmodulestate(module)->And_type);
  230. Py_CLEAR(astmodulestate(module)->AnnAssign_type);
  231. Py_CLEAR(astmodulestate(module)->Assert_type);
  232. Py_CLEAR(astmodulestate(module)->Assign_type);
  233. Py_CLEAR(astmodulestate(module)->AsyncFor_type);
  234. Py_CLEAR(astmodulestate(module)->AsyncFunctionDef_type);
  235. Py_CLEAR(astmodulestate(module)->AsyncWith_type);
  236. Py_CLEAR(astmodulestate(module)->Attribute_type);
  237. Py_CLEAR(astmodulestate(module)->AugAssign_type);
  238. Py_CLEAR(astmodulestate(module)->Await_type);
  239. Py_CLEAR(astmodulestate(module)->BinOp_type);
  240. Py_CLEAR(astmodulestate(module)->BitAnd_singleton);
  241. Py_CLEAR(astmodulestate(module)->BitAnd_type);
  242. Py_CLEAR(astmodulestate(module)->BitOr_singleton);
  243. Py_CLEAR(astmodulestate(module)->BitOr_type);
  244. Py_CLEAR(astmodulestate(module)->BitXor_singleton);
  245. Py_CLEAR(astmodulestate(module)->BitXor_type);
  246. Py_CLEAR(astmodulestate(module)->BoolOp_type);
  247. Py_CLEAR(astmodulestate(module)->Break_type);
  248. Py_CLEAR(astmodulestate(module)->Call_type);
  249. Py_CLEAR(astmodulestate(module)->ClassDef_type);
  250. Py_CLEAR(astmodulestate(module)->Compare_type);
  251. Py_CLEAR(astmodulestate(module)->Constant_type);
  252. Py_CLEAR(astmodulestate(module)->Continue_type);
  253. Py_CLEAR(astmodulestate(module)->Del_singleton);
  254. Py_CLEAR(astmodulestate(module)->Del_type);
  255. Py_CLEAR(astmodulestate(module)->Delete_type);
  256. Py_CLEAR(astmodulestate(module)->DictComp_type);
  257. Py_CLEAR(astmodulestate(module)->Dict_type);
  258. Py_CLEAR(astmodulestate(module)->Div_singleton);
  259. Py_CLEAR(astmodulestate(module)->Div_type);
  260. Py_CLEAR(astmodulestate(module)->Eq_singleton);
  261. Py_CLEAR(astmodulestate(module)->Eq_type);
  262. Py_CLEAR(astmodulestate(module)->ExceptHandler_type);
  263. Py_CLEAR(astmodulestate(module)->Expr_type);
  264. Py_CLEAR(astmodulestate(module)->Expression_type);
  265. Py_CLEAR(astmodulestate(module)->FloorDiv_singleton);
  266. Py_CLEAR(astmodulestate(module)->FloorDiv_type);
  267. Py_CLEAR(astmodulestate(module)->For_type);
  268. Py_CLEAR(astmodulestate(module)->FormattedValue_type);
  269. Py_CLEAR(astmodulestate(module)->FunctionDef_type);
  270. Py_CLEAR(astmodulestate(module)->FunctionType_type);
  271. Py_CLEAR(astmodulestate(module)->GeneratorExp_type);
  272. Py_CLEAR(astmodulestate(module)->Global_type);
  273. Py_CLEAR(astmodulestate(module)->GtE_singleton);
  274. Py_CLEAR(astmodulestate(module)->GtE_type);
  275. Py_CLEAR(astmodulestate(module)->Gt_singleton);
  276. Py_CLEAR(astmodulestate(module)->Gt_type);
  277. Py_CLEAR(astmodulestate(module)->IfExp_type);
  278. Py_CLEAR(astmodulestate(module)->If_type);
  279. Py_CLEAR(astmodulestate(module)->ImportFrom_type);
  280. Py_CLEAR(astmodulestate(module)->Import_type);
  281. Py_CLEAR(astmodulestate(module)->In_singleton);
  282. Py_CLEAR(astmodulestate(module)->In_type);
  283. Py_CLEAR(astmodulestate(module)->Interactive_type);
  284. Py_CLEAR(astmodulestate(module)->Invert_singleton);
  285. Py_CLEAR(astmodulestate(module)->Invert_type);
  286. Py_CLEAR(astmodulestate(module)->IsNot_singleton);
  287. Py_CLEAR(astmodulestate(module)->IsNot_type);
  288. Py_CLEAR(astmodulestate(module)->Is_singleton);
  289. Py_CLEAR(astmodulestate(module)->Is_type);
  290. Py_CLEAR(astmodulestate(module)->JoinedStr_type);
  291. Py_CLEAR(astmodulestate(module)->LShift_singleton);
  292. Py_CLEAR(astmodulestate(module)->LShift_type);
  293. Py_CLEAR(astmodulestate(module)->Lambda_type);
  294. Py_CLEAR(astmodulestate(module)->ListComp_type);
  295. Py_CLEAR(astmodulestate(module)->List_type);
  296. Py_CLEAR(astmodulestate(module)->Load_singleton);
  297. Py_CLEAR(astmodulestate(module)->Load_type);
  298. Py_CLEAR(astmodulestate(module)->LtE_singleton);
  299. Py_CLEAR(astmodulestate(module)->LtE_type);
  300. Py_CLEAR(astmodulestate(module)->Lt_singleton);
  301. Py_CLEAR(astmodulestate(module)->Lt_type);
  302. Py_CLEAR(astmodulestate(module)->MatMult_singleton);
  303. Py_CLEAR(astmodulestate(module)->MatMult_type);
  304. Py_CLEAR(astmodulestate(module)->Mod_singleton);
  305. Py_CLEAR(astmodulestate(module)->Mod_type);
  306. Py_CLEAR(astmodulestate(module)->Module_type);
  307. Py_CLEAR(astmodulestate(module)->Mult_singleton);
  308. Py_CLEAR(astmodulestate(module)->Mult_type);
  309. Py_CLEAR(astmodulestate(module)->Name_type);
  310. Py_CLEAR(astmodulestate(module)->NamedExpr_type);
  311. Py_CLEAR(astmodulestate(module)->Nonlocal_type);
  312. Py_CLEAR(astmodulestate(module)->NotEq_singleton);
  313. Py_CLEAR(astmodulestate(module)->NotEq_type);
  314. Py_CLEAR(astmodulestate(module)->NotIn_singleton);
  315. Py_CLEAR(astmodulestate(module)->NotIn_type);
  316. Py_CLEAR(astmodulestate(module)->Not_singleton);
  317. Py_CLEAR(astmodulestate(module)->Not_type);
  318. Py_CLEAR(astmodulestate(module)->Or_singleton);
  319. Py_CLEAR(astmodulestate(module)->Or_type);
  320. Py_CLEAR(astmodulestate(module)->Pass_type);
  321. Py_CLEAR(astmodulestate(module)->Pow_singleton);
  322. Py_CLEAR(astmodulestate(module)->Pow_type);
  323. Py_CLEAR(astmodulestate(module)->RShift_singleton);
  324. Py_CLEAR(astmodulestate(module)->RShift_type);
  325. Py_CLEAR(astmodulestate(module)->Raise_type);
  326. Py_CLEAR(astmodulestate(module)->Return_type);
  327. Py_CLEAR(astmodulestate(module)->SetComp_type);
  328. Py_CLEAR(astmodulestate(module)->Set_type);
  329. Py_CLEAR(astmodulestate(module)->Slice_type);
  330. Py_CLEAR(astmodulestate(module)->Starred_type);
  331. Py_CLEAR(astmodulestate(module)->Store_singleton);
  332. Py_CLEAR(astmodulestate(module)->Store_type);
  333. Py_CLEAR(astmodulestate(module)->Sub_singleton);
  334. Py_CLEAR(astmodulestate(module)->Sub_type);
  335. Py_CLEAR(astmodulestate(module)->Subscript_type);
  336. Py_CLEAR(astmodulestate(module)->Try_type);
  337. Py_CLEAR(astmodulestate(module)->Tuple_type);
  338. Py_CLEAR(astmodulestate(module)->TypeIgnore_type);
  339. Py_CLEAR(astmodulestate(module)->UAdd_singleton);
  340. Py_CLEAR(astmodulestate(module)->UAdd_type);
  341. Py_CLEAR(astmodulestate(module)->USub_singleton);
  342. Py_CLEAR(astmodulestate(module)->USub_type);
  343. Py_CLEAR(astmodulestate(module)->UnaryOp_type);
  344. Py_CLEAR(astmodulestate(module)->While_type);
  345. Py_CLEAR(astmodulestate(module)->With_type);
  346. Py_CLEAR(astmodulestate(module)->YieldFrom_type);
  347. Py_CLEAR(astmodulestate(module)->Yield_type);
  348. Py_CLEAR(astmodulestate(module)->__dict__);
  349. Py_CLEAR(astmodulestate(module)->__doc__);
  350. Py_CLEAR(astmodulestate(module)->__module__);
  351. Py_CLEAR(astmodulestate(module)->_attributes);
  352. Py_CLEAR(astmodulestate(module)->_fields);
  353. Py_CLEAR(astmodulestate(module)->alias_type);
  354. Py_CLEAR(astmodulestate(module)->annotation);
  355. Py_CLEAR(astmodulestate(module)->arg);
  356. Py_CLEAR(astmodulestate(module)->arg_type);
  357. Py_CLEAR(astmodulestate(module)->args);
  358. Py_CLEAR(astmodulestate(module)->argtypes);
  359. Py_CLEAR(astmodulestate(module)->arguments_type);
  360. Py_CLEAR(astmodulestate(module)->asname);
  361. Py_CLEAR(astmodulestate(module)->ast);
  362. Py_CLEAR(astmodulestate(module)->attr);
  363. Py_CLEAR(astmodulestate(module)->bases);
  364. Py_CLEAR(astmodulestate(module)->body);
  365. Py_CLEAR(astmodulestate(module)->boolop_type);
  366. Py_CLEAR(astmodulestate(module)->cause);
  367. Py_CLEAR(astmodulestate(module)->cmpop_type);
  368. Py_CLEAR(astmodulestate(module)->col_offset);
  369. Py_CLEAR(astmodulestate(module)->comparators);
  370. Py_CLEAR(astmodulestate(module)->comprehension_type);
  371. Py_CLEAR(astmodulestate(module)->context_expr);
  372. Py_CLEAR(astmodulestate(module)->conversion);
  373. Py_CLEAR(astmodulestate(module)->ctx);
  374. Py_CLEAR(astmodulestate(module)->decorator_list);
  375. Py_CLEAR(astmodulestate(module)->defaults);
  376. Py_CLEAR(astmodulestate(module)->elt);
  377. Py_CLEAR(astmodulestate(module)->elts);
  378. Py_CLEAR(astmodulestate(module)->end_col_offset);
  379. Py_CLEAR(astmodulestate(module)->end_lineno);
  380. Py_CLEAR(astmodulestate(module)->exc);
  381. Py_CLEAR(astmodulestate(module)->excepthandler_type);
  382. Py_CLEAR(astmodulestate(module)->expr_context_type);
  383. Py_CLEAR(astmodulestate(module)->expr_type);
  384. Py_CLEAR(astmodulestate(module)->finalbody);
  385. Py_CLEAR(astmodulestate(module)->format_spec);
  386. Py_CLEAR(astmodulestate(module)->func);
  387. Py_CLEAR(astmodulestate(module)->generators);
  388. Py_CLEAR(astmodulestate(module)->handlers);
  389. Py_CLEAR(astmodulestate(module)->id);
  390. Py_CLEAR(astmodulestate(module)->ifs);
  391. Py_CLEAR(astmodulestate(module)->is_async);
  392. Py_CLEAR(astmodulestate(module)->items);
  393. Py_CLEAR(astmodulestate(module)->iter);
  394. Py_CLEAR(astmodulestate(module)->key);
  395. Py_CLEAR(astmodulestate(module)->keys);
  396. Py_CLEAR(astmodulestate(module)->keyword_type);
  397. Py_CLEAR(astmodulestate(module)->keywords);
  398. Py_CLEAR(astmodulestate(module)->kind);
  399. Py_CLEAR(astmodulestate(module)->kw_defaults);
  400. Py_CLEAR(astmodulestate(module)->kwarg);
  401. Py_CLEAR(astmodulestate(module)->kwonlyargs);
  402. Py_CLEAR(astmodulestate(module)->left);
  403. Py_CLEAR(astmodulestate(module)->level);
  404. Py_CLEAR(astmodulestate(module)->lineno);
  405. Py_CLEAR(astmodulestate(module)->lower);
  406. Py_CLEAR(astmodulestate(module)->mod_type);
  407. Py_CLEAR(astmodulestate(module)->module);
  408. Py_CLEAR(astmodulestate(module)->msg);
  409. Py_CLEAR(astmodulestate(module)->name);
  410. Py_CLEAR(astmodulestate(module)->names);
  411. Py_CLEAR(astmodulestate(module)->op);
  412. Py_CLEAR(astmodulestate(module)->operand);
  413. Py_CLEAR(astmodulestate(module)->operator_type);
  414. Py_CLEAR(astmodulestate(module)->ops);
  415. Py_CLEAR(astmodulestate(module)->optional_vars);
  416. Py_CLEAR(astmodulestate(module)->orelse);
  417. Py_CLEAR(astmodulestate(module)->posonlyargs);
  418. Py_CLEAR(astmodulestate(module)->returns);
  419. Py_CLEAR(astmodulestate(module)->right);
  420. Py_CLEAR(astmodulestate(module)->simple);
  421. Py_CLEAR(astmodulestate(module)->slice);
  422. Py_CLEAR(astmodulestate(module)->step);
  423. Py_CLEAR(astmodulestate(module)->stmt_type);
  424. Py_CLEAR(astmodulestate(module)->tag);
  425. Py_CLEAR(astmodulestate(module)->target);
  426. Py_CLEAR(astmodulestate(module)->targets);
  427. Py_CLEAR(astmodulestate(module)->test);
  428. Py_CLEAR(astmodulestate(module)->type);
  429. Py_CLEAR(astmodulestate(module)->type_comment);
  430. Py_CLEAR(astmodulestate(module)->type_ignore_type);
  431. Py_CLEAR(astmodulestate(module)->type_ignores);
  432. Py_CLEAR(astmodulestate(module)->unaryop_type);
  433. Py_CLEAR(astmodulestate(module)->upper);
  434. Py_CLEAR(astmodulestate(module)->value);
  435. Py_CLEAR(astmodulestate(module)->values);
  436. Py_CLEAR(astmodulestate(module)->vararg);
  437. Py_CLEAR(astmodulestate(module)->withitem_type);
  438. return 0;
  439. }
  440. static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
  441. {
  442. Py_VISIT(astmodulestate(module)->AST_type);
  443. Py_VISIT(astmodulestate(module)->Add_singleton);
  444. Py_VISIT(astmodulestate(module)->Add_type);
  445. Py_VISIT(astmodulestate(module)->And_singleton);
  446. Py_VISIT(astmodulestate(module)->And_type);
  447. Py_VISIT(astmodulestate(module)->AnnAssign_type);
  448. Py_VISIT(astmodulestate(module)->Assert_type);
  449. Py_VISIT(astmodulestate(module)->Assign_type);
  450. Py_VISIT(astmodulestate(module)->AsyncFor_type);
  451. Py_VISIT(astmodulestate(module)->AsyncFunctionDef_type);
  452. Py_VISIT(astmodulestate(module)->AsyncWith_type);
  453. Py_VISIT(astmodulestate(module)->Attribute_type);
  454. Py_VISIT(astmodulestate(module)->AugAssign_type);
  455. Py_VISIT(astmodulestate(module)->Await_type);
  456. Py_VISIT(astmodulestate(module)->BinOp_type);
  457. Py_VISIT(astmodulestate(module)->BitAnd_singleton);
  458. Py_VISIT(astmodulestate(module)->BitAnd_type);
  459. Py_VISIT(astmodulestate(module)->BitOr_singleton);
  460. Py_VISIT(astmodulestate(module)->BitOr_type);
  461. Py_VISIT(astmodulestate(module)->BitXor_singleton);
  462. Py_VISIT(astmodulestate(module)->BitXor_type);
  463. Py_VISIT(astmodulestate(module)->BoolOp_type);
  464. Py_VISIT(astmodulestate(module)->Break_type);
  465. Py_VISIT(astmodulestate(module)->Call_type);
  466. Py_VISIT(astmodulestate(module)->ClassDef_type);
  467. Py_VISIT(astmodulestate(module)->Compare_type);
  468. Py_VISIT(astmodulestate(module)->Constant_type);
  469. Py_VISIT(astmodulestate(module)->Continue_type);
  470. Py_VISIT(astmodulestate(module)->Del_singleton);
  471. Py_VISIT(astmodulestate(module)->Del_type);
  472. Py_VISIT(astmodulestate(module)->Delete_type);
  473. Py_VISIT(astmodulestate(module)->DictComp_type);
  474. Py_VISIT(astmodulestate(module)->Dict_type);
  475. Py_VISIT(astmodulestate(module)->Div_singleton);
  476. Py_VISIT(astmodulestate(module)->Div_type);
  477. Py_VISIT(astmodulestate(module)->Eq_singleton);
  478. Py_VISIT(astmodulestate(module)->Eq_type);
  479. Py_VISIT(astmodulestate(module)->ExceptHandler_type);
  480. Py_VISIT(astmodulestate(module)->Expr_type);
  481. Py_VISIT(astmodulestate(module)->Expression_type);
  482. Py_VISIT(astmodulestate(module)->FloorDiv_singleton);
  483. Py_VISIT(astmodulestate(module)->FloorDiv_type);
  484. Py_VISIT(astmodulestate(module)->For_type);
  485. Py_VISIT(astmodulestate(module)->FormattedValue_type);
  486. Py_VISIT(astmodulestate(module)->FunctionDef_type);
  487. Py_VISIT(astmodulestate(module)->FunctionType_type);
  488. Py_VISIT(astmodulestate(module)->GeneratorExp_type);
  489. Py_VISIT(astmodulestate(module)->Global_type);
  490. Py_VISIT(astmodulestate(module)->GtE_singleton);
  491. Py_VISIT(astmodulestate(module)->GtE_type);
  492. Py_VISIT(astmodulestate(module)->Gt_singleton);
  493. Py_VISIT(astmodulestate(module)->Gt_type);
  494. Py_VISIT(astmodulestate(module)->IfExp_type);
  495. Py_VISIT(astmodulestate(module)->If_type);
  496. Py_VISIT(astmodulestate(module)->ImportFrom_type);
  497. Py_VISIT(astmodulestate(module)->Import_type);
  498. Py_VISIT(astmodulestate(module)->In_singleton);
  499. Py_VISIT(astmodulestate(module)->In_type);
  500. Py_VISIT(astmodulestate(module)->Interactive_type);
  501. Py_VISIT(astmodulestate(module)->Invert_singleton);
  502. Py_VISIT(astmodulestate(module)->Invert_type);
  503. Py_VISIT(astmodulestate(module)->IsNot_singleton);
  504. Py_VISIT(astmodulestate(module)->IsNot_type);
  505. Py_VISIT(astmodulestate(module)->Is_singleton);
  506. Py_VISIT(astmodulestate(module)->Is_type);
  507. Py_VISIT(astmodulestate(module)->JoinedStr_type);
  508. Py_VISIT(astmodulestate(module)->LShift_singleton);
  509. Py_VISIT(astmodulestate(module)->LShift_type);
  510. Py_VISIT(astmodulestate(module)->Lambda_type);
  511. Py_VISIT(astmodulestate(module)->ListComp_type);
  512. Py_VISIT(astmodulestate(module)->List_type);
  513. Py_VISIT(astmodulestate(module)->Load_singleton);
  514. Py_VISIT(astmodulestate(module)->Load_type);
  515. Py_VISIT(astmodulestate(module)->LtE_singleton);
  516. Py_VISIT(astmodulestate(module)->LtE_type);
  517. Py_VISIT(astmodulestate(module)->Lt_singleton);
  518. Py_VISIT(astmodulestate(module)->Lt_type);
  519. Py_VISIT(astmodulestate(module)->MatMult_singleton);
  520. Py_VISIT(astmodulestate(module)->MatMult_type);
  521. Py_VISIT(astmodulestate(module)->Mod_singleton);
  522. Py_VISIT(astmodulestate(module)->Mod_type);
  523. Py_VISIT(astmodulestate(module)->Module_type);
  524. Py_VISIT(astmodulestate(module)->Mult_singleton);
  525. Py_VISIT(astmodulestate(module)->Mult_type);
  526. Py_VISIT(astmodulestate(module)->Name_type);
  527. Py_VISIT(astmodulestate(module)->NamedExpr_type);
  528. Py_VISIT(astmodulestate(module)->Nonlocal_type);
  529. Py_VISIT(astmodulestate(module)->NotEq_singleton);
  530. Py_VISIT(astmodulestate(module)->NotEq_type);
  531. Py_VISIT(astmodulestate(module)->NotIn_singleton);
  532. Py_VISIT(astmodulestate(module)->NotIn_type);
  533. Py_VISIT(astmodulestate(module)->Not_singleton);
  534. Py_VISIT(astmodulestate(module)->Not_type);
  535. Py_VISIT(astmodulestate(module)->Or_singleton);
  536. Py_VISIT(astmodulestate(module)->Or_type);
  537. Py_VISIT(astmodulestate(module)->Pass_type);
  538. Py_VISIT(astmodulestate(module)->Pow_singleton);
  539. Py_VISIT(astmodulestate(module)->Pow_type);
  540. Py_VISIT(astmodulestate(module)->RShift_singleton);
  541. Py_VISIT(astmodulestate(module)->RShift_type);
  542. Py_VISIT(astmodulestate(module)->Raise_type);
  543. Py_VISIT(astmodulestate(module)->Return_type);
  544. Py_VISIT(astmodulestate(module)->SetComp_type);
  545. Py_VISIT(astmodulestate(module)->Set_type);
  546. Py_VISIT(astmodulestate(module)->Slice_type);
  547. Py_VISIT(astmodulestate(module)->Starred_type);
  548. Py_VISIT(astmodulestate(module)->Store_singleton);
  549. Py_VISIT(astmodulestate(module)->Store_type);
  550. Py_VISIT(astmodulestate(module)->Sub_singleton);
  551. Py_VISIT(astmodulestate(module)->Sub_type);
  552. Py_VISIT(astmodulestate(module)->Subscript_type);
  553. Py_VISIT(astmodulestate(module)->Try_type);
  554. Py_VISIT(astmodulestate(module)->Tuple_type);
  555. Py_VISIT(astmodulestate(module)->TypeIgnore_type);
  556. Py_VISIT(astmodulestate(module)->UAdd_singleton);
  557. Py_VISIT(astmodulestate(module)->UAdd_type);
  558. Py_VISIT(astmodulestate(module)->USub_singleton);
  559. Py_VISIT(astmodulestate(module)->USub_type);
  560. Py_VISIT(astmodulestate(module)->UnaryOp_type);
  561. Py_VISIT(astmodulestate(module)->While_type);
  562. Py_VISIT(astmodulestate(module)->With_type);
  563. Py_VISIT(astmodulestate(module)->YieldFrom_type);
  564. Py_VISIT(astmodulestate(module)->Yield_type);
  565. Py_VISIT(astmodulestate(module)->__dict__);
  566. Py_VISIT(astmodulestate(module)->__doc__);
  567. Py_VISIT(astmodulestate(module)->__module__);
  568. Py_VISIT(astmodulestate(module)->_attributes);
  569. Py_VISIT(astmodulestate(module)->_fields);
  570. Py_VISIT(astmodulestate(module)->alias_type);
  571. Py_VISIT(astmodulestate(module)->annotation);
  572. Py_VISIT(astmodulestate(module)->arg);
  573. Py_VISIT(astmodulestate(module)->arg_type);
  574. Py_VISIT(astmodulestate(module)->args);
  575. Py_VISIT(astmodulestate(module)->argtypes);
  576. Py_VISIT(astmodulestate(module)->arguments_type);
  577. Py_VISIT(astmodulestate(module)->asname);
  578. Py_VISIT(astmodulestate(module)->ast);
  579. Py_VISIT(astmodulestate(module)->attr);
  580. Py_VISIT(astmodulestate(module)->bases);
  581. Py_VISIT(astmodulestate(module)->body);
  582. Py_VISIT(astmodulestate(module)->boolop_type);
  583. Py_VISIT(astmodulestate(module)->cause);
  584. Py_VISIT(astmodulestate(module)->cmpop_type);
  585. Py_VISIT(astmodulestate(module)->col_offset);
  586. Py_VISIT(astmodulestate(module)->comparators);
  587. Py_VISIT(astmodulestate(module)->comprehension_type);
  588. Py_VISIT(astmodulestate(module)->context_expr);
  589. Py_VISIT(astmodulestate(module)->conversion);
  590. Py_VISIT(astmodulestate(module)->ctx);
  591. Py_VISIT(astmodulestate(module)->decorator_list);
  592. Py_VISIT(astmodulestate(module)->defaults);
  593. Py_VISIT(astmodulestate(module)->elt);
  594. Py_VISIT(astmodulestate(module)->elts);
  595. Py_VISIT(astmodulestate(module)->end_col_offset);
  596. Py_VISIT(astmodulestate(module)->end_lineno);
  597. Py_VISIT(astmodulestate(module)->exc);
  598. Py_VISIT(astmodulestate(module)->excepthandler_type);
  599. Py_VISIT(astmodulestate(module)->expr_context_type);
  600. Py_VISIT(astmodulestate(module)->expr_type);
  601. Py_VISIT(astmodulestate(module)->finalbody);
  602. Py_VISIT(astmodulestate(module)->format_spec);
  603. Py_VISIT(astmodulestate(module)->func);
  604. Py_VISIT(astmodulestate(module)->generators);
  605. Py_VISIT(astmodulestate(module)->handlers);
  606. Py_VISIT(astmodulestate(module)->id);
  607. Py_VISIT(astmodulestate(module)->ifs);
  608. Py_VISIT(astmodulestate(module)->is_async);
  609. Py_VISIT(astmodulestate(module)->items);
  610. Py_VISIT(astmodulestate(module)->iter);
  611. Py_VISIT(astmodulestate(module)->key);
  612. Py_VISIT(astmodulestate(module)->keys);
  613. Py_VISIT(astmodulestate(module)->keyword_type);
  614. Py_VISIT(astmodulestate(module)->keywords);
  615. Py_VISIT(astmodulestate(module)->kind);
  616. Py_VISIT(astmodulestate(module)->kw_defaults);
  617. Py_VISIT(astmodulestate(module)->kwarg);
  618. Py_VISIT(astmodulestate(module)->kwonlyargs);
  619. Py_VISIT(astmodulestate(module)->left);
  620. Py_VISIT(astmodulestate(module)->level);
  621. Py_VISIT(astmodulestate(module)->lineno);
  622. Py_VISIT(astmodulestate(module)->lower);
  623. Py_VISIT(astmodulestate(module)->mod_type);
  624. Py_VISIT(astmodulestate(module)->module);
  625. Py_VISIT(astmodulestate(module)->msg);
  626. Py_VISIT(astmodulestate(module)->name);
  627. Py_VISIT(astmodulestate(module)->names);
  628. Py_VISIT(astmodulestate(module)->op);
  629. Py_VISIT(astmodulestate(module)->operand);
  630. Py_VISIT(astmodulestate(module)->operator_type);
  631. Py_VISIT(astmodulestate(module)->ops);
  632. Py_VISIT(astmodulestate(module)->optional_vars);
  633. Py_VISIT(astmodulestate(module)->orelse);
  634. Py_VISIT(astmodulestate(module)->posonlyargs);
  635. Py_VISIT(astmodulestate(module)->returns);
  636. Py_VISIT(astmodulestate(module)->right);
  637. Py_VISIT(astmodulestate(module)->simple);
  638. Py_VISIT(astmodulestate(module)->slice);
  639. Py_VISIT(astmodulestate(module)->step);
  640. Py_VISIT(astmodulestate(module)->stmt_type);
  641. Py_VISIT(astmodulestate(module)->tag);
  642. Py_VISIT(astmodulestate(module)->target);
  643. Py_VISIT(astmodulestate(module)->targets);
  644. Py_VISIT(astmodulestate(module)->test);
  645. Py_VISIT(astmodulestate(module)->type);
  646. Py_VISIT(astmodulestate(module)->type_comment);
  647. Py_VISIT(astmodulestate(module)->type_ignore_type);
  648. Py_VISIT(astmodulestate(module)->type_ignores);
  649. Py_VISIT(astmodulestate(module)->unaryop_type);
  650. Py_VISIT(astmodulestate(module)->upper);
  651. Py_VISIT(astmodulestate(module)->value);
  652. Py_VISIT(astmodulestate(module)->values);
  653. Py_VISIT(astmodulestate(module)->vararg);
  654. Py_VISIT(astmodulestate(module)->withitem_type);
  655. return 0;
  656. }
  657. static void astmodule_free(void* module) {
  658. astmodule_clear((PyObject*)module);
  659. }
  660. static struct PyModuleDef _astmodule = {
  661. PyModuleDef_HEAD_INIT,
  662. "_ast",
  663. NULL,
  664. sizeof(astmodulestate),
  665. NULL,
  666. NULL,
  667. astmodule_traverse,
  668. astmodule_clear,
  669. astmodule_free,
  670. };
  671. #define astmodulestate_global ((astmodulestate *)PyModule_GetState(PyState_FindModule(&_astmodule)))
  672. static int init_identifiers(void)
  673. {
  674. astmodulestate *state = astmodulestate_global;
  675. if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0;
  676. if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0;
  677. if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0;
  678. if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0;
  679. if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0;
  680. if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0;
  681. if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return 0;
  682. if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0;
  683. if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0;
  684. if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0;
  685. if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return 0;
  686. if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0;
  687. if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0;
  688. if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0;
  689. if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0;
  690. if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return 0;
  691. if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return 0;
  692. if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return 0;
  693. if ((state->conversion = PyUnicode_InternFromString("conversion")) == NULL) return 0;
  694. if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0;
  695. if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0;
  696. if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0;
  697. if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0;
  698. if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0;
  699. if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0;
  700. if ((state->end_lineno = PyUnicode_InternFromString("end_lineno")) == NULL) return 0;
  701. if ((state->exc = PyUnicode_InternFromString("exc")) == NULL) return 0;
  702. if ((state->finalbody = PyUnicode_InternFromString("finalbody")) == NULL) return 0;
  703. if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return 0;
  704. if ((state->func = PyUnicode_InternFromString("func")) == NULL) return 0;
  705. if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return 0;
  706. if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return 0;
  707. if ((state->id = PyUnicode_InternFromString("id")) == NULL) return 0;
  708. if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return 0;
  709. if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return 0;
  710. if ((state->items = PyUnicode_InternFromString("items")) == NULL) return 0;
  711. if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return 0;
  712. if ((state->key = PyUnicode_InternFromString("key")) == NULL) return 0;
  713. if ((state->keys = PyUnicode_InternFromString("keys")) == NULL) return 0;
  714. if ((state->keywords = PyUnicode_InternFromString("keywords")) == NULL) return 0;
  715. if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return 0;
  716. if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return 0;
  717. if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return 0;
  718. if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return 0;
  719. if ((state->left = PyUnicode_InternFromString("left")) == NULL) return 0;
  720. if ((state->level = PyUnicode_InternFromString("level")) == NULL) return 0;
  721. if ((state->lineno = PyUnicode_InternFromString("lineno")) == NULL) return 0;
  722. if ((state->lower = PyUnicode_InternFromString("lower")) == NULL) return 0;
  723. if ((state->module = PyUnicode_InternFromString("module")) == NULL) return 0;
  724. if ((state->msg = PyUnicode_InternFromString("msg")) == NULL) return 0;
  725. if ((state->name = PyUnicode_InternFromString("name")) == NULL) return 0;
  726. if ((state->names = PyUnicode_InternFromString("names")) == NULL) return 0;
  727. if ((state->op = PyUnicode_InternFromString("op")) == NULL) return 0;
  728. if ((state->operand = PyUnicode_InternFromString("operand")) == NULL) return 0;
  729. if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return 0;
  730. if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return 0;
  731. if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return 0;
  732. if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return 0;
  733. if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return 0;
  734. if ((state->right = PyUnicode_InternFromString("right")) == NULL) return 0;
  735. if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return 0;
  736. if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return 0;
  737. if ((state->step = PyUnicode_InternFromString("step")) == NULL) return 0;
  738. if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return 0;
  739. if ((state->target = PyUnicode_InternFromString("target")) == NULL) return 0;
  740. if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return 0;
  741. if ((state->test = PyUnicode_InternFromString("test")) == NULL) return 0;
  742. if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0;
  743. if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0;
  744. if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0;
  745. if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0;
  746. if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0;
  747. if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0;
  748. if ((state->vararg = PyUnicode_InternFromString("vararg")) == NULL) return 0;
  749. return 1;
  750. };
  751. static PyObject* ast2obj_mod(void*);
  752. static const char * const Module_fields[]={
  753. "body",
  754. "type_ignores",
  755. };
  756. static const char * const Interactive_fields[]={
  757. "body",
  758. };
  759. static const char * const Expression_fields[]={
  760. "body",
  761. };
  762. static const char * const FunctionType_fields[]={
  763. "argtypes",
  764. "returns",
  765. };
  766. static const char * const stmt_attributes[] = {
  767. "lineno",
  768. "col_offset",
  769. "end_lineno",
  770. "end_col_offset",
  771. };
  772. static PyObject* ast2obj_stmt(void*);
  773. static const char * const FunctionDef_fields[]={
  774. "name",
  775. "args",
  776. "body",
  777. "decorator_list",
  778. "returns",
  779. "type_comment",
  780. };
  781. static const char * const AsyncFunctionDef_fields[]={
  782. "name",
  783. "args",
  784. "body",
  785. "decorator_list",
  786. "returns",
  787. "type_comment",
  788. };
  789. static const char * const ClassDef_fields[]={
  790. "name",
  791. "bases",
  792. "keywords",
  793. "body",
  794. "decorator_list",
  795. };
  796. static const char * const Return_fields[]={
  797. "value",
  798. };
  799. static const char * const Delete_fields[]={
  800. "targets",
  801. };
  802. static const char * const Assign_fields[]={
  803. "targets",
  804. "value",
  805. "type_comment",
  806. };
  807. static const char * const AugAssign_fields[]={
  808. "target",
  809. "op",
  810. "value",
  811. };
  812. static const char * const AnnAssign_fields[]={
  813. "target",
  814. "annotation",
  815. "value",
  816. "simple",
  817. };
  818. static const char * const For_fields[]={
  819. "target",
  820. "iter",
  821. "body",
  822. "orelse",
  823. "type_comment",
  824. };
  825. static const char * const AsyncFor_fields[]={
  826. "target",
  827. "iter",
  828. "body",
  829. "orelse",
  830. "type_comment",
  831. };
  832. static const char * const While_fields[]={
  833. "test",
  834. "body",
  835. "orelse",
  836. };
  837. static const char * const If_fields[]={
  838. "test",
  839. "body",
  840. "orelse",
  841. };
  842. static const char * const With_fields[]={
  843. "items",
  844. "body",
  845. "type_comment",
  846. };
  847. static const char * const AsyncWith_fields[]={
  848. "items",
  849. "body",
  850. "type_comment",
  851. };
  852. static const char * const Raise_fields[]={
  853. "exc",
  854. "cause",
  855. };
  856. static const char * const Try_fields[]={
  857. "body",
  858. "handlers",
  859. "orelse",
  860. "finalbody",
  861. };
  862. static const char * const Assert_fields[]={
  863. "test",
  864. "msg",
  865. };
  866. static const char * const Import_fields[]={
  867. "names",
  868. };
  869. static const char * const ImportFrom_fields[]={
  870. "module",
  871. "names",
  872. "level",
  873. };
  874. static const char * const Global_fields[]={
  875. "names",
  876. };
  877. static const char * const Nonlocal_fields[]={
  878. "names",
  879. };
  880. static const char * const Expr_fields[]={
  881. "value",
  882. };
  883. static const char * const expr_attributes[] = {
  884. "lineno",
  885. "col_offset",
  886. "end_lineno",
  887. "end_col_offset",
  888. };
  889. static PyObject* ast2obj_expr(void*);
  890. static const char * const BoolOp_fields[]={
  891. "op",
  892. "values",
  893. };
  894. static const char * const NamedExpr_fields[]={
  895. "target",
  896. "value",
  897. };
  898. static const char * const BinOp_fields[]={
  899. "left",
  900. "op",
  901. "right",
  902. };
  903. static const char * const UnaryOp_fields[]={
  904. "op",
  905. "operand",
  906. };
  907. static const char * const Lambda_fields[]={
  908. "args",
  909. "body",
  910. };
  911. static const char * const IfExp_fields[]={
  912. "test",
  913. "body",
  914. "orelse",
  915. };
  916. static const char * const Dict_fields[]={
  917. "keys",
  918. "values",
  919. };
  920. static const char * const Set_fields[]={
  921. "elts",
  922. };
  923. static const char * const ListComp_fields[]={
  924. "elt",
  925. "generators",
  926. };
  927. static const char * const SetComp_fields[]={
  928. "elt",
  929. "generators",
  930. };
  931. static const char * const DictComp_fields[]={
  932. "key",
  933. "value",
  934. "generators",
  935. };
  936. static const char * const GeneratorExp_fields[]={
  937. "elt",
  938. "generators",
  939. };
  940. static const char * const Await_fields[]={
  941. "value",
  942. };
  943. static const char * const Yield_fields[]={
  944. "value",
  945. };
  946. static const char * const YieldFrom_fields[]={
  947. "value",
  948. };
  949. static const char * const Compare_fields[]={
  950. "left",
  951. "ops",
  952. "comparators",
  953. };
  954. static const char * const Call_fields[]={
  955. "func",
  956. "args",
  957. "keywords",
  958. };
  959. static const char * const FormattedValue_fields[]={
  960. "value",
  961. "conversion",
  962. "format_spec",
  963. };
  964. static const char * const JoinedStr_fields[]={
  965. "values",
  966. };
  967. static const char * const Constant_fields[]={
  968. "value",
  969. "kind",
  970. };
  971. static const char * const Attribute_fields[]={
  972. "value",
  973. "attr",
  974. "ctx",
  975. };
  976. static const char * const Subscript_fields[]={
  977. "value",
  978. "slice",
  979. "ctx",
  980. };
  981. static const char * const Starred_fields[]={
  982. "value",
  983. "ctx",
  984. };
  985. static const char * const Name_fields[]={
  986. "id",
  987. "ctx",
  988. };
  989. static const char * const List_fields[]={
  990. "elts",
  991. "ctx",
  992. };
  993. static const char * const Tuple_fields[]={
  994. "elts",
  995. "ctx",
  996. };
  997. static const char * const Slice_fields[]={
  998. "lower",
  999. "upper",
  1000. "step",
  1001. };
  1002. static PyObject* ast2obj_expr_context(expr_context_ty);
  1003. static PyObject* ast2obj_boolop(boolop_ty);
  1004. static PyObject* ast2obj_operator(operator_ty);
  1005. static PyObject* ast2obj_unaryop(unaryop_ty);
  1006. static PyObject* ast2obj_cmpop(cmpop_ty);
  1007. static PyObject* ast2obj_comprehension(void*);
  1008. static const char * const comprehension_fields[]={
  1009. "target",
  1010. "iter",
  1011. "ifs",
  1012. "is_async",
  1013. };
  1014. static const char * const excepthandler_attributes[] = {
  1015. "lineno",
  1016. "col_offset",
  1017. "end_lineno",
  1018. "end_col_offset",
  1019. };
  1020. static PyObject* ast2obj_excepthandler(void*);
  1021. static const char * const ExceptHandler_fields[]={
  1022. "type",
  1023. "name",
  1024. "body",
  1025. };
  1026. static PyObject* ast2obj_arguments(void*);
  1027. static const char * const arguments_fields[]={
  1028. "posonlyargs",
  1029. "args",
  1030. "vararg",
  1031. "kwonlyargs",
  1032. "kw_defaults",
  1033. "kwarg",
  1034. "defaults",
  1035. };
  1036. static PyObject* ast2obj_arg(void*);
  1037. static const char * const arg_attributes[] = {
  1038. "lineno",
  1039. "col_offset",
  1040. "end_lineno",
  1041. "end_col_offset",
  1042. };
  1043. static const char * const arg_fields[]={
  1044. "arg",
  1045. "annotation",
  1046. "type_comment",
  1047. };
  1048. static PyObject* ast2obj_keyword(void*);
  1049. static const char * const keyword_attributes[] = {
  1050. "lineno",
  1051. "col_offset",
  1052. "end_lineno",
  1053. "end_col_offset",
  1054. };
  1055. static const char * const keyword_fields[]={
  1056. "arg",
  1057. "value",
  1058. };
  1059. static PyObject* ast2obj_alias(void*);
  1060. static const char * const alias_fields[]={
  1061. "name",
  1062. "asname",
  1063. };
  1064. static PyObject* ast2obj_withitem(void*);
  1065. static const char * const withitem_fields[]={
  1066. "context_expr",
  1067. "optional_vars",
  1068. };
  1069. static PyObject* ast2obj_type_ignore(void*);
  1070. static const char * const TypeIgnore_fields[]={
  1071. "lineno",
  1072. "tag",
  1073. };
  1074. typedef struct {
  1075. PyObject_HEAD
  1076. PyObject *dict;
  1077. } AST_object;
  1078. static void
  1079. ast_dealloc(AST_object *self)
  1080. {
  1081. /* bpo-31095: UnTrack is needed before calling any callbacks */
  1082. PyTypeObject *tp = Py_TYPE(self);
  1083. PyObject_GC_UnTrack(self);
  1084. Py_CLEAR(self->dict);
  1085. freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
  1086. assert(free_func != NULL);
  1087. free_func(self);
  1088. Py_DECREF(tp);
  1089. }
  1090. static int
  1091. ast_traverse(AST_object *self, visitproc visit, void *arg)
  1092. {
  1093. Py_VISIT(Py_TYPE(self));
  1094. Py_VISIT(self->dict);
  1095. return 0;
  1096. }
  1097. static int
  1098. ast_clear(AST_object *self)
  1099. {
  1100. Py_CLEAR(self->dict);
  1101. return 0;
  1102. }
  1103. static int
  1104. ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
  1105. {
  1106. Py_ssize_t i, numfields = 0;
  1107. int res = -1;
  1108. PyObject *key, *value, *fields;
  1109. if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), astmodulestate_global->_fields, &fields) < 0) {
  1110. goto cleanup;
  1111. }
  1112. if (fields) {
  1113. numfields = PySequence_Size(fields);
  1114. if (numfields == -1) {
  1115. goto cleanup;
  1116. }
  1117. }
  1118. res = 0; /* if no error occurs, this stays 0 to the end */
  1119. if (numfields < PyTuple_GET_SIZE(args)) {
  1120. PyErr_Format(PyExc_TypeError, "%.400s constructor takes at most "
  1121. "%zd positional argument%s",
  1122. _PyType_Name(Py_TYPE(self)),
  1123. numfields, numfields == 1 ? "" : "s");
  1124. res = -1;
  1125. goto cleanup;
  1126. }
  1127. for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
  1128. /* cannot be reached when fields is NULL */
  1129. PyObject *name = PySequence_GetItem(fields, i);
  1130. if (!name) {
  1131. res = -1;
  1132. goto cleanup;
  1133. }
  1134. res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i));
  1135. Py_DECREF(name);
  1136. if (res < 0) {
  1137. goto cleanup;
  1138. }
  1139. }
  1140. if (kw) {
  1141. i = 0; /* needed by PyDict_Next */
  1142. while (PyDict_Next(kw, &i, &key, &value)) {
  1143. int contains = PySequence_Contains(fields, key);
  1144. if (contains == -1) {
  1145. res = -1;
  1146. goto cleanup;
  1147. } else if (contains == 1) {
  1148. Py_ssize_t p = PySequence_Index(fields, key);
  1149. if (p == -1) {
  1150. res = -1;
  1151. goto cleanup;
  1152. }
  1153. if (p < PyTuple_GET_SIZE(args)) {
  1154. PyErr_Format(PyExc_TypeError,
  1155. "%.400s got multiple values for argument '%U'",
  1156. Py_TYPE(self)->tp_name, key);
  1157. res = -1;
  1158. goto cleanup;
  1159. }
  1160. }
  1161. res = PyObject_SetAttr(self, key, value);
  1162. if (res < 0) {
  1163. goto cleanup;
  1164. }
  1165. }
  1166. }
  1167. cleanup:
  1168. Py_XDECREF(fields);
  1169. return res;
  1170. }
  1171. /* Pickling support */
  1172. static PyObject *
  1173. ast_type_reduce(PyObject *self, PyObject *unused)
  1174. {
  1175. PyObject *dict;
  1176. if (_PyObject_LookupAttr(self, astmodulestate_global->__dict__, &dict) < 0) {
  1177. return NULL;
  1178. }
  1179. if (dict) {
  1180. return Py_BuildValue("O()N", Py_TYPE(self), dict);
  1181. }
  1182. return Py_BuildValue("O()", Py_TYPE(self));
  1183. }
  1184. static PyMemberDef ast_type_members[] = {
  1185. {"__dictoffset__", T_PYSSIZET, offsetof(AST_object, dict), READONLY},
  1186. {NULL} /* Sentinel */
  1187. };
  1188. static PyMethodDef ast_type_methods[] = {
  1189. {"__reduce__", ast_type_reduce, METH_NOARGS, NULL},
  1190. {NULL}
  1191. };
  1192. static PyGetSetDef ast_type_getsets[] = {
  1193. {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
  1194. {NULL}
  1195. };
  1196. static PyType_Slot AST_type_slots[] = {
  1197. {Py_tp_dealloc, ast_dealloc},
  1198. {Py_tp_getattro, PyObject_GenericGetAttr},
  1199. {Py_tp_setattro, PyObject_GenericSetAttr},
  1200. {Py_tp_traverse, ast_traverse},
  1201. {Py_tp_clear, ast_clear},
  1202. {Py_tp_members, ast_type_members},
  1203. {Py_tp_methods, ast_type_methods},
  1204. {Py_tp_getset, ast_type_getsets},
  1205. {Py_tp_init, ast_type_init},
  1206. {Py_tp_alloc, PyType_GenericAlloc},
  1207. {Py_tp_new, PyType_GenericNew},
  1208. {Py_tp_free, PyObject_GC_Del},
  1209. {0, 0},
  1210. };
  1211. static PyType_Spec AST_type_spec = {
  1212. "ast.AST",
  1213. sizeof(AST_object),
  1214. 0,
  1215. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
  1216. AST_type_slots
  1217. };
  1218. static PyObject *
  1219. make_type(const char *type, PyObject* base, const char* const* fields, int num_fields, const char *doc)
  1220. {
  1221. PyObject *fnames, *result;
  1222. int i;
  1223. fnames = PyTuple_New(num_fields);
  1224. if (!fnames) return NULL;
  1225. for (i = 0; i < num_fields; i++) {
  1226. PyObject *field = PyUnicode_InternFromString(fields[i]);
  1227. if (!field) {
  1228. Py_DECREF(fnames);
  1229. return NULL;
  1230. }
  1231. PyTuple_SET_ITEM(fnames, i, field);
  1232. }
  1233. result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOs}",
  1234. type, base,
  1235. astmodulestate_global->_fields, fnames,
  1236. astmodulestate_global->__module__,
  1237. astmodulestate_global->ast,
  1238. astmodulestate_global->__doc__, doc);
  1239. Py_DECREF(fnames);
  1240. return result;
  1241. }
  1242. static int
  1243. add_attributes(PyObject *type, const char * const *attrs, int num_fields)
  1244. {
  1245. int i, result;
  1246. PyObject *s, *l = PyTuple_New(num_fields);
  1247. if (!l)
  1248. return 0;
  1249. for (i = 0; i < num_fields; i++) {
  1250. s = PyUnicode_InternFromString(attrs[i]);
  1251. if (!s) {
  1252. Py_DECREF(l);
  1253. return 0;
  1254. }
  1255. PyTuple_SET_ITEM(l, i, s);
  1256. }
  1257. result = PyObject_SetAttr(type, astmodulestate_global->_attributes, l) >= 0;
  1258. Py_DECREF(l);
  1259. return result;
  1260. }
  1261. /* Conversion AST -> Python */
  1262. static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*))
  1263. {
  1264. Py_ssize_t i, n = asdl_seq_LEN(seq);
  1265. PyObject *result = PyList_New(n);
  1266. PyObject *value;
  1267. if (!result)
  1268. return NULL;
  1269. for (i = 0; i < n; i++) {
  1270. value = func(asdl_seq_GET(seq, i));
  1271. if (!value) {
  1272. Py_DECREF(result);
  1273. return NULL;
  1274. }
  1275. PyList_SET_ITEM(result, i, value);
  1276. }
  1277. return result;
  1278. }
  1279. static PyObject* ast2obj_object(void *o)
  1280. {
  1281. if (!o)
  1282. o = Py_None;
  1283. Py_INCREF((PyObject*)o);
  1284. return (PyObject*)o;
  1285. }
  1286. #define ast2obj_constant ast2obj_object
  1287. #define ast2obj_identifier ast2obj_object
  1288. #define ast2obj_string ast2obj_object
  1289. static PyObject* ast2obj_int(long b)
  1290. {
  1291. return PyLong_FromLong(b);
  1292. }
  1293. /* Conversion Python -> AST */
  1294. static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
  1295. {
  1296. if (obj == Py_None)
  1297. obj = NULL;
  1298. if (obj) {
  1299. if (PyArena_AddPyObject(arena, obj) < 0) {
  1300. *out = NULL;
  1301. return -1;
  1302. }
  1303. Py_INCREF(obj);
  1304. }
  1305. *out = obj;
  1306. return 0;
  1307. }
  1308. static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena)
  1309. {
  1310. if (PyArena_AddPyObject(arena, obj) < 0) {
  1311. *out = NULL;
  1312. return -1;
  1313. }
  1314. Py_INCREF(obj);
  1315. *out = obj;
  1316. return 0;
  1317. }
  1318. static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena)
  1319. {
  1320. if (!PyUnicode_CheckExact(obj) && obj != Py_None) {
  1321. PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str");
  1322. return 1;
  1323. }
  1324. return obj2ast_object(obj, out, arena);
  1325. }
  1326. static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
  1327. {
  1328. if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
  1329. PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
  1330. return 1;
  1331. }
  1332. return obj2ast_object(obj, out, arena);
  1333. }
  1334. static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
  1335. {
  1336. int i;
  1337. if (!PyLong_Check(obj)) {
  1338. PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj);
  1339. return 1;
  1340. }
  1341. i = _PyLong_AsInt(obj);
  1342. if (i == -1 && PyErr_Occurred())
  1343. return 1;
  1344. *out = i;
  1345. return 0;
  1346. }
  1347. static int add_ast_fields(void)
  1348. {
  1349. PyObject *empty_tuple;
  1350. empty_tuple = PyTuple_New(0);
  1351. if (!empty_tuple ||
  1352. PyObject_SetAttrString(astmodulestate_global->AST_type, "_fields", empty_tuple) < 0 ||
  1353. PyObject_SetAttrString(astmodulestate_global->AST_type, "_attributes", empty_tuple) < 0) {
  1354. Py_XDECREF(empty_tuple);
  1355. return -1;
  1356. }
  1357. Py_DECREF(empty_tuple);
  1358. return 0;
  1359. }
  1360. static int init_types(void)
  1361. {
  1362. PyObject *m;
  1363. if (PyState_FindModule(&_astmodule) == NULL) {
  1364. m = PyModule_Create(&_astmodule);
  1365. if (!m) return 0;
  1366. PyState_AddModule(m, &_astmodule);
  1367. }
  1368. astmodulestate *state = astmodulestate_global;
  1369. if (state->initialized) return 1;
  1370. if (init_identifiers() < 0) return 0;
  1371. state->AST_type = PyType_FromSpec(&AST_type_spec);
  1372. if (!state->AST_type) return 0;
  1373. if (add_ast_fields() < 0) return 0;
  1374. state->mod_type = make_type("mod", state->AST_type, NULL, 0,
  1375. "mod = Module(stmt* body, type_ignore* type_ignores)\n"
  1376. " | Interactive(stmt* body)\n"
  1377. " | Expression(expr body)\n"
  1378. " | FunctionType(expr* argtypes, expr returns)");
  1379. if (!state->mod_type) return 0;
  1380. if (!add_attributes(state->mod_type, NULL, 0)) return 0;
  1381. state->Module_type = make_type("Module", state->mod_type, Module_fields, 2,
  1382. "Module(stmt* body, type_ignore* type_ignores)");
  1383. if (!state->Module_type) return 0;
  1384. state->Interactive_type = make_type("Interactive", state->mod_type,
  1385. Interactive_fields, 1,
  1386. "Interactive(stmt* body)");
  1387. if (!state->Interactive_type) return 0;
  1388. state->Expression_type = make_type("Expression", state->mod_type,
  1389. Expression_fields, 1,
  1390. "Expression(expr body)");
  1391. if (!state->Expression_type) return 0;
  1392. state->FunctionType_type = make_type("FunctionType", state->mod_type,
  1393. FunctionType_fields, 2,
  1394. "FunctionType(expr* argtypes, expr returns)");
  1395. if (!state->FunctionType_type) return 0;
  1396. state->stmt_type = make_type("stmt", state->AST_type, NULL, 0,
  1397. "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
  1398. " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
  1399. " | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n"
  1400. " | Return(expr? value)\n"
  1401. " | Delete(expr* targets)\n"
  1402. " | Assign(expr* targets, expr value, string? type_comment)\n"
  1403. " | AugAssign(expr target, operator op, expr value)\n"
  1404. " | AnnAssign(expr target, expr annotation, expr? value, int simple)\n"
  1405. " | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
  1406. " | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
  1407. " | While(expr test, stmt* body, stmt* orelse)\n"
  1408. " | If(expr test, stmt* body, stmt* orelse)\n"
  1409. " | With(withitem* items, stmt* body, string? type_comment)\n"
  1410. " | AsyncWith(withitem* items, stmt* body, string? type_comment)\n"
  1411. " | Raise(expr? exc, expr? cause)\n"
  1412. " | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n"
  1413. " | Assert(expr test, expr? msg)\n"
  1414. " | Import(alias* names)\n"
  1415. " | ImportFrom(identifier? module, alias* names, int? level)\n"
  1416. " | Global(identifier* names)\n"
  1417. " | Nonlocal(identifier* names)\n"
  1418. " | Expr(expr value)\n"
  1419. " | Pass\n"
  1420. " | Break\n"
  1421. " | Continue");
  1422. if (!state->stmt_type) return 0;
  1423. if (!add_attributes(state->stmt_type, stmt_attributes, 4)) return 0;
  1424. if (PyObject_SetAttr(state->stmt_type, state->end_lineno, Py_None) == -1)
  1425. return 0;
  1426. if (PyObject_SetAttr(state->stmt_type, state->end_col_offset, Py_None) ==
  1427. -1)
  1428. return 0;
  1429. state->FunctionDef_type = make_type("FunctionDef", state->stmt_type,
  1430. FunctionDef_fields, 6,
  1431. "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
  1432. if (!state->FunctionDef_type) return 0;
  1433. if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) ==
  1434. -1)
  1435. return 0;
  1436. if (PyObject_SetAttr(state->FunctionDef_type, state->type_comment, Py_None)
  1437. == -1)
  1438. return 0;
  1439. state->AsyncFunctionDef_type = make_type("AsyncFunctionDef",
  1440. state->stmt_type,
  1441. AsyncFunctionDef_fields, 6,
  1442. "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
  1443. if (!state->AsyncFunctionDef_type) return 0;
  1444. if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None)
  1445. == -1)
  1446. return 0;
  1447. if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->type_comment,
  1448. Py_None) == -1)
  1449. return 0;
  1450. state->ClassDef_type = make_type("ClassDef", state->stmt_type,
  1451. ClassDef_fields, 5,
  1452. "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)");
  1453. if (!state->ClassDef_type) return 0;
  1454. state->Return_type = make_type("Return", state->stmt_type, Return_fields, 1,
  1455. "Return(expr? value)");
  1456. if (!state->Return_type) return 0;
  1457. if (PyObject_SetAttr(state->Return_type, state->value, Py_None) == -1)
  1458. return 0;
  1459. state->Delete_type = make_type("Delete", state->stmt_type, Delete_fields, 1,
  1460. "Delete(expr* targets)");
  1461. if (!state->Delete_type) return 0;
  1462. state->Assign_type = make_type("Assign", state->stmt_type, Assign_fields, 3,
  1463. "Assign(expr* targets, expr value, string? type_comment)");
  1464. if (!state->Assign_type) return 0;
  1465. if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) ==
  1466. -1)
  1467. return 0;
  1468. state->AugAssign_type = make_type("AugAssign", state->stmt_type,
  1469. AugAssign_fields, 3,
  1470. "AugAssign(expr target, operator op, expr value)");
  1471. if (!state->AugAssign_type) return 0;
  1472. state->AnnAssign_type = make_type("AnnAssign", state->stmt_type,
  1473. AnnAssign_fields, 4,
  1474. "AnnAssign(expr target, expr annotation, expr? value, int simple)");
  1475. if (!state->AnnAssign_type) return 0;
  1476. if (PyObject_SetAttr(state->AnnAssign_type, state->value, Py_None) == -1)
  1477. return 0;
  1478. state->For_type = make_type("For", state->stmt_type, For_fields, 5,
  1479. "For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)");
  1480. if (!state->For_type) return 0;
  1481. if (PyObject_SetAttr(state->For_type, state->type_comment, Py_None) == -1)
  1482. return 0;
  1483. state->AsyncFor_type = make_type("AsyncFor", state->stmt_type,
  1484. AsyncFor_fields, 5,
  1485. "AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)");
  1486. if (!state->AsyncFor_type) return 0;
  1487. if (PyObject_SetAttr(state->AsyncFor_type, state->type_comment, Py_None) ==
  1488. -1)
  1489. return 0;
  1490. state->While_type = make_type("While", state->stmt_type, While_fields, 3,
  1491. "While(expr test, stmt* body, stmt* orelse)");
  1492. if (!state->While_type) return 0;
  1493. state->If_type = make_type("If", state->stmt_type, If_fields, 3,
  1494. "If(expr test, stmt* body, stmt* orelse)");
  1495. if (!state->If_type) return 0;
  1496. state->With_type = make_type("With", state->stmt_type, With_fields, 3,
  1497. "With(withitem* items, stmt* body, string? type_comment)");
  1498. if (!state->With_type) return 0;
  1499. if (PyObject_SetAttr(state->With_type, state->type_comment, Py_None) == -1)
  1500. return 0;
  1501. state->AsyncWith_type = make_type("AsyncWith", state->stmt_type,
  1502. AsyncWith_fields, 3,
  1503. "AsyncWith(withitem* items, stmt* body, string? type_comment)");
  1504. if (!state->AsyncWith_type) return 0;
  1505. if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None)
  1506. == -1)
  1507. return 0;
  1508. state->Raise_type = make_type("Raise", state->stmt_type, Raise_fields, 2,
  1509. "Raise(expr? exc, expr? cause)");
  1510. if (!state->Raise_type) return 0;
  1511. if (PyObject_SetAttr(state->Raise_type, state->exc, Py_None) == -1)
  1512. return 0;
  1513. if (PyObject_SetAttr(state->Raise_type, state->cause, Py_None) == -1)
  1514. return 0;
  1515. state->Try_type = make_type("Try", state->stmt_type, Try_fields, 4,
  1516. "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)");
  1517. if (!state->Try_type) return 0;
  1518. state->Assert_type = make_type("Assert", state->stmt_type, Assert_fields, 2,
  1519. "Assert(expr test, expr? msg)");
  1520. if (!state->Assert_type) return 0;
  1521. if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1)
  1522. return 0;
  1523. state->Import_type = make_type("Import", state->stmt_type, Import_fields, 1,
  1524. "Import(alias* names)");
  1525. if (!state->Import_type) return 0;
  1526. state->ImportFrom_type = make_type("ImportFrom", state->stmt_type,
  1527. ImportFrom_fields, 3,
  1528. "ImportFrom(identifier? module, alias* names, int? level)");
  1529. if (!state->ImportFrom_type) return 0;
  1530. if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1)
  1531. return 0;
  1532. if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1)
  1533. return 0;
  1534. state->Global_type = make_type("Global", state->stmt_type, Global_fields, 1,
  1535. "Global(identifier* names)");
  1536. if (!state->Global_type) return 0;
  1537. state->Nonlocal_type = make_type("Nonlocal", state->stmt_type,
  1538. Nonlocal_fields, 1,
  1539. "Nonlocal(identifier* names)");
  1540. if (!state->Nonlocal_type) return 0;
  1541. state->Expr_type = make_type("Expr", state->stmt_type, Expr_fields, 1,
  1542. "Expr(expr value)");
  1543. if (!state->Expr_type) return 0;
  1544. state->Pass_type = make_type("Pass", state->stmt_type, NULL, 0,
  1545. "Pass");
  1546. if (!state->Pass_type) return 0;
  1547. state->Break_type = make_type("Break", state->stmt_type, NULL, 0,
  1548. "Break");
  1549. if (!state->Break_type) return 0;
  1550. state->Continue_type = make_type("Continue", state->stmt_type, NULL, 0,
  1551. "Continue");
  1552. if (!state->Continue_type) return 0;
  1553. state->expr_type = make_type("expr", state->AST_type, NULL, 0,
  1554. "expr = BoolOp(boolop op, expr* values)\n"
  1555. " | NamedExpr(expr target, expr value)\n"
  1556. " | BinOp(expr left, operator op, expr right)\n"
  1557. " | UnaryOp(unaryop op, expr operand)\n"
  1558. " | Lambda(arguments args, expr body)\n"
  1559. " | IfExp(expr test, expr body, expr orelse)\n"
  1560. " | Dict(expr* keys, expr* values)\n"
  1561. " | Set(expr* elts)\n"
  1562. " | ListComp(expr elt, comprehension* generators)\n"
  1563. " | SetComp(expr elt, comprehension* generators)\n"
  1564. " | DictComp(expr key, expr value, comprehension* generators)\n"
  1565. " | GeneratorExp(expr elt, comprehension* generators)\n"
  1566. " | Await(expr value)\n"
  1567. " | Yield(expr? value)\n"
  1568. " | YieldFrom(expr value)\n"
  1569. " | Compare(expr left, cmpop* ops, expr* comparators)\n"
  1570. " | Call(expr func, expr* args, keyword* keywords)\n"
  1571. " | FormattedValue(expr value, int? conversion, expr? format_spec)\n"
  1572. " | JoinedStr(expr* values)\n"
  1573. " | Constant(constant value, string? kind)\n"
  1574. " | Attribute(expr value, identifier attr, expr_context ctx)\n"
  1575. " | Subscript(expr value, expr slice, expr_context ctx)\n"
  1576. " | Starred(expr value, expr_context ctx)\n"
  1577. " | Name(identifier id, expr_context ctx)\n"
  1578. " | List(expr* elts, expr_context ctx)\n"
  1579. " | Tuple(expr* elts, expr_context ctx)\n"
  1580. " | Slice(expr? lower, expr? upper, expr? step)");
  1581. if (!state->expr_type) return 0;
  1582. if (!add_attributes(state->expr_type, expr_attributes, 4)) return 0;
  1583. if (PyObject_SetAttr(state->expr_type, state->end_lineno, Py_None) == -1)
  1584. return 0;
  1585. if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) ==
  1586. -1)
  1587. return 0;
  1588. state->BoolOp_type = make_type("BoolOp", state->expr_type, BoolOp_fields, 2,
  1589. "BoolOp(boolop op, expr* values)");
  1590. if (!state->BoolOp_type) return 0;
  1591. state->NamedExpr_type = make_type("NamedExpr", state->expr_type,
  1592. NamedExpr_fields, 2,
  1593. "NamedExpr(expr target, expr value)");
  1594. if (!state->NamedExpr_type) return 0;
  1595. state->BinOp_type = make_type("BinOp", state->expr_type, BinOp_fields, 3,
  1596. "BinOp(expr left, operator op, expr right)");
  1597. if (!state->BinOp_type) return 0;
  1598. state->UnaryOp_type = make_type("UnaryOp", state->expr_type,
  1599. UnaryOp_fields, 2,
  1600. "UnaryOp(unaryop op, expr operand)");
  1601. if (!state->UnaryOp_type) return 0;
  1602. state->Lambda_type = make_type("Lambda", state->expr_type, Lambda_fields, 2,
  1603. "Lambda(arguments args, expr body)");
  1604. if (!state->Lambda_type) return 0;
  1605. state->IfExp_type = make_type("IfExp", state->expr_type, IfExp_fields, 3,
  1606. "IfExp(expr test, expr body, expr orelse)");
  1607. if (!state->IfExp_type) return 0;
  1608. state->Dict_type = make_type("Dict", state->expr_type, Dict_fields, 2,
  1609. "Dict(expr* keys, expr* values)");
  1610. if (!state->Dict_type) return 0;
  1611. state->Set_type = make_type("Set", state->expr_type, Set_fields, 1,
  1612. "Set(expr* elts)");
  1613. if (!state->Set_type) return 0;
  1614. state->ListComp_type = make_type("ListComp", state->expr_type,
  1615. ListComp_fields, 2,
  1616. "ListComp(expr elt, comprehension* generators)");
  1617. if (!state->ListComp_type) return 0;
  1618. state->SetComp_type = make_type("SetComp", state->expr_type,
  1619. SetComp_fields, 2,
  1620. "SetComp(expr elt, comprehension* generators)");
  1621. if (!state->SetComp_type) return 0;
  1622. state->DictComp_type = make_type("DictComp", state->expr_type,
  1623. DictComp_fields, 3,
  1624. "DictComp(expr key, expr value, comprehension* generators)");
  1625. if (!state->DictComp_type) return 0;
  1626. state->GeneratorExp_type = make_type("GeneratorExp", state->expr_type,
  1627. GeneratorExp_fields, 2,
  1628. "GeneratorExp(expr elt, comprehension* generators)");
  1629. if (!state->GeneratorExp_type) return 0;
  1630. state->Await_type = make_type("Await", state->expr_type, Await_fields, 1,
  1631. "Await(expr value)");
  1632. if (!state->Await_type) return 0;
  1633. state->Yield_type = make_type("Yield", state->expr_type, Yield_fields, 1,
  1634. "Yield(expr? value)");
  1635. if (!state->Yield_type) return 0;
  1636. if (PyObject_SetAttr(state->Yield_type, state->value, Py_None) == -1)
  1637. return 0;
  1638. state->YieldFrom_type = make_type("YieldFrom", state->expr_type,
  1639. YieldFrom_fields, 1,
  1640. "YieldFrom(expr value)");
  1641. if (!state->YieldFrom_type) return 0;
  1642. state->Compare_type = make_type("Compare", state->expr_type,
  1643. Compare_fields, 3,
  1644. "Compare(expr left, cmpop* ops, expr* comparators)");
  1645. if (!state->Compare_type) return 0;
  1646. state->Call_type = make_type("Call", state->expr_type, Call_fields, 3,
  1647. "Call(expr func, expr* args, keyword* keywords)");
  1648. if (!state->Call_type) return 0;
  1649. state->FormattedValue_type = make_type("FormattedValue", state->expr_type,
  1650. FormattedValue_fields, 3,
  1651. "FormattedValue(expr value, int? conversion, expr? format_spec)");
  1652. if (!state->FormattedValue_type) return 0;
  1653. if (PyObject_SetAttr(state->FormattedValue_type, state->conversion,
  1654. Py_None) == -1)
  1655. return 0;
  1656. if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec,
  1657. Py_None) == -1)
  1658. return 0;
  1659. state->JoinedStr_type = make_type("JoinedStr", state->expr_type,
  1660. JoinedStr_fields, 1,
  1661. "JoinedStr(expr* values)");
  1662. if (!state->JoinedStr_type) return 0;
  1663. state->Constant_type = make_type("Constant", state->expr_type,
  1664. Constant_fields, 2,
  1665. "Constant(constant value, string? kind)");
  1666. if (!state->Constant_type) return 0;
  1667. if (PyObject_SetAttr(state->Constant_type, state->kind, Py_None) == -1)
  1668. return 0;
  1669. state->Attribute_type = make_type("Attribute", state->expr_type,
  1670. Attribute_fields, 3,
  1671. "Attribute(expr value, identifier attr, expr_context ctx)");
  1672. if (!state->Attribute_type) return 0;
  1673. state->Subscript_type = make_type("Subscript", state->expr_type,
  1674. Subscript_fields, 3,
  1675. "Subscript(expr value, expr slice, expr_context ctx)");
  1676. if (!state->Subscript_type) return 0;
  1677. state->Starred_type = make_type("Starred", state->expr_type,
  1678. Starred_fields, 2,
  1679. "Starred(expr value, expr_context ctx)");
  1680. if (!state->Starred_type) return 0;
  1681. state->Name_type = make_type("Name", state->expr_type, Name_fields, 2,
  1682. "Name(identifier id, expr_context ctx)");
  1683. if (!state->Name_type) return 0;
  1684. state->List_type = make_type("List", state->expr_type, List_fields, 2,
  1685. "List(expr* elts, expr_context ctx)");
  1686. if (!state->List_type) return 0;
  1687. state->Tuple_type = make_type("Tuple", state->expr_type, Tuple_fields, 2,
  1688. "Tuple(expr* elts, expr_context ctx)");
  1689. if (!state->Tuple_type) return 0;
  1690. state->Slice_type = make_type("Slice", state->expr_type, Slice_fields, 3,
  1691. "Slice(expr? lower, expr? upper, expr? step)");
  1692. if (!state->Slice_type) return 0;
  1693. if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
  1694. return 0;
  1695. if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
  1696. return 0;
  1697. if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
  1698. return 0;
  1699. state->expr_context_type = make_type("expr_context", state->AST_type, NULL,
  1700. 0,
  1701. "expr_context = Load | Store | Del");
  1702. if (!state->expr_context_type) return 0;
  1703. if (!add_attributes(state->expr_context_type, NULL, 0)) return 0;
  1704. state->Load_type = make_type("Load", state->expr_context_type, NULL, 0,
  1705. "Load");
  1706. if (!state->Load_type) return 0;
  1707. state->Load_singleton = PyType_GenericNew((PyTypeObject *)state->Load_type,
  1708. NULL, NULL);
  1709. if (!state->Load_singleton) return 0;
  1710. state->Store_type = make_type("Store", state->expr_context_type, NULL, 0,
  1711. "Store");
  1712. if (!state->Store_type) return 0;
  1713. state->Store_singleton = PyType_GenericNew((PyTypeObject
  1714. *)state->Store_type, NULL, NULL);
  1715. if (!state->Store_singleton) return 0;
  1716. state->Del_type = make_type("Del", state->expr_context_type, NULL, 0,
  1717. "Del");
  1718. if (!state->Del_type) return 0;
  1719. state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type,
  1720. NULL, NULL);
  1721. if (!state->Del_singleton) return 0;
  1722. state->boolop_type = make_type("boolop", state->AST_type, NULL, 0,
  1723. "boolop = And | Or");
  1724. if (!state->boolop_type) return 0;
  1725. if (!add_attributes(state->boolop_type, NULL, 0)) return 0;
  1726. state->And_type = make_type("And", state->boolop_type, NULL, 0,
  1727. "And");
  1728. if (!state->And_type) return 0;
  1729. state->And_singleton = PyType_GenericNew((PyTypeObject *)state->And_type,
  1730. NULL, NULL);
  1731. if (!state->And_singleton) return 0;
  1732. state->Or_type = make_type("Or", state->boolop_type, NULL, 0,
  1733. "Or");
  1734. if (!state->Or_type) return 0;
  1735. state->Or_singleton = PyType_GenericNew((PyTypeObject *)state->Or_type,
  1736. NULL, NULL);
  1737. if (!state->Or_singleton) return 0;
  1738. state->operator_type = make_type("operator", state->AST_type, NULL, 0,
  1739. "operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv");
  1740. if (!state->operator_type) return 0;
  1741. if (!add_attributes(state->operator_type, NULL, 0)) return 0;
  1742. state->Add_type = make_type("Add", state->operator_type, NULL, 0,
  1743. "Add");
  1744. if (!state->Add_type) return 0;
  1745. state->Add_singleton = PyType_GenericNew((PyTypeObject *)state->Add_type,
  1746. NULL, NULL);
  1747. if (!state->Add_singleton) return 0;
  1748. state->Sub_type = make_type("Sub", state->operator_type, NULL, 0,
  1749. "Sub");
  1750. if (!state->Sub_type) return 0;
  1751. state->Sub_singleton = PyType_GenericNew((PyTypeObject *)state->Sub_type,
  1752. NULL, NULL);
  1753. if (!state->Sub_singleton) return 0;
  1754. state->Mult_type = make_type("Mult", state->operator_type, NULL, 0,
  1755. "Mult");
  1756. if (!state->Mult_type) return 0;
  1757. state->Mult_singleton = PyType_GenericNew((PyTypeObject *)state->Mult_type,
  1758. NULL, NULL);
  1759. if (!state->Mult_singleton) return 0;
  1760. state->MatMult_type = make_type("MatMult", state->operator_type, NULL, 0,
  1761. "MatMult");
  1762. if (!state->MatMult_type) return 0;
  1763. state->MatMult_singleton = PyType_GenericNew((PyTypeObject
  1764. *)state->MatMult_type, NULL,
  1765. NULL);
  1766. if (!state->MatMult_singleton) return 0;
  1767. state->Div_type = make_type("Div", state->operator_type, NULL, 0,
  1768. "Div");
  1769. if (!state->Div_type) return 0;
  1770. state->Div_singleton = PyType_GenericNew((PyTypeObject *)state->Div_type,
  1771. NULL, NULL);
  1772. if (!state->Div_singleton) return 0;
  1773. state->Mod_type = make_type("Mod", state->operator_type, NULL, 0,
  1774. "Mod");
  1775. if (!state->Mod_type) return 0;
  1776. state->Mod_singleton = PyType_GenericNew((PyTypeObject *)state->Mod_type,
  1777. NULL, NULL);
  1778. if (!state->Mod_singleton) return 0;
  1779. state->Pow_type = make_type("Pow", state->operator_type, NULL, 0,
  1780. "Pow");
  1781. if (!state->Pow_type) return 0;
  1782. state->Pow_singleton = PyType_GenericNew((PyTypeObject *)state->Pow_type,
  1783. NULL, NULL);
  1784. if (!state->Pow_singleton) return 0;
  1785. state->LShift_type = make_type("LShift", state->operator_type, NULL, 0,
  1786. "LShift");
  1787. if (!state->LShift_type) return 0;
  1788. state->LShift_singleton = PyType_GenericNew((PyTypeObject
  1789. *)state->LShift_type, NULL,
  1790. NULL);
  1791. if (!state->LShift_singleton) return 0;
  1792. state->RShift_type = make_type("RShift", state->operator_type, NULL, 0,
  1793. "RShift");
  1794. if (!state->RShift_type) return 0;
  1795. state->RShift_singleton = PyType_GenericNew((PyTypeObject
  1796. *)state->RShift_type, NULL,
  1797. NULL);
  1798. if (!state->RShift_singleton) return 0;
  1799. state->BitOr_type = make_type("BitOr", state->operator_type, NULL, 0,
  1800. "BitOr");
  1801. if (!state->BitOr_type) return 0;
  1802. state->BitOr_singleton = PyType_GenericNew((PyTypeObject
  1803. *)state->BitOr_type, NULL, NULL);
  1804. if (!state->BitOr_singleton) return 0;
  1805. state->BitXor_type = make_type("BitXor", state->operator_type, NULL, 0,
  1806. "BitXor");
  1807. if (!state->BitXor_type) return 0;
  1808. state->BitXor_singleton = PyType_GenericNew((PyTypeObject
  1809. *)state->BitXor_type, NULL,
  1810. NULL);
  1811. if (!state->BitXor_singleton) return 0;
  1812. state->BitAnd_type = make_type("BitAnd", state->operator_type, NULL, 0,
  1813. "BitAnd");
  1814. if (!state->BitAnd_type) return 0;
  1815. state->BitAnd_singleton = PyType_GenericNew((PyTypeObject
  1816. *)state->BitAnd_type, NULL,
  1817. NULL);
  1818. if (!state->BitAnd_singleton) return 0;
  1819. state->FloorDiv_type = make_type("FloorDiv", state->operator_type, NULL, 0,
  1820. "FloorDiv");
  1821. if (!state->FloorDiv_type) return 0;
  1822. state->FloorDiv_singleton = PyType_GenericNew((PyTypeObject
  1823. *)state->FloorDiv_type, NULL,
  1824. NULL);
  1825. if (!state->FloorDiv_singleton) return 0;
  1826. state->unaryop_type = make_type("unaryop", state->AST_type, NULL, 0,
  1827. "unaryop = Invert | Not | UAdd | USub");
  1828. if (!state->unaryop_type) return 0;
  1829. if (!add_attributes(state->unaryop_type, NULL, 0)) return 0;
  1830. state->Invert_type = make_type("Invert", state->unaryop_type, NULL, 0,
  1831. "Invert");
  1832. if (!state->Invert_type) return 0;
  1833. state->Invert_singleton = PyType_GenericNew((PyTypeObject
  1834. *)state->Invert_type, NULL,
  1835. NULL);
  1836. if (!state->Invert_singleton) return 0;
  1837. state->Not_type = make_type("Not", state->unaryop_type, NULL, 0,
  1838. "Not");
  1839. if (!state->Not_type) return 0;
  1840. state->Not_singleton = PyType_GenericNew((PyTypeObject *)state->Not_type,
  1841. NULL, NULL);
  1842. if (!state->Not_singleton) return 0;
  1843. state->UAdd_type = make_type("UAdd", state->unaryop_type, NULL, 0,
  1844. "UAdd");
  1845. if (!state->UAdd_type) return 0;
  1846. state->UAdd_singleton = PyType_GenericNew((PyTypeObject *)state->UAdd_type,
  1847. NULL, NULL);
  1848. if (!state->UAdd_singleton) return 0;
  1849. state->USub_type = make_type("USub", state->unaryop_type, NULL, 0,
  1850. "USub");
  1851. if (!state->USub_type) return 0;
  1852. state->USub_singleton = PyType_GenericNew((PyTypeObject *)state->USub_type,
  1853. NULL, NULL);
  1854. if (!state->USub_singleton) return 0;
  1855. state->cmpop_type = make_type("cmpop", state->AST_type, NULL, 0,
  1856. "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn");
  1857. if (!state->cmpop_type) return 0;
  1858. if (!add_attributes(state->cmpop_type, NULL, 0)) return 0;
  1859. state->Eq_type = make_type("Eq", state->cmpop_type, NULL, 0,
  1860. "Eq");
  1861. if (!state->Eq_type) return 0;
  1862. state->Eq_singleton = PyType_GenericNew((PyTypeObject *)state->Eq_type,
  1863. NULL, NULL);
  1864. if (!state->Eq_singleton) return 0;
  1865. state->NotEq_type = make_type("NotEq", state->cmpop_type, NULL, 0,
  1866. "NotEq");
  1867. if (!state->NotEq_type) return 0;
  1868. state->NotEq_singleton = PyType_GenericNew((PyTypeObject
  1869. *)state->NotEq_type, NULL, NULL);
  1870. if (!state->NotEq_singleton) return 0;
  1871. state->Lt_type = make_type("Lt", state->cmpop_type, NULL, 0,
  1872. "Lt");
  1873. if (!state->Lt_type) return 0;
  1874. state->Lt_singleton = PyType_GenericNew((PyTypeObject *)state->Lt_type,
  1875. NULL, NULL);
  1876. if (!state->Lt_singleton) return 0;
  1877. state->LtE_type = make_type("LtE", state->cmpop_type, NULL, 0,
  1878. "LtE");
  1879. if (!state->LtE_type) return 0;
  1880. state->LtE_singleton = PyType_GenericNew((PyTypeObject *)state->LtE_type,
  1881. NULL, NULL);
  1882. if (!state->LtE_singleton) return 0;
  1883. state->Gt_type = make_type("Gt", state->cmpop_type, NULL, 0,
  1884. "Gt");
  1885. if (!state->Gt_type) return 0;
  1886. state->Gt_singleton = PyType_GenericNew((PyTypeObject *)state->Gt_type,
  1887. NULL, NULL);
  1888. if (!state->Gt_singleton) return 0;
  1889. state->GtE_type = make_type("GtE", state->cmpop_type, NULL, 0,
  1890. "GtE");
  1891. if (!state->GtE_type) return 0;
  1892. state->GtE_singleton = PyType_GenericNew((PyTypeObject *)state->GtE_type,
  1893. NULL, NULL);
  1894. if (!state->GtE_singleton) return 0;
  1895. state->Is_type = make_type("Is", state->cmpop_type, NULL, 0,
  1896. "Is");
  1897. if (!state->Is_type) return 0;
  1898. state->Is_singleton = PyType_GenericNew((PyTypeObject *)state->Is_type,
  1899. NULL, NULL);
  1900. if (!state->Is_singleton) return 0;
  1901. state->IsNot_type = make_type("IsNot", state->cmpop_type, NULL, 0,
  1902. "IsNot");
  1903. if (!state->IsNot_type) return 0;
  1904. state->IsNot_singleton = PyType_GenericNew((PyTypeObject
  1905. *)state->IsNot_type, NULL, NULL);
  1906. if (!state->IsNot_singleton) return 0;
  1907. state->In_type = make_type("In", state->cmpop_type, NULL, 0,
  1908. "In");
  1909. if (!state->In_type) return 0;
  1910. state->In_singleton = PyType_GenericNew((PyTypeObject *)state->In_type,
  1911. NULL, NULL);
  1912. if (!state->In_singleton) return 0;
  1913. state->NotIn_type = make_type("NotIn", state->cmpop_type, NULL, 0,
  1914. "NotIn");
  1915. if (!state->NotIn_type) return 0;
  1916. state->NotIn_singleton = PyType_GenericNew((PyTypeObject
  1917. *)state->NotIn_type, NULL, NULL);
  1918. if (!state->NotIn_singleton) return 0;
  1919. state->comprehension_type = make_type("comprehension", state->AST_type,
  1920. comprehension_fields, 4,
  1921. "comprehension(expr target, expr iter, expr* ifs, int is_async)");
  1922. if (!state->comprehension_type) return 0;
  1923. if (!add_attributes(state->comprehension_type, NULL, 0)) return 0;
  1924. state->excepthandler_type = make_type("excepthandler", state->AST_type,
  1925. NULL, 0,
  1926. "excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)");
  1927. if (!state->excepthandler_type) return 0;
  1928. if (!add_attributes(state->excepthandler_type, excepthandler_attributes,
  1929. 4)) return 0;
  1930. if (PyObject_SetAttr(state->excepthandler_type, state->end_lineno, Py_None)
  1931. == -1)
  1932. return 0;
  1933. if (PyObject_SetAttr(state->excepthandler_type, state->end_col_offset,
  1934. Py_None) == -1)
  1935. return 0;
  1936. state->ExceptHandler_type = make_type("ExceptHandler",
  1937. state->excepthandler_type,
  1938. ExceptHandler_fields, 3,
  1939. "ExceptHandler(expr? type, identifier? name, stmt* body)");
  1940. if (!state->ExceptHandler_type) return 0;
  1941. if (PyObject_SetAttr(state->ExceptHandler_type, state->type, Py_None) == -1)
  1942. return 0;
  1943. if (PyObject_SetAttr(state->ExceptHandler_type, state->name, Py_None) == -1)
  1944. return 0;
  1945. state->arguments_type = make_type("arguments", state->AST_type,
  1946. arguments_fields, 7,
  1947. "arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults)");
  1948. if (!state->arguments_type) return 0;
  1949. if (!add_attributes(state->arguments_type, NULL, 0)) return 0;
  1950. if (PyObject_SetAttr(state->arguments_type, state->vararg, Py_None) == -1)
  1951. return 0;
  1952. if (PyObject_SetAttr(state->arguments_type, state->kwarg, Py_None) == -1)
  1953. return 0;
  1954. state->arg_type = make_type("arg", state->AST_type, arg_fields, 3,
  1955. "arg(identifier arg, expr? annotation, string? type_comment)");
  1956. if (!state->arg_type) return 0;
  1957. if (!add_attributes(state->arg_type, arg_attributes, 4)) return 0;
  1958. if (PyObject_SetAttr(state->arg_type, state->annotation, Py_None) == -1)
  1959. return 0;
  1960. if (PyObject_SetAttr(state->arg_type, state->type_comment, Py_None) == -1)
  1961. return 0;
  1962. if (PyObject_SetAttr(state->arg_type, state->end_lineno, Py_None) == -1)
  1963. return 0;
  1964. if (PyObject_SetAttr(state->arg_type, state->end_col_offset, Py_None) == -1)
  1965. return 0;
  1966. state->keyword_type = make_type("keyword", state->AST_type, keyword_fields,
  1967. 2,
  1968. "keyword(identifier? arg, expr value)");
  1969. if (!state->keyword_type) return 0;
  1970. if (!add_attributes(state->keyword_type, keyword_attributes, 4)) return 0;
  1971. if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1)
  1972. return 0;
  1973. if (PyObject_SetAttr(state->keyword_type, state->end_lineno, Py_None) == -1)
  1974. return 0;
  1975. if (PyObject_SetAttr(state->keyword_type, state->end_col_offset, Py_None)
  1976. == -1)
  1977. return 0;
  1978. state->alias_type = make_type("alias", state->AST_type, alias_fields, 2,
  1979. "alias(identifier name, identifier? asname)");
  1980. if (!state->alias_type) return 0;
  1981. if (!add_attributes(state->alias_type, NULL, 0)) return 0;
  1982. if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1)
  1983. return 0;
  1984. state->withitem_type = make_type("withitem", state->AST_type,
  1985. withitem_fields, 2,
  1986. "withitem(expr context_expr, expr? optional_vars)");
  1987. if (!state->withitem_type) return 0;
  1988. if (!add_attributes(state->withitem_type, NULL, 0)) return 0;
  1989. if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None)
  1990. == -1)
  1991. return 0;
  1992. state->type_ignore_type = make_type("type_ignore", state->AST_type, NULL, 0,
  1993. "type_ignore = TypeIgnore(int lineno, string tag)");
  1994. if (!state->type_ignore_type) return 0;
  1995. if (!add_attributes(state->type_ignore_type, NULL, 0)) return 0;
  1996. state->TypeIgnore_type = make_type("TypeIgnore", state->type_ignore_type,
  1997. TypeIgnore_fields, 2,
  1998. "TypeIgnore(int lineno, string tag)");
  1999. if (!state->TypeIgnore_type) return 0;
  2000. state->initialized = 1;
  2001. return 1;
  2002. }
  2003. static int obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena);
  2004. static int obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena);
  2005. static int obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena);
  2006. static int obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena*
  2007. arena);
  2008. static int obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena);
  2009. static int obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena);
  2010. static int obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena);
  2011. static int obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena);
  2012. static int obj2ast_comprehension(PyObject* obj, comprehension_ty* out, PyArena*
  2013. arena);
  2014. static int obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena*
  2015. arena);
  2016. static int obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena);
  2017. static int obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena);
  2018. static int obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena);
  2019. static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena);
  2020. static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena);
  2021. static int obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena*
  2022. arena);
  2023. mod_ty
  2024. Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena)
  2025. {
  2026. mod_ty p;
  2027. p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
  2028. if (!p)
  2029. return NULL;
  2030. p->kind = Module_kind;
  2031. p->v.Module.body = body;
  2032. p->v.Module.type_ignores = type_ignores;
  2033. return p;
  2034. }
  2035. mod_ty
  2036. Interactive(asdl_seq * body, PyArena *arena)
  2037. {
  2038. mod_ty p;
  2039. p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
  2040. if (!p)
  2041. return NULL;
  2042. p->kind = Interactive_kind;
  2043. p->v.Interactive.body = body;
  2044. return p;
  2045. }
  2046. mod_ty
  2047. Expression(expr_ty body, PyArena *arena)
  2048. {
  2049. mod_ty p;
  2050. if (!body) {
  2051. PyErr_SetString(PyExc_ValueError,
  2052. "field 'body' is required for Expression");
  2053. return NULL;
  2054. }
  2055. p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
  2056. if (!p)
  2057. return NULL;
  2058. p->kind = Expression_kind;
  2059. p->v.Expression.body = body;
  2060. return p;
  2061. }
  2062. mod_ty
  2063. FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena)
  2064. {
  2065. mod_ty p;
  2066. if (!returns) {
  2067. PyErr_SetString(PyExc_ValueError,
  2068. "field 'returns' is required for FunctionType");
  2069. return NULL;
  2070. }
  2071. p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
  2072. if (!p)
  2073. return NULL;
  2074. p->kind = FunctionType_kind;
  2075. p->v.FunctionType.argtypes = argtypes;
  2076. p->v.FunctionType.returns = returns;
  2077. return p;
  2078. }
  2079. stmt_ty
  2080. FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
  2081. decorator_list, expr_ty returns, string type_comment, int lineno,
  2082. int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2083. {
  2084. stmt_ty p;
  2085. if (!name) {
  2086. PyErr_SetString(PyExc_ValueError,
  2087. "field 'name' is required for FunctionDef");
  2088. return NULL;
  2089. }
  2090. if (!args) {
  2091. PyErr_SetString(PyExc_ValueError,
  2092. "field 'args' is required for FunctionDef");
  2093. return NULL;
  2094. }
  2095. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2096. if (!p)
  2097. return NULL;
  2098. p->kind = FunctionDef_kind;
  2099. p->v.FunctionDef.name = name;
  2100. p->v.FunctionDef.args = args;
  2101. p->v.FunctionDef.body = body;
  2102. p->v.FunctionDef.decorator_list = decorator_list;
  2103. p->v.FunctionDef.returns = returns;
  2104. p->v.FunctionDef.type_comment = type_comment;
  2105. p->lineno = lineno;
  2106. p->col_offset = col_offset;
  2107. p->end_lineno = end_lineno;
  2108. p->end_col_offset = end_col_offset;
  2109. return p;
  2110. }
  2111. stmt_ty
  2112. AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
  2113. * decorator_list, expr_ty returns, string type_comment, int
  2114. lineno, int col_offset, int end_lineno, int end_col_offset,
  2115. PyArena *arena)
  2116. {
  2117. stmt_ty p;
  2118. if (!name) {
  2119. PyErr_SetString(PyExc_ValueError,
  2120. "field 'name' is required for AsyncFunctionDef");
  2121. return NULL;
  2122. }
  2123. if (!args) {
  2124. PyErr_SetString(PyExc_ValueError,
  2125. "field 'args' is required for AsyncFunctionDef");
  2126. return NULL;
  2127. }
  2128. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2129. if (!p)
  2130. return NULL;
  2131. p->kind = AsyncFunctionDef_kind;
  2132. p->v.AsyncFunctionDef.name = name;
  2133. p->v.AsyncFunctionDef.args = args;
  2134. p->v.AsyncFunctionDef.body = body;
  2135. p->v.AsyncFunctionDef.decorator_list = decorator_list;
  2136. p->v.AsyncFunctionDef.returns = returns;
  2137. p->v.AsyncFunctionDef.type_comment = type_comment;
  2138. p->lineno = lineno;
  2139. p->col_offset = col_offset;
  2140. p->end_lineno = end_lineno;
  2141. p->end_col_offset = end_col_offset;
  2142. return p;
  2143. }
  2144. stmt_ty
  2145. ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq *
  2146. body, asdl_seq * decorator_list, int lineno, int col_offset, int
  2147. end_lineno, int end_col_offset, PyArena *arena)
  2148. {
  2149. stmt_ty p;
  2150. if (!name) {
  2151. PyErr_SetString(PyExc_ValueError,
  2152. "field 'name' is required for ClassDef");
  2153. return NULL;
  2154. }
  2155. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2156. if (!p)
  2157. return NULL;
  2158. p->kind = ClassDef_kind;
  2159. p->v.ClassDef.name = name;
  2160. p->v.ClassDef.bases = bases;
  2161. p->v.ClassDef.keywords = keywords;
  2162. p->v.ClassDef.body = body;
  2163. p->v.ClassDef.decorator_list = decorator_list;
  2164. p->lineno = lineno;
  2165. p->col_offset = col_offset;
  2166. p->end_lineno = end_lineno;
  2167. p->end_col_offset = end_col_offset;
  2168. return p;
  2169. }
  2170. stmt_ty
  2171. Return(expr_ty value, int lineno, int col_offset, int end_lineno, int
  2172. end_col_offset, PyArena *arena)
  2173. {
  2174. stmt_ty p;
  2175. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2176. if (!p)
  2177. return NULL;
  2178. p->kind = Return_kind;
  2179. p->v.Return.value = value;
  2180. p->lineno = lineno;
  2181. p->col_offset = col_offset;
  2182. p->end_lineno = end_lineno;
  2183. p->end_col_offset = end_col_offset;
  2184. return p;
  2185. }
  2186. stmt_ty
  2187. Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int
  2188. end_col_offset, PyArena *arena)
  2189. {
  2190. stmt_ty p;
  2191. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2192. if (!p)
  2193. return NULL;
  2194. p->kind = Delete_kind;
  2195. p->v.Delete.targets = targets;
  2196. p->lineno = lineno;
  2197. p->col_offset = col_offset;
  2198. p->end_lineno = end_lineno;
  2199. p->end_col_offset = end_col_offset;
  2200. return p;
  2201. }
  2202. stmt_ty
  2203. Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int
  2204. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2205. {
  2206. stmt_ty p;
  2207. if (!value) {
  2208. PyErr_SetString(PyExc_ValueError,
  2209. "field 'value' is required for Assign");
  2210. return NULL;
  2211. }
  2212. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2213. if (!p)
  2214. return NULL;
  2215. p->kind = Assign_kind;
  2216. p->v.Assign.targets = targets;
  2217. p->v.Assign.value = value;
  2218. p->v.Assign.type_comment = type_comment;
  2219. p->lineno = lineno;
  2220. p->col_offset = col_offset;
  2221. p->end_lineno = end_lineno;
  2222. p->end_col_offset = end_col_offset;
  2223. return p;
  2224. }
  2225. stmt_ty
  2226. AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int
  2227. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2228. {
  2229. stmt_ty p;
  2230. if (!target) {
  2231. PyErr_SetString(PyExc_ValueError,
  2232. "field 'target' is required for AugAssign");
  2233. return NULL;
  2234. }
  2235. if (!op) {
  2236. PyErr_SetString(PyExc_ValueError,
  2237. "field 'op' is required for AugAssign");
  2238. return NULL;
  2239. }
  2240. if (!value) {
  2241. PyErr_SetString(PyExc_ValueError,
  2242. "field 'value' is required for AugAssign");
  2243. return NULL;
  2244. }
  2245. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2246. if (!p)
  2247. return NULL;
  2248. p->kind = AugAssign_kind;
  2249. p->v.AugAssign.target = target;
  2250. p->v.AugAssign.op = op;
  2251. p->v.AugAssign.value = value;
  2252. p->lineno = lineno;
  2253. p->col_offset = col_offset;
  2254. p->end_lineno = end_lineno;
  2255. p->end_col_offset = end_col_offset;
  2256. return p;
  2257. }
  2258. stmt_ty
  2259. AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int
  2260. lineno, int col_offset, int end_lineno, int end_col_offset, PyArena
  2261. *arena)
  2262. {
  2263. stmt_ty p;
  2264. if (!target) {
  2265. PyErr_SetString(PyExc_ValueError,
  2266. "field 'target' is required for AnnAssign");
  2267. return NULL;
  2268. }
  2269. if (!annotation) {
  2270. PyErr_SetString(PyExc_ValueError,
  2271. "field 'annotation' is required for AnnAssign");
  2272. return NULL;
  2273. }
  2274. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2275. if (!p)
  2276. return NULL;
  2277. p->kind = AnnAssign_kind;
  2278. p->v.AnnAssign.target = target;
  2279. p->v.AnnAssign.annotation = annotation;
  2280. p->v.AnnAssign.value = value;
  2281. p->v.AnnAssign.simple = simple;
  2282. p->lineno = lineno;
  2283. p->col_offset = col_offset;
  2284. p->end_lineno = end_lineno;
  2285. p->end_col_offset = end_col_offset;
  2286. return p;
  2287. }
  2288. stmt_ty
  2289. For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string
  2290. type_comment, int lineno, int col_offset, int end_lineno, int
  2291. end_col_offset, PyArena *arena)
  2292. {
  2293. stmt_ty p;
  2294. if (!target) {
  2295. PyErr_SetString(PyExc_ValueError,
  2296. "field 'target' is required for For");
  2297. return NULL;
  2298. }
  2299. if (!iter) {
  2300. PyErr_SetString(PyExc_ValueError,
  2301. "field 'iter' is required for For");
  2302. return NULL;
  2303. }
  2304. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2305. if (!p)
  2306. return NULL;
  2307. p->kind = For_kind;
  2308. p->v.For.target = target;
  2309. p->v.For.iter = iter;
  2310. p->v.For.body = body;
  2311. p->v.For.orelse = orelse;
  2312. p->v.For.type_comment = type_comment;
  2313. p->lineno = lineno;
  2314. p->col_offset = col_offset;
  2315. p->end_lineno = end_lineno;
  2316. p->end_col_offset = end_col_offset;
  2317. return p;
  2318. }
  2319. stmt_ty
  2320. AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse,
  2321. string type_comment, int lineno, int col_offset, int end_lineno, int
  2322. end_col_offset, PyArena *arena)
  2323. {
  2324. stmt_ty p;
  2325. if (!target) {
  2326. PyErr_SetString(PyExc_ValueError,
  2327. "field 'target' is required for AsyncFor");
  2328. return NULL;
  2329. }
  2330. if (!iter) {
  2331. PyErr_SetString(PyExc_ValueError,
  2332. "field 'iter' is required for AsyncFor");
  2333. return NULL;
  2334. }
  2335. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2336. if (!p)
  2337. return NULL;
  2338. p->kind = AsyncFor_kind;
  2339. p->v.AsyncFor.target = target;
  2340. p->v.AsyncFor.iter = iter;
  2341. p->v.AsyncFor.body = body;
  2342. p->v.AsyncFor.orelse = orelse;
  2343. p->v.AsyncFor.type_comment = type_comment;
  2344. p->lineno = lineno;
  2345. p->col_offset = col_offset;
  2346. p->end_lineno = end_lineno;
  2347. p->end_col_offset = end_col_offset;
  2348. return p;
  2349. }
  2350. stmt_ty
  2351. While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
  2352. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2353. {
  2354. stmt_ty p;
  2355. if (!test) {
  2356. PyErr_SetString(PyExc_ValueError,
  2357. "field 'test' is required for While");
  2358. return NULL;
  2359. }
  2360. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2361. if (!p)
  2362. return NULL;
  2363. p->kind = While_kind;
  2364. p->v.While.test = test;
  2365. p->v.While.body = body;
  2366. p->v.While.orelse = orelse;
  2367. p->lineno = lineno;
  2368. p->col_offset = col_offset;
  2369. p->end_lineno = end_lineno;
  2370. p->end_col_offset = end_col_offset;
  2371. return p;
  2372. }
  2373. stmt_ty
  2374. If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
  2375. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2376. {
  2377. stmt_ty p;
  2378. if (!test) {
  2379. PyErr_SetString(PyExc_ValueError,
  2380. "field 'test' is required for If");
  2381. return NULL;
  2382. }
  2383. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2384. if (!p)
  2385. return NULL;
  2386. p->kind = If_kind;
  2387. p->v.If.test = test;
  2388. p->v.If.body = body;
  2389. p->v.If.orelse = orelse;
  2390. p->lineno = lineno;
  2391. p->col_offset = col_offset;
  2392. p->end_lineno = end_lineno;
  2393. p->end_col_offset = end_col_offset;
  2394. return p;
  2395. }
  2396. stmt_ty
  2397. With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int
  2398. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2399. {
  2400. stmt_ty p;
  2401. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2402. if (!p)
  2403. return NULL;
  2404. p->kind = With_kind;
  2405. p->v.With.items = items;
  2406. p->v.With.body = body;
  2407. p->v.With.type_comment = type_comment;
  2408. p->lineno = lineno;
  2409. p->col_offset = col_offset;
  2410. p->end_lineno = end_lineno;
  2411. p->end_col_offset = end_col_offset;
  2412. return p;
  2413. }
  2414. stmt_ty
  2415. AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, int lineno,
  2416. int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2417. {
  2418. stmt_ty p;
  2419. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2420. if (!p)
  2421. return NULL;
  2422. p->kind = AsyncWith_kind;
  2423. p->v.AsyncWith.items = items;
  2424. p->v.AsyncWith.body = body;
  2425. p->v.AsyncWith.type_comment = type_comment;
  2426. p->lineno = lineno;
  2427. p->col_offset = col_offset;
  2428. p->end_lineno = end_lineno;
  2429. p->end_col_offset = end_col_offset;
  2430. return p;
  2431. }
  2432. stmt_ty
  2433. Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno,
  2434. int end_col_offset, PyArena *arena)
  2435. {
  2436. stmt_ty p;
  2437. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2438. if (!p)
  2439. return NULL;
  2440. p->kind = Raise_kind;
  2441. p->v.Raise.exc = exc;
  2442. p->v.Raise.cause = cause;
  2443. p->lineno = lineno;
  2444. p->col_offset = col_offset;
  2445. p->end_lineno = end_lineno;
  2446. p->end_col_offset = end_col_offset;
  2447. return p;
  2448. }
  2449. stmt_ty
  2450. Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq *
  2451. finalbody, int lineno, int col_offset, int end_lineno, int end_col_offset,
  2452. PyArena *arena)
  2453. {
  2454. stmt_ty p;
  2455. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2456. if (!p)
  2457. return NULL;
  2458. p->kind = Try_kind;
  2459. p->v.Try.body = body;
  2460. p->v.Try.handlers = handlers;
  2461. p->v.Try.orelse = orelse;
  2462. p->v.Try.finalbody = finalbody;
  2463. p->lineno = lineno;
  2464. p->col_offset = col_offset;
  2465. p->end_lineno = end_lineno;
  2466. p->end_col_offset = end_col_offset;
  2467. return p;
  2468. }
  2469. stmt_ty
  2470. Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno,
  2471. int end_col_offset, PyArena *arena)
  2472. {
  2473. stmt_ty p;
  2474. if (!test) {
  2475. PyErr_SetString(PyExc_ValueError,
  2476. "field 'test' is required for Assert");
  2477. return NULL;
  2478. }
  2479. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2480. if (!p)
  2481. return NULL;
  2482. p->kind = Assert_kind;
  2483. p->v.Assert.test = test;
  2484. p->v.Assert.msg = msg;
  2485. p->lineno = lineno;
  2486. p->col_offset = col_offset;
  2487. p->end_lineno = end_lineno;
  2488. p->end_col_offset = end_col_offset;
  2489. return p;
  2490. }
  2491. stmt_ty
  2492. Import(asdl_seq * names, int lineno, int col_offset, int end_lineno, int
  2493. end_col_offset, PyArena *arena)
  2494. {
  2495. stmt_ty p;
  2496. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2497. if (!p)
  2498. return NULL;
  2499. p->kind = Import_kind;
  2500. p->v.Import.names = names;
  2501. p->lineno = lineno;
  2502. p->col_offset = col_offset;
  2503. p->end_lineno = end_lineno;
  2504. p->end_col_offset = end_col_offset;
  2505. return p;
  2506. }
  2507. stmt_ty
  2508. ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int
  2509. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2510. {
  2511. stmt_ty p;
  2512. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2513. if (!p)
  2514. return NULL;
  2515. p->kind = ImportFrom_kind;
  2516. p->v.ImportFrom.module = module;
  2517. p->v.ImportFrom.names = names;
  2518. p->v.ImportFrom.level = level;
  2519. p->lineno = lineno;
  2520. p->col_offset = col_offset;
  2521. p->end_lineno = end_lineno;
  2522. p->end_col_offset = end_col_offset;
  2523. return p;
  2524. }
  2525. stmt_ty
  2526. Global(asdl_seq * names, int lineno, int col_offset, int end_lineno, int
  2527. end_col_offset, PyArena *arena)
  2528. {
  2529. stmt_ty p;
  2530. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2531. if (!p)
  2532. return NULL;
  2533. p->kind = Global_kind;
  2534. p->v.Global.names = names;
  2535. p->lineno = lineno;
  2536. p->col_offset = col_offset;
  2537. p->end_lineno = end_lineno;
  2538. p->end_col_offset = end_col_offset;
  2539. return p;
  2540. }
  2541. stmt_ty
  2542. Nonlocal(asdl_seq * names, int lineno, int col_offset, int end_lineno, int
  2543. end_col_offset, PyArena *arena)
  2544. {
  2545. stmt_ty p;
  2546. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2547. if (!p)
  2548. return NULL;
  2549. p->kind = Nonlocal_kind;
  2550. p->v.Nonlocal.names = names;
  2551. p->lineno = lineno;
  2552. p->col_offset = col_offset;
  2553. p->end_lineno = end_lineno;
  2554. p->end_col_offset = end_col_offset;
  2555. return p;
  2556. }
  2557. stmt_ty
  2558. Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int
  2559. end_col_offset, PyArena *arena)
  2560. {
  2561. stmt_ty p;
  2562. if (!value) {
  2563. PyErr_SetString(PyExc_ValueError,
  2564. "field 'value' is required for Expr");
  2565. return NULL;
  2566. }
  2567. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2568. if (!p)
  2569. return NULL;
  2570. p->kind = Expr_kind;
  2571. p->v.Expr.value = value;
  2572. p->lineno = lineno;
  2573. p->col_offset = col_offset;
  2574. p->end_lineno = end_lineno;
  2575. p->end_col_offset = end_col_offset;
  2576. return p;
  2577. }
  2578. stmt_ty
  2579. Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena
  2580. *arena)
  2581. {
  2582. stmt_ty p;
  2583. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2584. if (!p)
  2585. return NULL;
  2586. p->kind = Pass_kind;
  2587. p->lineno = lineno;
  2588. p->col_offset = col_offset;
  2589. p->end_lineno = end_lineno;
  2590. p->end_col_offset = end_col_offset;
  2591. return p;
  2592. }
  2593. stmt_ty
  2594. Break(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena
  2595. *arena)
  2596. {
  2597. stmt_ty p;
  2598. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2599. if (!p)
  2600. return NULL;
  2601. p->kind = Break_kind;
  2602. p->lineno = lineno;
  2603. p->col_offset = col_offset;
  2604. p->end_lineno = end_lineno;
  2605. p->end_col_offset = end_col_offset;
  2606. return p;
  2607. }
  2608. stmt_ty
  2609. Continue(int lineno, int col_offset, int end_lineno, int end_col_offset,
  2610. PyArena *arena)
  2611. {
  2612. stmt_ty p;
  2613. p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
  2614. if (!p)
  2615. return NULL;
  2616. p->kind = Continue_kind;
  2617. p->lineno = lineno;
  2618. p->col_offset = col_offset;
  2619. p->end_lineno = end_lineno;
  2620. p->end_col_offset = end_col_offset;
  2621. return p;
  2622. }
  2623. expr_ty
  2624. BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int
  2625. end_lineno, int end_col_offset, PyArena *arena)
  2626. {
  2627. expr_ty p;
  2628. if (!op) {
  2629. PyErr_SetString(PyExc_ValueError,
  2630. "field 'op' is required for BoolOp");
  2631. return NULL;
  2632. }
  2633. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2634. if (!p)
  2635. return NULL;
  2636. p->kind = BoolOp_kind;
  2637. p->v.BoolOp.op = op;
  2638. p->v.BoolOp.values = values;
  2639. p->lineno = lineno;
  2640. p->col_offset = col_offset;
  2641. p->end_lineno = end_lineno;
  2642. p->end_col_offset = end_col_offset;
  2643. return p;
  2644. }
  2645. expr_ty
  2646. NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int
  2647. end_lineno, int end_col_offset, PyArena *arena)
  2648. {
  2649. expr_ty p;
  2650. if (!target) {
  2651. PyErr_SetString(PyExc_ValueError,
  2652. "field 'target' is required for NamedExpr");
  2653. return NULL;
  2654. }
  2655. if (!value) {
  2656. PyErr_SetString(PyExc_ValueError,
  2657. "field 'value' is required for NamedExpr");
  2658. return NULL;
  2659. }
  2660. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2661. if (!p)
  2662. return NULL;
  2663. p->kind = NamedExpr_kind;
  2664. p->v.NamedExpr.target = target;
  2665. p->v.NamedExpr.value = value;
  2666. p->lineno = lineno;
  2667. p->col_offset = col_offset;
  2668. p->end_lineno = end_lineno;
  2669. p->end_col_offset = end_col_offset;
  2670. return p;
  2671. }
  2672. expr_ty
  2673. BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset,
  2674. int end_lineno, int end_col_offset, PyArena *arena)
  2675. {
  2676. expr_ty p;
  2677. if (!left) {
  2678. PyErr_SetString(PyExc_ValueError,
  2679. "field 'left' is required for BinOp");
  2680. return NULL;
  2681. }
  2682. if (!op) {
  2683. PyErr_SetString(PyExc_ValueError,
  2684. "field 'op' is required for BinOp");
  2685. return NULL;
  2686. }
  2687. if (!right) {
  2688. PyErr_SetString(PyExc_ValueError,
  2689. "field 'right' is required for BinOp");
  2690. return NULL;
  2691. }
  2692. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2693. if (!p)
  2694. return NULL;
  2695. p->kind = BinOp_kind;
  2696. p->v.BinOp.left = left;
  2697. p->v.BinOp.op = op;
  2698. p->v.BinOp.right = right;
  2699. p->lineno = lineno;
  2700. p->col_offset = col_offset;
  2701. p->end_lineno = end_lineno;
  2702. p->end_col_offset = end_col_offset;
  2703. return p;
  2704. }
  2705. expr_ty
  2706. UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int
  2707. end_lineno, int end_col_offset, PyArena *arena)
  2708. {
  2709. expr_ty p;
  2710. if (!op) {
  2711. PyErr_SetString(PyExc_ValueError,
  2712. "field 'op' is required for UnaryOp");
  2713. return NULL;
  2714. }
  2715. if (!operand) {
  2716. PyErr_SetString(PyExc_ValueError,
  2717. "field 'operand' is required for UnaryOp");
  2718. return NULL;
  2719. }
  2720. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2721. if (!p)
  2722. return NULL;
  2723. p->kind = UnaryOp_kind;
  2724. p->v.UnaryOp.op = op;
  2725. p->v.UnaryOp.operand = operand;
  2726. p->lineno = lineno;
  2727. p->col_offset = col_offset;
  2728. p->end_lineno = end_lineno;
  2729. p->end_col_offset = end_col_offset;
  2730. return p;
  2731. }
  2732. expr_ty
  2733. Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int
  2734. end_lineno, int end_col_offset, PyArena *arena)
  2735. {
  2736. expr_ty p;
  2737. if (!args) {
  2738. PyErr_SetString(PyExc_ValueError,
  2739. "field 'args' is required for Lambda");
  2740. return NULL;
  2741. }
  2742. if (!body) {
  2743. PyErr_SetString(PyExc_ValueError,
  2744. "field 'body' is required for Lambda");
  2745. return NULL;
  2746. }
  2747. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2748. if (!p)
  2749. return NULL;
  2750. p->kind = Lambda_kind;
  2751. p->v.Lambda.args = args;
  2752. p->v.Lambda.body = body;
  2753. p->lineno = lineno;
  2754. p->col_offset = col_offset;
  2755. p->end_lineno = end_lineno;
  2756. p->end_col_offset = end_col_offset;
  2757. return p;
  2758. }
  2759. expr_ty
  2760. IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset,
  2761. int end_lineno, int end_col_offset, PyArena *arena)
  2762. {
  2763. expr_ty p;
  2764. if (!test) {
  2765. PyErr_SetString(PyExc_ValueError,
  2766. "field 'test' is required for IfExp");
  2767. return NULL;
  2768. }
  2769. if (!body) {
  2770. PyErr_SetString(PyExc_ValueError,
  2771. "field 'body' is required for IfExp");
  2772. return NULL;
  2773. }
  2774. if (!orelse) {
  2775. PyErr_SetString(PyExc_ValueError,
  2776. "field 'orelse' is required for IfExp");
  2777. return NULL;
  2778. }
  2779. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2780. if (!p)
  2781. return NULL;
  2782. p->kind = IfExp_kind;
  2783. p->v.IfExp.test = test;
  2784. p->v.IfExp.body = body;
  2785. p->v.IfExp.orelse = orelse;
  2786. p->lineno = lineno;
  2787. p->col_offset = col_offset;
  2788. p->end_lineno = end_lineno;
  2789. p->end_col_offset = end_col_offset;
  2790. return p;
  2791. }
  2792. expr_ty
  2793. Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int
  2794. end_lineno, int end_col_offset, PyArena *arena)
  2795. {
  2796. expr_ty p;
  2797. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2798. if (!p)
  2799. return NULL;
  2800. p->kind = Dict_kind;
  2801. p->v.Dict.keys = keys;
  2802. p->v.Dict.values = values;
  2803. p->lineno = lineno;
  2804. p->col_offset = col_offset;
  2805. p->end_lineno = end_lineno;
  2806. p->end_col_offset = end_col_offset;
  2807. return p;
  2808. }
  2809. expr_ty
  2810. Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int
  2811. end_col_offset, PyArena *arena)
  2812. {
  2813. expr_ty p;
  2814. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2815. if (!p)
  2816. return NULL;
  2817. p->kind = Set_kind;
  2818. p->v.Set.elts = elts;
  2819. p->lineno = lineno;
  2820. p->col_offset = col_offset;
  2821. p->end_lineno = end_lineno;
  2822. p->end_col_offset = end_col_offset;
  2823. return p;
  2824. }
  2825. expr_ty
  2826. ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int
  2827. end_lineno, int end_col_offset, PyArena *arena)
  2828. {
  2829. expr_ty p;
  2830. if (!elt) {
  2831. PyErr_SetString(PyExc_ValueError,
  2832. "field 'elt' is required for ListComp");
  2833. return NULL;
  2834. }
  2835. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2836. if (!p)
  2837. return NULL;
  2838. p->kind = ListComp_kind;
  2839. p->v.ListComp.elt = elt;
  2840. p->v.ListComp.generators = generators;
  2841. p->lineno = lineno;
  2842. p->col_offset = col_offset;
  2843. p->end_lineno = end_lineno;
  2844. p->end_col_offset = end_col_offset;
  2845. return p;
  2846. }
  2847. expr_ty
  2848. SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int
  2849. end_lineno, int end_col_offset, PyArena *arena)
  2850. {
  2851. expr_ty p;
  2852. if (!elt) {
  2853. PyErr_SetString(PyExc_ValueError,
  2854. "field 'elt' is required for SetComp");
  2855. return NULL;
  2856. }
  2857. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2858. if (!p)
  2859. return NULL;
  2860. p->kind = SetComp_kind;
  2861. p->v.SetComp.elt = elt;
  2862. p->v.SetComp.generators = generators;
  2863. p->lineno = lineno;
  2864. p->col_offset = col_offset;
  2865. p->end_lineno = end_lineno;
  2866. p->end_col_offset = end_col_offset;
  2867. return p;
  2868. }
  2869. expr_ty
  2870. DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int
  2871. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2872. {
  2873. expr_ty p;
  2874. if (!key) {
  2875. PyErr_SetString(PyExc_ValueError,
  2876. "field 'key' is required for DictComp");
  2877. return NULL;
  2878. }
  2879. if (!value) {
  2880. PyErr_SetString(PyExc_ValueError,
  2881. "field 'value' is required for DictComp");
  2882. return NULL;
  2883. }
  2884. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2885. if (!p)
  2886. return NULL;
  2887. p->kind = DictComp_kind;
  2888. p->v.DictComp.key = key;
  2889. p->v.DictComp.value = value;
  2890. p->v.DictComp.generators = generators;
  2891. p->lineno = lineno;
  2892. p->col_offset = col_offset;
  2893. p->end_lineno = end_lineno;
  2894. p->end_col_offset = end_col_offset;
  2895. return p;
  2896. }
  2897. expr_ty
  2898. GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
  2899. int end_lineno, int end_col_offset, PyArena *arena)
  2900. {
  2901. expr_ty p;
  2902. if (!elt) {
  2903. PyErr_SetString(PyExc_ValueError,
  2904. "field 'elt' is required for GeneratorExp");
  2905. return NULL;
  2906. }
  2907. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2908. if (!p)
  2909. return NULL;
  2910. p->kind = GeneratorExp_kind;
  2911. p->v.GeneratorExp.elt = elt;
  2912. p->v.GeneratorExp.generators = generators;
  2913. p->lineno = lineno;
  2914. p->col_offset = col_offset;
  2915. p->end_lineno = end_lineno;
  2916. p->end_col_offset = end_col_offset;
  2917. return p;
  2918. }
  2919. expr_ty
  2920. Await(expr_ty value, int lineno, int col_offset, int end_lineno, int
  2921. end_col_offset, PyArena *arena)
  2922. {
  2923. expr_ty p;
  2924. if (!value) {
  2925. PyErr_SetString(PyExc_ValueError,
  2926. "field 'value' is required for Await");
  2927. return NULL;
  2928. }
  2929. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2930. if (!p)
  2931. return NULL;
  2932. p->kind = Await_kind;
  2933. p->v.Await.value = value;
  2934. p->lineno = lineno;
  2935. p->col_offset = col_offset;
  2936. p->end_lineno = end_lineno;
  2937. p->end_col_offset = end_col_offset;
  2938. return p;
  2939. }
  2940. expr_ty
  2941. Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int
  2942. end_col_offset, PyArena *arena)
  2943. {
  2944. expr_ty p;
  2945. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2946. if (!p)
  2947. return NULL;
  2948. p->kind = Yield_kind;
  2949. p->v.Yield.value = value;
  2950. p->lineno = lineno;
  2951. p->col_offset = col_offset;
  2952. p->end_lineno = end_lineno;
  2953. p->end_col_offset = end_col_offset;
  2954. return p;
  2955. }
  2956. expr_ty
  2957. YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int
  2958. end_col_offset, PyArena *arena)
  2959. {
  2960. expr_ty p;
  2961. if (!value) {
  2962. PyErr_SetString(PyExc_ValueError,
  2963. "field 'value' is required for YieldFrom");
  2964. return NULL;
  2965. }
  2966. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2967. if (!p)
  2968. return NULL;
  2969. p->kind = YieldFrom_kind;
  2970. p->v.YieldFrom.value = value;
  2971. p->lineno = lineno;
  2972. p->col_offset = col_offset;
  2973. p->end_lineno = end_lineno;
  2974. p->end_col_offset = end_col_offset;
  2975. return p;
  2976. }
  2977. expr_ty
  2978. Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno,
  2979. int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  2980. {
  2981. expr_ty p;
  2982. if (!left) {
  2983. PyErr_SetString(PyExc_ValueError,
  2984. "field 'left' is required for Compare");
  2985. return NULL;
  2986. }
  2987. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  2988. if (!p)
  2989. return NULL;
  2990. p->kind = Compare_kind;
  2991. p->v.Compare.left = left;
  2992. p->v.Compare.ops = ops;
  2993. p->v.Compare.comparators = comparators;
  2994. p->lineno = lineno;
  2995. p->col_offset = col_offset;
  2996. p->end_lineno = end_lineno;
  2997. p->end_col_offset = end_col_offset;
  2998. return p;
  2999. }
  3000. expr_ty
  3001. Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int
  3002. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  3003. {
  3004. expr_ty p;
  3005. if (!func) {
  3006. PyErr_SetString(PyExc_ValueError,
  3007. "field 'func' is required for Call");
  3008. return NULL;
  3009. }
  3010. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3011. if (!p)
  3012. return NULL;
  3013. p->kind = Call_kind;
  3014. p->v.Call.func = func;
  3015. p->v.Call.args = args;
  3016. p->v.Call.keywords = keywords;
  3017. p->lineno = lineno;
  3018. p->col_offset = col_offset;
  3019. p->end_lineno = end_lineno;
  3020. p->end_col_offset = end_col_offset;
  3021. return p;
  3022. }
  3023. expr_ty
  3024. FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno,
  3025. int col_offset, int end_lineno, int end_col_offset, PyArena
  3026. *arena)
  3027. {
  3028. expr_ty p;
  3029. if (!value) {
  3030. PyErr_SetString(PyExc_ValueError,
  3031. "field 'value' is required for FormattedValue");
  3032. return NULL;
  3033. }
  3034. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3035. if (!p)
  3036. return NULL;
  3037. p->kind = FormattedValue_kind;
  3038. p->v.FormattedValue.value = value;
  3039. p->v.FormattedValue.conversion = conversion;
  3040. p->v.FormattedValue.format_spec = format_spec;
  3041. p->lineno = lineno;
  3042. p->col_offset = col_offset;
  3043. p->end_lineno = end_lineno;
  3044. p->end_col_offset = end_col_offset;
  3045. return p;
  3046. }
  3047. expr_ty
  3048. JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int
  3049. end_col_offset, PyArena *arena)
  3050. {
  3051. expr_ty p;
  3052. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3053. if (!p)
  3054. return NULL;
  3055. p->kind = JoinedStr_kind;
  3056. p->v.JoinedStr.values = values;
  3057. p->lineno = lineno;
  3058. p->col_offset = col_offset;
  3059. p->end_lineno = end_lineno;
  3060. p->end_col_offset = end_col_offset;
  3061. return p;
  3062. }
  3063. expr_ty
  3064. Constant(constant value, string kind, int lineno, int col_offset, int
  3065. end_lineno, int end_col_offset, PyArena *arena)
  3066. {
  3067. expr_ty p;
  3068. if (!value) {
  3069. PyErr_SetString(PyExc_ValueError,
  3070. "field 'value' is required for Constant");
  3071. return NULL;
  3072. }
  3073. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3074. if (!p)
  3075. return NULL;
  3076. p->kind = Constant_kind;
  3077. p->v.Constant.value = value;
  3078. p->v.Constant.kind = kind;
  3079. p->lineno = lineno;
  3080. p->col_offset = col_offset;
  3081. p->end_lineno = end_lineno;
  3082. p->end_col_offset = end_col_offset;
  3083. return p;
  3084. }
  3085. expr_ty
  3086. Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
  3087. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  3088. {
  3089. expr_ty p;
  3090. if (!value) {
  3091. PyErr_SetString(PyExc_ValueError,
  3092. "field 'value' is required for Attribute");
  3093. return NULL;
  3094. }
  3095. if (!attr) {
  3096. PyErr_SetString(PyExc_ValueError,
  3097. "field 'attr' is required for Attribute");
  3098. return NULL;
  3099. }
  3100. if (!ctx) {
  3101. PyErr_SetString(PyExc_ValueError,
  3102. "field 'ctx' is required for Attribute");
  3103. return NULL;
  3104. }
  3105. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3106. if (!p)
  3107. return NULL;
  3108. p->kind = Attribute_kind;
  3109. p->v.Attribute.value = value;
  3110. p->v.Attribute.attr = attr;
  3111. p->v.Attribute.ctx = ctx;
  3112. p->lineno = lineno;
  3113. p->col_offset = col_offset;
  3114. p->end_lineno = end_lineno;
  3115. p->end_col_offset = end_col_offset;
  3116. return p;
  3117. }
  3118. expr_ty
  3119. Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, int
  3120. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  3121. {
  3122. expr_ty p;
  3123. if (!value) {
  3124. PyErr_SetString(PyExc_ValueError,
  3125. "field 'value' is required for Subscript");
  3126. return NULL;
  3127. }
  3128. if (!slice) {
  3129. PyErr_SetString(PyExc_ValueError,
  3130. "field 'slice' is required for Subscript");
  3131. return NULL;
  3132. }
  3133. if (!ctx) {
  3134. PyErr_SetString(PyExc_ValueError,
  3135. "field 'ctx' is required for Subscript");
  3136. return NULL;
  3137. }
  3138. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3139. if (!p)
  3140. return NULL;
  3141. p->kind = Subscript_kind;
  3142. p->v.Subscript.value = value;
  3143. p->v.Subscript.slice = slice;
  3144. p->v.Subscript.ctx = ctx;
  3145. p->lineno = lineno;
  3146. p->col_offset = col_offset;
  3147. p->end_lineno = end_lineno;
  3148. p->end_col_offset = end_col_offset;
  3149. return p;
  3150. }
  3151. expr_ty
  3152. Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int
  3153. end_lineno, int end_col_offset, PyArena *arena)
  3154. {
  3155. expr_ty p;
  3156. if (!value) {
  3157. PyErr_SetString(PyExc_ValueError,
  3158. "field 'value' is required for Starred");
  3159. return NULL;
  3160. }
  3161. if (!ctx) {
  3162. PyErr_SetString(PyExc_ValueError,
  3163. "field 'ctx' is required for Starred");
  3164. return NULL;
  3165. }
  3166. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3167. if (!p)
  3168. return NULL;
  3169. p->kind = Starred_kind;
  3170. p->v.Starred.value = value;
  3171. p->v.Starred.ctx = ctx;
  3172. p->lineno = lineno;
  3173. p->col_offset = col_offset;
  3174. p->end_lineno = end_lineno;
  3175. p->end_col_offset = end_col_offset;
  3176. return p;
  3177. }
  3178. expr_ty
  3179. Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int
  3180. end_lineno, int end_col_offset, PyArena *arena)
  3181. {
  3182. expr_ty p;
  3183. if (!id) {
  3184. PyErr_SetString(PyExc_ValueError,
  3185. "field 'id' is required for Name");
  3186. return NULL;
  3187. }
  3188. if (!ctx) {
  3189. PyErr_SetString(PyExc_ValueError,
  3190. "field 'ctx' is required for Name");
  3191. return NULL;
  3192. }
  3193. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3194. if (!p)
  3195. return NULL;
  3196. p->kind = Name_kind;
  3197. p->v.Name.id = id;
  3198. p->v.Name.ctx = ctx;
  3199. p->lineno = lineno;
  3200. p->col_offset = col_offset;
  3201. p->end_lineno = end_lineno;
  3202. p->end_col_offset = end_col_offset;
  3203. return p;
  3204. }
  3205. expr_ty
  3206. List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int
  3207. end_lineno, int end_col_offset, PyArena *arena)
  3208. {
  3209. expr_ty p;
  3210. if (!ctx) {
  3211. PyErr_SetString(PyExc_ValueError,
  3212. "field 'ctx' is required for List");
  3213. return NULL;
  3214. }
  3215. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3216. if (!p)
  3217. return NULL;
  3218. p->kind = List_kind;
  3219. p->v.List.elts = elts;
  3220. p->v.List.ctx = ctx;
  3221. p->lineno = lineno;
  3222. p->col_offset = col_offset;
  3223. p->end_lineno = end_lineno;
  3224. p->end_col_offset = end_col_offset;
  3225. return p;
  3226. }
  3227. expr_ty
  3228. Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int
  3229. end_lineno, int end_col_offset, PyArena *arena)
  3230. {
  3231. expr_ty p;
  3232. if (!ctx) {
  3233. PyErr_SetString(PyExc_ValueError,
  3234. "field 'ctx' is required for Tuple");
  3235. return NULL;
  3236. }
  3237. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3238. if (!p)
  3239. return NULL;
  3240. p->kind = Tuple_kind;
  3241. p->v.Tuple.elts = elts;
  3242. p->v.Tuple.ctx = ctx;
  3243. p->lineno = lineno;
  3244. p->col_offset = col_offset;
  3245. p->end_lineno = end_lineno;
  3246. p->end_col_offset = end_col_offset;
  3247. return p;
  3248. }
  3249. expr_ty
  3250. Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset,
  3251. int end_lineno, int end_col_offset, PyArena *arena)
  3252. {
  3253. expr_ty p;
  3254. p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
  3255. if (!p)
  3256. return NULL;
  3257. p->kind = Slice_kind;
  3258. p->v.Slice.lower = lower;
  3259. p->v.Slice.upper = upper;
  3260. p->v.Slice.step = step;
  3261. p->lineno = lineno;
  3262. p->col_offset = col_offset;
  3263. p->end_lineno = end_lineno;
  3264. p->end_col_offset = end_col_offset;
  3265. return p;
  3266. }
  3267. comprehension_ty
  3268. comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async,
  3269. PyArena *arena)
  3270. {
  3271. comprehension_ty p;
  3272. if (!target) {
  3273. PyErr_SetString(PyExc_ValueError,
  3274. "field 'target' is required for comprehension");
  3275. return NULL;
  3276. }
  3277. if (!iter) {
  3278. PyErr_SetString(PyExc_ValueError,
  3279. "field 'iter' is required for comprehension");
  3280. return NULL;
  3281. }
  3282. p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p));
  3283. if (!p)
  3284. return NULL;
  3285. p->target = target;
  3286. p->iter = iter;
  3287. p->ifs = ifs;
  3288. p->is_async = is_async;
  3289. return p;
  3290. }
  3291. excepthandler_ty
  3292. ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int
  3293. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  3294. {
  3295. excepthandler_ty p;
  3296. p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
  3297. if (!p)
  3298. return NULL;
  3299. p->kind = ExceptHandler_kind;
  3300. p->v.ExceptHandler.type = type;
  3301. p->v.ExceptHandler.name = name;
  3302. p->v.ExceptHandler.body = body;
  3303. p->lineno = lineno;
  3304. p->col_offset = col_offset;
  3305. p->end_lineno = end_lineno;
  3306. p->end_col_offset = end_col_offset;
  3307. return p;
  3308. }
  3309. arguments_ty
  3310. arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq *
  3311. kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq *
  3312. defaults, PyArena *arena)
  3313. {
  3314. arguments_ty p;
  3315. p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
  3316. if (!p)
  3317. return NULL;
  3318. p->posonlyargs = posonlyargs;
  3319. p->args = args;
  3320. p->vararg = vararg;
  3321. p->kwonlyargs = kwonlyargs;
  3322. p->kw_defaults = kw_defaults;
  3323. p->kwarg = kwarg;
  3324. p->defaults = defaults;
  3325. return p;
  3326. }
  3327. arg_ty
  3328. arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int
  3329. col_offset, int end_lineno, int end_col_offset, PyArena *arena)
  3330. {
  3331. arg_ty p;
  3332. if (!arg) {
  3333. PyErr_SetString(PyExc_ValueError,
  3334. "field 'arg' is required for arg");
  3335. return NULL;
  3336. }
  3337. p = (arg_ty)PyArena_Malloc(arena, sizeof(*p));
  3338. if (!p)
  3339. return NULL;
  3340. p->arg = arg;
  3341. p->annotation = annotation;
  3342. p->type_comment = type_comment;
  3343. p->lineno = lineno;
  3344. p->col_offset = col_offset;
  3345. p->end_lineno = end_lineno;
  3346. p->end_col_offset = end_col_offset;
  3347. return p;
  3348. }
  3349. keyword_ty
  3350. keyword(identifier arg, expr_ty value, int lineno, int col_offset, int
  3351. end_lineno, int end_col_offset, PyArena *arena)
  3352. {
  3353. keyword_ty p;
  3354. if (!value) {
  3355. PyErr_SetString(PyExc_ValueError,
  3356. "field 'value' is required for keyword");
  3357. return NULL;
  3358. }
  3359. p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p));
  3360. if (!p)
  3361. return NULL;
  3362. p->arg = arg;
  3363. p->value = value;
  3364. p->lineno = lineno;
  3365. p->col_offset = col_offset;
  3366. p->end_lineno = end_lineno;
  3367. p->end_col_offset = end_col_offset;
  3368. return p;
  3369. }
  3370. alias_ty
  3371. alias(identifier name, identifier asname, PyArena *arena)
  3372. {
  3373. alias_ty p;
  3374. if (!name) {
  3375. PyErr_SetString(PyExc_ValueError,
  3376. "field 'name' is required for alias");
  3377. return NULL;
  3378. }
  3379. p = (alias_ty)PyArena_Malloc(arena, sizeof(*p));
  3380. if (!p)
  3381. return NULL;
  3382. p->name = name;
  3383. p->asname = asname;
  3384. return p;
  3385. }
  3386. withitem_ty
  3387. withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena)
  3388. {
  3389. withitem_ty p;
  3390. if (!context_expr) {
  3391. PyErr_SetString(PyExc_ValueError,
  3392. "field 'context_expr' is required for withitem");
  3393. return NULL;
  3394. }
  3395. p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p));
  3396. if (!p)
  3397. return NULL;
  3398. p->context_expr = context_expr;
  3399. p->optional_vars = optional_vars;
  3400. return p;
  3401. }
  3402. type_ignore_ty
  3403. TypeIgnore(int lineno, string tag, PyArena *arena)
  3404. {
  3405. type_ignore_ty p;
  3406. if (!tag) {
  3407. PyErr_SetString(PyExc_ValueError,
  3408. "field 'tag' is required for TypeIgnore");
  3409. return NULL;
  3410. }
  3411. p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p));
  3412. if (!p)
  3413. return NULL;
  3414. p->kind = TypeIgnore_kind;
  3415. p->v.TypeIgnore.lineno = lineno;
  3416. p->v.TypeIgnore.tag = tag;
  3417. return p;
  3418. }
  3419. PyObject*
  3420. ast2obj_mod(void* _o)
  3421. {
  3422. mod_ty o = (mod_ty)_o;
  3423. PyObject *result = NULL, *value = NULL;
  3424. PyTypeObject *tp;
  3425. if (!o) {
  3426. Py_RETURN_NONE;
  3427. }
  3428. switch (o->kind) {
  3429. case Module_kind:
  3430. tp = (PyTypeObject *)astmodulestate_global->Module_type;
  3431. result = PyType_GenericNew(tp, NULL, NULL);
  3432. if (!result) goto failed;
  3433. value = ast2obj_list(o->v.Module.body, ast2obj_stmt);
  3434. if (!value) goto failed;
  3435. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3436. goto failed;
  3437. Py_DECREF(value);
  3438. value = ast2obj_list(o->v.Module.type_ignores, ast2obj_type_ignore);
  3439. if (!value) goto failed;
  3440. if (PyObject_SetAttr(result, astmodulestate_global->type_ignores,
  3441. value) == -1)
  3442. goto failed;
  3443. Py_DECREF(value);
  3444. break;
  3445. case Interactive_kind:
  3446. tp = (PyTypeObject *)astmodulestate_global->Interactive_type;
  3447. result = PyType_GenericNew(tp, NULL, NULL);
  3448. if (!result) goto failed;
  3449. value = ast2obj_list(o->v.Interactive.body, ast2obj_stmt);
  3450. if (!value) goto failed;
  3451. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3452. goto failed;
  3453. Py_DECREF(value);
  3454. break;
  3455. case Expression_kind:
  3456. tp = (PyTypeObject *)astmodulestate_global->Expression_type;
  3457. result = PyType_GenericNew(tp, NULL, NULL);
  3458. if (!result) goto failed;
  3459. value = ast2obj_expr(o->v.Expression.body);
  3460. if (!value) goto failed;
  3461. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3462. goto failed;
  3463. Py_DECREF(value);
  3464. break;
  3465. case FunctionType_kind:
  3466. tp = (PyTypeObject *)astmodulestate_global->FunctionType_type;
  3467. result = PyType_GenericNew(tp, NULL, NULL);
  3468. if (!result) goto failed;
  3469. value = ast2obj_list(o->v.FunctionType.argtypes, ast2obj_expr);
  3470. if (!value) goto failed;
  3471. if (PyObject_SetAttr(result, astmodulestate_global->argtypes, value) ==
  3472. -1)
  3473. goto failed;
  3474. Py_DECREF(value);
  3475. value = ast2obj_expr(o->v.FunctionType.returns);
  3476. if (!value) goto failed;
  3477. if (PyObject_SetAttr(result, astmodulestate_global->returns, value) ==
  3478. -1)
  3479. goto failed;
  3480. Py_DECREF(value);
  3481. break;
  3482. }
  3483. return result;
  3484. failed:
  3485. Py_XDECREF(value);
  3486. Py_XDECREF(result);
  3487. return NULL;
  3488. }
  3489. PyObject*
  3490. ast2obj_stmt(void* _o)
  3491. {
  3492. stmt_ty o = (stmt_ty)_o;
  3493. PyObject *result = NULL, *value = NULL;
  3494. PyTypeObject *tp;
  3495. if (!o) {
  3496. Py_RETURN_NONE;
  3497. }
  3498. switch (o->kind) {
  3499. case FunctionDef_kind:
  3500. tp = (PyTypeObject *)astmodulestate_global->FunctionDef_type;
  3501. result = PyType_GenericNew(tp, NULL, NULL);
  3502. if (!result) goto failed;
  3503. value = ast2obj_identifier(o->v.FunctionDef.name);
  3504. if (!value) goto failed;
  3505. if (PyObject_SetAttr(result, astmodulestate_global->name, value) == -1)
  3506. goto failed;
  3507. Py_DECREF(value);
  3508. value = ast2obj_arguments(o->v.FunctionDef.args);
  3509. if (!value) goto failed;
  3510. if (PyObject_SetAttr(result, astmodulestate_global->args, value) == -1)
  3511. goto failed;
  3512. Py_DECREF(value);
  3513. value = ast2obj_list(o->v.FunctionDef.body, ast2obj_stmt);
  3514. if (!value) goto failed;
  3515. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3516. goto failed;
  3517. Py_DECREF(value);
  3518. value = ast2obj_list(o->v.FunctionDef.decorator_list, ast2obj_expr);
  3519. if (!value) goto failed;
  3520. if (PyObject_SetAttr(result, astmodulestate_global->decorator_list,
  3521. value) == -1)
  3522. goto failed;
  3523. Py_DECREF(value);
  3524. value = ast2obj_expr(o->v.FunctionDef.returns);
  3525. if (!value) goto failed;
  3526. if (PyObject_SetAttr(result, astmodulestate_global->returns, value) ==
  3527. -1)
  3528. goto failed;
  3529. Py_DECREF(value);
  3530. value = ast2obj_string(o->v.FunctionDef.type_comment);
  3531. if (!value) goto failed;
  3532. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3533. value) == -1)
  3534. goto failed;
  3535. Py_DECREF(value);
  3536. break;
  3537. case AsyncFunctionDef_kind:
  3538. tp = (PyTypeObject *)astmodulestate_global->AsyncFunctionDef_type;
  3539. result = PyType_GenericNew(tp, NULL, NULL);
  3540. if (!result) goto failed;
  3541. value = ast2obj_identifier(o->v.AsyncFunctionDef.name);
  3542. if (!value) goto failed;
  3543. if (PyObject_SetAttr(result, astmodulestate_global->name, value) == -1)
  3544. goto failed;
  3545. Py_DECREF(value);
  3546. value = ast2obj_arguments(o->v.AsyncFunctionDef.args);
  3547. if (!value) goto failed;
  3548. if (PyObject_SetAttr(result, astmodulestate_global->args, value) == -1)
  3549. goto failed;
  3550. Py_DECREF(value);
  3551. value = ast2obj_list(o->v.AsyncFunctionDef.body, ast2obj_stmt);
  3552. if (!value) goto failed;
  3553. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3554. goto failed;
  3555. Py_DECREF(value);
  3556. value = ast2obj_list(o->v.AsyncFunctionDef.decorator_list,
  3557. ast2obj_expr);
  3558. if (!value) goto failed;
  3559. if (PyObject_SetAttr(result, astmodulestate_global->decorator_list,
  3560. value) == -1)
  3561. goto failed;
  3562. Py_DECREF(value);
  3563. value = ast2obj_expr(o->v.AsyncFunctionDef.returns);
  3564. if (!value) goto failed;
  3565. if (PyObject_SetAttr(result, astmodulestate_global->returns, value) ==
  3566. -1)
  3567. goto failed;
  3568. Py_DECREF(value);
  3569. value = ast2obj_string(o->v.AsyncFunctionDef.type_comment);
  3570. if (!value) goto failed;
  3571. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3572. value) == -1)
  3573. goto failed;
  3574. Py_DECREF(value);
  3575. break;
  3576. case ClassDef_kind:
  3577. tp = (PyTypeObject *)astmodulestate_global->ClassDef_type;
  3578. result = PyType_GenericNew(tp, NULL, NULL);
  3579. if (!result) goto failed;
  3580. value = ast2obj_identifier(o->v.ClassDef.name);
  3581. if (!value) goto failed;
  3582. if (PyObject_SetAttr(result, astmodulestate_global->name, value) == -1)
  3583. goto failed;
  3584. Py_DECREF(value);
  3585. value = ast2obj_list(o->v.ClassDef.bases, ast2obj_expr);
  3586. if (!value) goto failed;
  3587. if (PyObject_SetAttr(result, astmodulestate_global->bases, value) == -1)
  3588. goto failed;
  3589. Py_DECREF(value);
  3590. value = ast2obj_list(o->v.ClassDef.keywords, ast2obj_keyword);
  3591. if (!value) goto failed;
  3592. if (PyObject_SetAttr(result, astmodulestate_global->keywords, value) ==
  3593. -1)
  3594. goto failed;
  3595. Py_DECREF(value);
  3596. value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt);
  3597. if (!value) goto failed;
  3598. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3599. goto failed;
  3600. Py_DECREF(value);
  3601. value = ast2obj_list(o->v.ClassDef.decorator_list, ast2obj_expr);
  3602. if (!value) goto failed;
  3603. if (PyObject_SetAttr(result, astmodulestate_global->decorator_list,
  3604. value) == -1)
  3605. goto failed;
  3606. Py_DECREF(value);
  3607. break;
  3608. case Return_kind:
  3609. tp = (PyTypeObject *)astmodulestate_global->Return_type;
  3610. result = PyType_GenericNew(tp, NULL, NULL);
  3611. if (!result) goto failed;
  3612. value = ast2obj_expr(o->v.Return.value);
  3613. if (!value) goto failed;
  3614. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  3615. goto failed;
  3616. Py_DECREF(value);
  3617. break;
  3618. case Delete_kind:
  3619. tp = (PyTypeObject *)astmodulestate_global->Delete_type;
  3620. result = PyType_GenericNew(tp, NULL, NULL);
  3621. if (!result) goto failed;
  3622. value = ast2obj_list(o->v.Delete.targets, ast2obj_expr);
  3623. if (!value) goto failed;
  3624. if (PyObject_SetAttr(result, astmodulestate_global->targets, value) ==
  3625. -1)
  3626. goto failed;
  3627. Py_DECREF(value);
  3628. break;
  3629. case Assign_kind:
  3630. tp = (PyTypeObject *)astmodulestate_global->Assign_type;
  3631. result = PyType_GenericNew(tp, NULL, NULL);
  3632. if (!result) goto failed;
  3633. value = ast2obj_list(o->v.Assign.targets, ast2obj_expr);
  3634. if (!value) goto failed;
  3635. if (PyObject_SetAttr(result, astmodulestate_global->targets, value) ==
  3636. -1)
  3637. goto failed;
  3638. Py_DECREF(value);
  3639. value = ast2obj_expr(o->v.Assign.value);
  3640. if (!value) goto failed;
  3641. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  3642. goto failed;
  3643. Py_DECREF(value);
  3644. value = ast2obj_string(o->v.Assign.type_comment);
  3645. if (!value) goto failed;
  3646. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3647. value) == -1)
  3648. goto failed;
  3649. Py_DECREF(value);
  3650. break;
  3651. case AugAssign_kind:
  3652. tp = (PyTypeObject *)astmodulestate_global->AugAssign_type;
  3653. result = PyType_GenericNew(tp, NULL, NULL);
  3654. if (!result) goto failed;
  3655. value = ast2obj_expr(o->v.AugAssign.target);
  3656. if (!value) goto failed;
  3657. if (PyObject_SetAttr(result, astmodulestate_global->target, value) ==
  3658. -1)
  3659. goto failed;
  3660. Py_DECREF(value);
  3661. value = ast2obj_operator(o->v.AugAssign.op);
  3662. if (!value) goto failed;
  3663. if (PyObject_SetAttr(result, astmodulestate_global->op, value) == -1)
  3664. goto failed;
  3665. Py_DECREF(value);
  3666. value = ast2obj_expr(o->v.AugAssign.value);
  3667. if (!value) goto failed;
  3668. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  3669. goto failed;
  3670. Py_DECREF(value);
  3671. break;
  3672. case AnnAssign_kind:
  3673. tp = (PyTypeObject *)astmodulestate_global->AnnAssign_type;
  3674. result = PyType_GenericNew(tp, NULL, NULL);
  3675. if (!result) goto failed;
  3676. value = ast2obj_expr(o->v.AnnAssign.target);
  3677. if (!value) goto failed;
  3678. if (PyObject_SetAttr(result, astmodulestate_global->target, value) ==
  3679. -1)
  3680. goto failed;
  3681. Py_DECREF(value);
  3682. value = ast2obj_expr(o->v.AnnAssign.annotation);
  3683. if (!value) goto failed;
  3684. if (PyObject_SetAttr(result, astmodulestate_global->annotation, value)
  3685. == -1)
  3686. goto failed;
  3687. Py_DECREF(value);
  3688. value = ast2obj_expr(o->v.AnnAssign.value);
  3689. if (!value) goto failed;
  3690. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  3691. goto failed;
  3692. Py_DECREF(value);
  3693. value = ast2obj_int(o->v.AnnAssign.simple);
  3694. if (!value) goto failed;
  3695. if (PyObject_SetAttr(result, astmodulestate_global->simple, value) ==
  3696. -1)
  3697. goto failed;
  3698. Py_DECREF(value);
  3699. break;
  3700. case For_kind:
  3701. tp = (PyTypeObject *)astmodulestate_global->For_type;
  3702. result = PyType_GenericNew(tp, NULL, NULL);
  3703. if (!result) goto failed;
  3704. value = ast2obj_expr(o->v.For.target);
  3705. if (!value) goto failed;
  3706. if (PyObject_SetAttr(result, astmodulestate_global->target, value) ==
  3707. -1)
  3708. goto failed;
  3709. Py_DECREF(value);
  3710. value = ast2obj_expr(o->v.For.iter);
  3711. if (!value) goto failed;
  3712. if (PyObject_SetAttr(result, astmodulestate_global->iter, value) == -1)
  3713. goto failed;
  3714. Py_DECREF(value);
  3715. value = ast2obj_list(o->v.For.body, ast2obj_stmt);
  3716. if (!value) goto failed;
  3717. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3718. goto failed;
  3719. Py_DECREF(value);
  3720. value = ast2obj_list(o->v.For.orelse, ast2obj_stmt);
  3721. if (!value) goto failed;
  3722. if (PyObject_SetAttr(result, astmodulestate_global->orelse, value) ==
  3723. -1)
  3724. goto failed;
  3725. Py_DECREF(value);
  3726. value = ast2obj_string(o->v.For.type_comment);
  3727. if (!value) goto failed;
  3728. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3729. value) == -1)
  3730. goto failed;
  3731. Py_DECREF(value);
  3732. break;
  3733. case AsyncFor_kind:
  3734. tp = (PyTypeObject *)astmodulestate_global->AsyncFor_type;
  3735. result = PyType_GenericNew(tp, NULL, NULL);
  3736. if (!result) goto failed;
  3737. value = ast2obj_expr(o->v.AsyncFor.target);
  3738. if (!value) goto failed;
  3739. if (PyObject_SetAttr(result, astmodulestate_global->target, value) ==
  3740. -1)
  3741. goto failed;
  3742. Py_DECREF(value);
  3743. value = ast2obj_expr(o->v.AsyncFor.iter);
  3744. if (!value) goto failed;
  3745. if (PyObject_SetAttr(result, astmodulestate_global->iter, value) == -1)
  3746. goto failed;
  3747. Py_DECREF(value);
  3748. value = ast2obj_list(o->v.AsyncFor.body, ast2obj_stmt);
  3749. if (!value) goto failed;
  3750. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3751. goto failed;
  3752. Py_DECREF(value);
  3753. value = ast2obj_list(o->v.AsyncFor.orelse, ast2obj_stmt);
  3754. if (!value) goto failed;
  3755. if (PyObject_SetAttr(result, astmodulestate_global->orelse, value) ==
  3756. -1)
  3757. goto failed;
  3758. Py_DECREF(value);
  3759. value = ast2obj_string(o->v.AsyncFor.type_comment);
  3760. if (!value) goto failed;
  3761. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3762. value) == -1)
  3763. goto failed;
  3764. Py_DECREF(value);
  3765. break;
  3766. case While_kind:
  3767. tp = (PyTypeObject *)astmodulestate_global->While_type;
  3768. result = PyType_GenericNew(tp, NULL, NULL);
  3769. if (!result) goto failed;
  3770. value = ast2obj_expr(o->v.While.test);
  3771. if (!value) goto failed;
  3772. if (PyObject_SetAttr(result, astmodulestate_global->test, value) == -1)
  3773. goto failed;
  3774. Py_DECREF(value);
  3775. value = ast2obj_list(o->v.While.body, ast2obj_stmt);
  3776. if (!value) goto failed;
  3777. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3778. goto failed;
  3779. Py_DECREF(value);
  3780. value = ast2obj_list(o->v.While.orelse, ast2obj_stmt);
  3781. if (!value) goto failed;
  3782. if (PyObject_SetAttr(result, astmodulestate_global->orelse, value) ==
  3783. -1)
  3784. goto failed;
  3785. Py_DECREF(value);
  3786. break;
  3787. case If_kind:
  3788. tp = (PyTypeObject *)astmodulestate_global->If_type;
  3789. result = PyType_GenericNew(tp, NULL, NULL);
  3790. if (!result) goto failed;
  3791. value = ast2obj_expr(o->v.If.test);
  3792. if (!value) goto failed;
  3793. if (PyObject_SetAttr(result, astmodulestate_global->test, value) == -1)
  3794. goto failed;
  3795. Py_DECREF(value);
  3796. value = ast2obj_list(o->v.If.body, ast2obj_stmt);
  3797. if (!value) goto failed;
  3798. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3799. goto failed;
  3800. Py_DECREF(value);
  3801. value = ast2obj_list(o->v.If.orelse, ast2obj_stmt);
  3802. if (!value) goto failed;
  3803. if (PyObject_SetAttr(result, astmodulestate_global->orelse, value) ==
  3804. -1)
  3805. goto failed;
  3806. Py_DECREF(value);
  3807. break;
  3808. case With_kind:
  3809. tp = (PyTypeObject *)astmodulestate_global->With_type;
  3810. result = PyType_GenericNew(tp, NULL, NULL);
  3811. if (!result) goto failed;
  3812. value = ast2obj_list(o->v.With.items, ast2obj_withitem);
  3813. if (!value) goto failed;
  3814. if (PyObject_SetAttr(result, astmodulestate_global->items, value) == -1)
  3815. goto failed;
  3816. Py_DECREF(value);
  3817. value = ast2obj_list(o->v.With.body, ast2obj_stmt);
  3818. if (!value) goto failed;
  3819. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3820. goto failed;
  3821. Py_DECREF(value);
  3822. value = ast2obj_string(o->v.With.type_comment);
  3823. if (!value) goto failed;
  3824. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3825. value) == -1)
  3826. goto failed;
  3827. Py_DECREF(value);
  3828. break;
  3829. case AsyncWith_kind:
  3830. tp = (PyTypeObject *)astmodulestate_global->AsyncWith_type;
  3831. result = PyType_GenericNew(tp, NULL, NULL);
  3832. if (!result) goto failed;
  3833. value = ast2obj_list(o->v.AsyncWith.items, ast2obj_withitem);
  3834. if (!value) goto failed;
  3835. if (PyObject_SetAttr(result, astmodulestate_global->items, value) == -1)
  3836. goto failed;
  3837. Py_DECREF(value);
  3838. value = ast2obj_list(o->v.AsyncWith.body, ast2obj_stmt);
  3839. if (!value) goto failed;
  3840. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3841. goto failed;
  3842. Py_DECREF(value);
  3843. value = ast2obj_string(o->v.AsyncWith.type_comment);
  3844. if (!value) goto failed;
  3845. if (PyObject_SetAttr(result, astmodulestate_global->type_comment,
  3846. value) == -1)
  3847. goto failed;
  3848. Py_DECREF(value);
  3849. break;
  3850. case Raise_kind:
  3851. tp = (PyTypeObject *)astmodulestate_global->Raise_type;
  3852. result = PyType_GenericNew(tp, NULL, NULL);
  3853. if (!result) goto failed;
  3854. value = ast2obj_expr(o->v.Raise.exc);
  3855. if (!value) goto failed;
  3856. if (PyObject_SetAttr(result, astmodulestate_global->exc, value) == -1)
  3857. goto failed;
  3858. Py_DECREF(value);
  3859. value = ast2obj_expr(o->v.Raise.cause);
  3860. if (!value) goto failed;
  3861. if (PyObject_SetAttr(result, astmodulestate_global->cause, value) == -1)
  3862. goto failed;
  3863. Py_DECREF(value);
  3864. break;
  3865. case Try_kind:
  3866. tp = (PyTypeObject *)astmodulestate_global->Try_type;
  3867. result = PyType_GenericNew(tp, NULL, NULL);
  3868. if (!result) goto failed;
  3869. value = ast2obj_list(o->v.Try.body, ast2obj_stmt);
  3870. if (!value) goto failed;
  3871. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  3872. goto failed;
  3873. Py_DECREF(value);
  3874. value = ast2obj_list(o->v.Try.handlers, ast2obj_excepthandler);
  3875. if (!value) goto failed;
  3876. if (PyObject_SetAttr(result, astmodulestate_global->handlers, value) ==
  3877. -1)
  3878. goto failed;
  3879. Py_DECREF(value);
  3880. value = ast2obj_list(o->v.Try.orelse, ast2obj_stmt);
  3881. if (!value) goto failed;
  3882. if (PyObject_SetAttr(result, astmodulestate_global->orelse, value) ==
  3883. -1)
  3884. goto failed;
  3885. Py_DECREF(value);
  3886. value = ast2obj_list(o->v.Try.finalbody, ast2obj_stmt);
  3887. if (!value) goto failed;
  3888. if (PyObject_SetAttr(result, astmodulestate_global->finalbody, value)
  3889. == -1)
  3890. goto failed;
  3891. Py_DECREF(value);
  3892. break;
  3893. case Assert_kind:
  3894. tp = (PyTypeObject *)astmodulestate_global->Assert_type;
  3895. result = PyType_GenericNew(tp, NULL, NULL);
  3896. if (!result) goto failed;
  3897. value = ast2obj_expr(o->v.Assert.test);
  3898. if (!value) goto failed;
  3899. if (PyObject_SetAttr(result, astmodulestate_global->test, value) == -1)
  3900. goto failed;
  3901. Py_DECREF(value);
  3902. value = ast2obj_expr(o->v.Assert.msg);
  3903. if (!value) goto failed;
  3904. if (PyObject_SetAttr(result, astmodulestate_global->msg, value) == -1)
  3905. goto failed;
  3906. Py_DECREF(value);
  3907. break;
  3908. case Import_kind:
  3909. tp = (PyTypeObject *)astmodulestate_global->Import_type;
  3910. result = PyType_GenericNew(tp, NULL, NULL);
  3911. if (!result) goto failed;
  3912. value = ast2obj_list(o->v.Import.names, ast2obj_alias);
  3913. if (!value) goto failed;
  3914. if (PyObject_SetAttr(result, astmodulestate_global->names, value) == -1)
  3915. goto failed;
  3916. Py_DECREF(value);
  3917. break;
  3918. case ImportFrom_kind:
  3919. tp = (PyTypeObject *)astmodulestate_global->ImportFrom_type;
  3920. result = PyType_GenericNew(tp, NULL, NULL);
  3921. if (!result) goto failed;
  3922. value = ast2obj_identifier(o->v.ImportFrom.module);
  3923. if (!value) goto failed;
  3924. if (PyObject_SetAttr(result, astmodulestate_global->module, value) ==
  3925. -1)
  3926. goto failed;
  3927. Py_DECREF(value);
  3928. value = ast2obj_list(o->v.ImportFrom.names, ast2obj_alias);
  3929. if (!value) goto failed;
  3930. if (PyObject_SetAttr(result, astmodulestate_global->names, value) == -1)
  3931. goto failed;
  3932. Py_DECREF(value);
  3933. value = ast2obj_int(o->v.ImportFrom.level);
  3934. if (!value) goto failed;
  3935. if (PyObject_SetAttr(result, astmodulestate_global->level, value) == -1)
  3936. goto failed;
  3937. Py_DECREF(value);
  3938. break;
  3939. case Global_kind:
  3940. tp = (PyTypeObject *)astmodulestate_global->Global_type;
  3941. result = PyType_GenericNew(tp, NULL, NULL);
  3942. if (!result) goto failed;
  3943. value = ast2obj_list(o->v.Global.names, ast2obj_identifier);
  3944. if (!value) goto failed;
  3945. if (PyObject_SetAttr(result, astmodulestate_global->names, value) == -1)
  3946. goto failed;
  3947. Py_DECREF(value);
  3948. break;
  3949. case Nonlocal_kind:
  3950. tp = (PyTypeObject *)astmodulestate_global->Nonlocal_type;
  3951. result = PyType_GenericNew(tp, NULL, NULL);
  3952. if (!result) goto failed;
  3953. value = ast2obj_list(o->v.Nonlocal.names, ast2obj_identifier);
  3954. if (!value) goto failed;
  3955. if (PyObject_SetAttr(result, astmodulestate_global->names, value) == -1)
  3956. goto failed;
  3957. Py_DECREF(value);
  3958. break;
  3959. case Expr_kind:
  3960. tp = (PyTypeObject *)astmodulestate_global->Expr_type;
  3961. result = PyType_GenericNew(tp, NULL, NULL);
  3962. if (!result) goto failed;
  3963. value = ast2obj_expr(o->v.Expr.value);
  3964. if (!value) goto failed;
  3965. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  3966. goto failed;
  3967. Py_DECREF(value);
  3968. break;
  3969. case Pass_kind:
  3970. tp = (PyTypeObject *)astmodulestate_global->Pass_type;
  3971. result = PyType_GenericNew(tp, NULL, NULL);
  3972. if (!result) goto failed;
  3973. break;
  3974. case Break_kind:
  3975. tp = (PyTypeObject *)astmodulestate_global->Break_type;
  3976. result = PyType_GenericNew(tp, NULL, NULL);
  3977. if (!result) goto failed;
  3978. break;
  3979. case Continue_kind:
  3980. tp = (PyTypeObject *)astmodulestate_global->Continue_type;
  3981. result = PyType_GenericNew(tp, NULL, NULL);
  3982. if (!result) goto failed;
  3983. break;
  3984. }
  3985. value = ast2obj_int(o->lineno);
  3986. if (!value) goto failed;
  3987. if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) < 0)
  3988. goto failed;
  3989. Py_DECREF(value);
  3990. value = ast2obj_int(o->col_offset);
  3991. if (!value) goto failed;
  3992. if (PyObject_SetAttr(result, astmodulestate_global->col_offset, value) < 0)
  3993. goto failed;
  3994. Py_DECREF(value);
  3995. value = ast2obj_int(o->end_lineno);
  3996. if (!value) goto failed;
  3997. if (PyObject_SetAttr(result, astmodulestate_global->end_lineno, value) < 0)
  3998. goto failed;
  3999. Py_DECREF(value);
  4000. value = ast2obj_int(o->end_col_offset);
  4001. if (!value) goto failed;
  4002. if (PyObject_SetAttr(result, astmodulestate_global->end_col_offset, value)
  4003. < 0)
  4004. goto failed;
  4005. Py_DECREF(value);
  4006. return result;
  4007. failed:
  4008. Py_XDECREF(value);
  4009. Py_XDECREF(result);
  4010. return NULL;
  4011. }
  4012. PyObject*
  4013. ast2obj_expr(void* _o)
  4014. {
  4015. expr_ty o = (expr_ty)_o;
  4016. PyObject *result = NULL, *value = NULL;
  4017. PyTypeObject *tp;
  4018. if (!o) {
  4019. Py_RETURN_NONE;
  4020. }
  4021. switch (o->kind) {
  4022. case BoolOp_kind:
  4023. tp = (PyTypeObject *)astmodulestate_global->BoolOp_type;
  4024. result = PyType_GenericNew(tp, NULL, NULL);
  4025. if (!result) goto failed;
  4026. value = ast2obj_boolop(o->v.BoolOp.op);
  4027. if (!value) goto failed;
  4028. if (PyObject_SetAttr(result, astmodulestate_global->op, value) == -1)
  4029. goto failed;
  4030. Py_DECREF(value);
  4031. value = ast2obj_list(o->v.BoolOp.values, ast2obj_expr);
  4032. if (!value) goto failed;
  4033. if (PyObject_SetAttr(result, astmodulestate_global->values, value) ==
  4034. -1)
  4035. goto failed;
  4036. Py_DECREF(value);
  4037. break;
  4038. case NamedExpr_kind:
  4039. tp = (PyTypeObject *)astmodulestate_global->NamedExpr_type;
  4040. result = PyType_GenericNew(tp, NULL, NULL);
  4041. if (!result) goto failed;
  4042. value = ast2obj_expr(o->v.NamedExpr.target);
  4043. if (!value) goto failed;
  4044. if (PyObject_SetAttr(result, astmodulestate_global->target, value) ==
  4045. -1)
  4046. goto failed;
  4047. Py_DECREF(value);
  4048. value = ast2obj_expr(o->v.NamedExpr.value);
  4049. if (!value) goto failed;
  4050. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4051. goto failed;
  4052. Py_DECREF(value);
  4053. break;
  4054. case BinOp_kind:
  4055. tp = (PyTypeObject *)astmodulestate_global->BinOp_type;
  4056. result = PyType_GenericNew(tp, NULL, NULL);
  4057. if (!result) goto failed;
  4058. value = ast2obj_expr(o->v.BinOp.left);
  4059. if (!value) goto failed;
  4060. if (PyObject_SetAttr(result, astmodulestate_global->left, value) == -1)
  4061. goto failed;
  4062. Py_DECREF(value);
  4063. value = ast2obj_operator(o->v.BinOp.op);
  4064. if (!value) goto failed;
  4065. if (PyObject_SetAttr(result, astmodulestate_global->op, value) == -1)
  4066. goto failed;
  4067. Py_DECREF(value);
  4068. value = ast2obj_expr(o->v.BinOp.right);
  4069. if (!value) goto failed;
  4070. if (PyObject_SetAttr(result, astmodulestate_global->right, value) == -1)
  4071. goto failed;
  4072. Py_DECREF(value);
  4073. break;
  4074. case UnaryOp_kind:
  4075. tp = (PyTypeObject *)astmodulestate_global->UnaryOp_type;
  4076. result = PyType_GenericNew(tp, NULL, NULL);
  4077. if (!result) goto failed;
  4078. value = ast2obj_unaryop(o->v.UnaryOp.op);
  4079. if (!value) goto failed;
  4080. if (PyObject_SetAttr(result, astmodulestate_global->op, value) == -1)
  4081. goto failed;
  4082. Py_DECREF(value);
  4083. value = ast2obj_expr(o->v.UnaryOp.operand);
  4084. if (!value) goto failed;
  4085. if (PyObject_SetAttr(result, astmodulestate_global->operand, value) ==
  4086. -1)
  4087. goto failed;
  4088. Py_DECREF(value);
  4089. break;
  4090. case Lambda_kind:
  4091. tp = (PyTypeObject *)astmodulestate_global->Lambda_type;
  4092. result = PyType_GenericNew(tp, NULL, NULL);
  4093. if (!result) goto failed;
  4094. value = ast2obj_arguments(o->v.Lambda.args);
  4095. if (!value) goto failed;
  4096. if (PyObject_SetAttr(result, astmodulestate_global->args, value) == -1)
  4097. goto failed;
  4098. Py_DECREF(value);
  4099. value = ast2obj_expr(o->v.Lambda.body);
  4100. if (!value) goto failed;
  4101. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  4102. goto failed;
  4103. Py_DECREF(value);
  4104. break;
  4105. case IfExp_kind:
  4106. tp = (PyTypeObject *)astmodulestate_global->IfExp_type;
  4107. result = PyType_GenericNew(tp, NULL, NULL);
  4108. if (!result) goto failed;
  4109. value = ast2obj_expr(o->v.IfExp.test);
  4110. if (!value) goto failed;
  4111. if (PyObject_SetAttr(result, astmodulestate_global->test, value) == -1)
  4112. goto failed;
  4113. Py_DECREF(value);
  4114. value = ast2obj_expr(o->v.IfExp.body);
  4115. if (!value) goto failed;
  4116. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  4117. goto failed;
  4118. Py_DECREF(value);
  4119. value = ast2obj_expr(o->v.IfExp.orelse);
  4120. if (!value) goto failed;
  4121. if (PyObject_SetAttr(result, astmodulestate_global->orelse, value) ==
  4122. -1)
  4123. goto failed;
  4124. Py_DECREF(value);
  4125. break;
  4126. case Dict_kind:
  4127. tp = (PyTypeObject *)astmodulestate_global->Dict_type;
  4128. result = PyType_GenericNew(tp, NULL, NULL);
  4129. if (!result) goto failed;
  4130. value = ast2obj_list(o->v.Dict.keys, ast2obj_expr);
  4131. if (!value) goto failed;
  4132. if (PyObject_SetAttr(result, astmodulestate_global->keys, value) == -1)
  4133. goto failed;
  4134. Py_DECREF(value);
  4135. value = ast2obj_list(o->v.Dict.values, ast2obj_expr);
  4136. if (!value) goto failed;
  4137. if (PyObject_SetAttr(result, astmodulestate_global->values, value) ==
  4138. -1)
  4139. goto failed;
  4140. Py_DECREF(value);
  4141. break;
  4142. case Set_kind:
  4143. tp = (PyTypeObject *)astmodulestate_global->Set_type;
  4144. result = PyType_GenericNew(tp, NULL, NULL);
  4145. if (!result) goto failed;
  4146. value = ast2obj_list(o->v.Set.elts, ast2obj_expr);
  4147. if (!value) goto failed;
  4148. if (PyObject_SetAttr(result, astmodulestate_global->elts, value) == -1)
  4149. goto failed;
  4150. Py_DECREF(value);
  4151. break;
  4152. case ListComp_kind:
  4153. tp = (PyTypeObject *)astmodulestate_global->ListComp_type;
  4154. result = PyType_GenericNew(tp, NULL, NULL);
  4155. if (!result) goto failed;
  4156. value = ast2obj_expr(o->v.ListComp.elt);
  4157. if (!value) goto failed;
  4158. if (PyObject_SetAttr(result, astmodulestate_global->elt, value) == -1)
  4159. goto failed;
  4160. Py_DECREF(value);
  4161. value = ast2obj_list(o->v.ListComp.generators, ast2obj_comprehension);
  4162. if (!value) goto failed;
  4163. if (PyObject_SetAttr(result, astmodulestate_global->generators, value)
  4164. == -1)
  4165. goto failed;
  4166. Py_DECREF(value);
  4167. break;
  4168. case SetComp_kind:
  4169. tp = (PyTypeObject *)astmodulestate_global->SetComp_type;
  4170. result = PyType_GenericNew(tp, NULL, NULL);
  4171. if (!result) goto failed;
  4172. value = ast2obj_expr(o->v.SetComp.elt);
  4173. if (!value) goto failed;
  4174. if (PyObject_SetAttr(result, astmodulestate_global->elt, value) == -1)
  4175. goto failed;
  4176. Py_DECREF(value);
  4177. value = ast2obj_list(o->v.SetComp.generators, ast2obj_comprehension);
  4178. if (!value) goto failed;
  4179. if (PyObject_SetAttr(result, astmodulestate_global->generators, value)
  4180. == -1)
  4181. goto failed;
  4182. Py_DECREF(value);
  4183. break;
  4184. case DictComp_kind:
  4185. tp = (PyTypeObject *)astmodulestate_global->DictComp_type;
  4186. result = PyType_GenericNew(tp, NULL, NULL);
  4187. if (!result) goto failed;
  4188. value = ast2obj_expr(o->v.DictComp.key);
  4189. if (!value) goto failed;
  4190. if (PyObject_SetAttr(result, astmodulestate_global->key, value) == -1)
  4191. goto failed;
  4192. Py_DECREF(value);
  4193. value = ast2obj_expr(o->v.DictComp.value);
  4194. if (!value) goto failed;
  4195. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4196. goto failed;
  4197. Py_DECREF(value);
  4198. value = ast2obj_list(o->v.DictComp.generators, ast2obj_comprehension);
  4199. if (!value) goto failed;
  4200. if (PyObject_SetAttr(result, astmodulestate_global->generators, value)
  4201. == -1)
  4202. goto failed;
  4203. Py_DECREF(value);
  4204. break;
  4205. case GeneratorExp_kind:
  4206. tp = (PyTypeObject *)astmodulestate_global->GeneratorExp_type;
  4207. result = PyType_GenericNew(tp, NULL, NULL);
  4208. if (!result) goto failed;
  4209. value = ast2obj_expr(o->v.GeneratorExp.elt);
  4210. if (!value) goto failed;
  4211. if (PyObject_SetAttr(result, astmodulestate_global->elt, value) == -1)
  4212. goto failed;
  4213. Py_DECREF(value);
  4214. value = ast2obj_list(o->v.GeneratorExp.generators,
  4215. ast2obj_comprehension);
  4216. if (!value) goto failed;
  4217. if (PyObject_SetAttr(result, astmodulestate_global->generators, value)
  4218. == -1)
  4219. goto failed;
  4220. Py_DECREF(value);
  4221. break;
  4222. case Await_kind:
  4223. tp = (PyTypeObject *)astmodulestate_global->Await_type;
  4224. result = PyType_GenericNew(tp, NULL, NULL);
  4225. if (!result) goto failed;
  4226. value = ast2obj_expr(o->v.Await.value);
  4227. if (!value) goto failed;
  4228. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4229. goto failed;
  4230. Py_DECREF(value);
  4231. break;
  4232. case Yield_kind:
  4233. tp = (PyTypeObject *)astmodulestate_global->Yield_type;
  4234. result = PyType_GenericNew(tp, NULL, NULL);
  4235. if (!result) goto failed;
  4236. value = ast2obj_expr(o->v.Yield.value);
  4237. if (!value) goto failed;
  4238. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4239. goto failed;
  4240. Py_DECREF(value);
  4241. break;
  4242. case YieldFrom_kind:
  4243. tp = (PyTypeObject *)astmodulestate_global->YieldFrom_type;
  4244. result = PyType_GenericNew(tp, NULL, NULL);
  4245. if (!result) goto failed;
  4246. value = ast2obj_expr(o->v.YieldFrom.value);
  4247. if (!value) goto failed;
  4248. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4249. goto failed;
  4250. Py_DECREF(value);
  4251. break;
  4252. case Compare_kind:
  4253. tp = (PyTypeObject *)astmodulestate_global->Compare_type;
  4254. result = PyType_GenericNew(tp, NULL, NULL);
  4255. if (!result) goto failed;
  4256. value = ast2obj_expr(o->v.Compare.left);
  4257. if (!value) goto failed;
  4258. if (PyObject_SetAttr(result, astmodulestate_global->left, value) == -1)
  4259. goto failed;
  4260. Py_DECREF(value);
  4261. {
  4262. Py_ssize_t i, n = asdl_seq_LEN(o->v.Compare.ops);
  4263. value = PyList_New(n);
  4264. if (!value) goto failed;
  4265. for(i = 0; i < n; i++)
  4266. PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i)));
  4267. }
  4268. if (!value) goto failed;
  4269. if (PyObject_SetAttr(result, astmodulestate_global->ops, value) == -1)
  4270. goto failed;
  4271. Py_DECREF(value);
  4272. value = ast2obj_list(o->v.Compare.comparators, ast2obj_expr);
  4273. if (!value) goto failed;
  4274. if (PyObject_SetAttr(result, astmodulestate_global->comparators, value)
  4275. == -1)
  4276. goto failed;
  4277. Py_DECREF(value);
  4278. break;
  4279. case Call_kind:
  4280. tp = (PyTypeObject *)astmodulestate_global->Call_type;
  4281. result = PyType_GenericNew(tp, NULL, NULL);
  4282. if (!result) goto failed;
  4283. value = ast2obj_expr(o->v.Call.func);
  4284. if (!value) goto failed;
  4285. if (PyObject_SetAttr(result, astmodulestate_global->func, value) == -1)
  4286. goto failed;
  4287. Py_DECREF(value);
  4288. value = ast2obj_list(o->v.Call.args, ast2obj_expr);
  4289. if (!value) goto failed;
  4290. if (PyObject_SetAttr(result, astmodulestate_global->args, value) == -1)
  4291. goto failed;
  4292. Py_DECREF(value);
  4293. value = ast2obj_list(o->v.Call.keywords, ast2obj_keyword);
  4294. if (!value) goto failed;
  4295. if (PyObject_SetAttr(result, astmodulestate_global->keywords, value) ==
  4296. -1)
  4297. goto failed;
  4298. Py_DECREF(value);
  4299. break;
  4300. case FormattedValue_kind:
  4301. tp = (PyTypeObject *)astmodulestate_global->FormattedValue_type;
  4302. result = PyType_GenericNew(tp, NULL, NULL);
  4303. if (!result) goto failed;
  4304. value = ast2obj_expr(o->v.FormattedValue.value);
  4305. if (!value) goto failed;
  4306. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4307. goto failed;
  4308. Py_DECREF(value);
  4309. value = ast2obj_int(o->v.FormattedValue.conversion);
  4310. if (!value) goto failed;
  4311. if (PyObject_SetAttr(result, astmodulestate_global->conversion, value)
  4312. == -1)
  4313. goto failed;
  4314. Py_DECREF(value);
  4315. value = ast2obj_expr(o->v.FormattedValue.format_spec);
  4316. if (!value) goto failed;
  4317. if (PyObject_SetAttr(result, astmodulestate_global->format_spec, value)
  4318. == -1)
  4319. goto failed;
  4320. Py_DECREF(value);
  4321. break;
  4322. case JoinedStr_kind:
  4323. tp = (PyTypeObject *)astmodulestate_global->JoinedStr_type;
  4324. result = PyType_GenericNew(tp, NULL, NULL);
  4325. if (!result) goto failed;
  4326. value = ast2obj_list(o->v.JoinedStr.values, ast2obj_expr);
  4327. if (!value) goto failed;
  4328. if (PyObject_SetAttr(result, astmodulestate_global->values, value) ==
  4329. -1)
  4330. goto failed;
  4331. Py_DECREF(value);
  4332. break;
  4333. case Constant_kind:
  4334. tp = (PyTypeObject *)astmodulestate_global->Constant_type;
  4335. result = PyType_GenericNew(tp, NULL, NULL);
  4336. if (!result) goto failed;
  4337. value = ast2obj_constant(o->v.Constant.value);
  4338. if (!value) goto failed;
  4339. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4340. goto failed;
  4341. Py_DECREF(value);
  4342. value = ast2obj_string(o->v.Constant.kind);
  4343. if (!value) goto failed;
  4344. if (PyObject_SetAttr(result, astmodulestate_global->kind, value) == -1)
  4345. goto failed;
  4346. Py_DECREF(value);
  4347. break;
  4348. case Attribute_kind:
  4349. tp = (PyTypeObject *)astmodulestate_global->Attribute_type;
  4350. result = PyType_GenericNew(tp, NULL, NULL);
  4351. if (!result) goto failed;
  4352. value = ast2obj_expr(o->v.Attribute.value);
  4353. if (!value) goto failed;
  4354. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4355. goto failed;
  4356. Py_DECREF(value);
  4357. value = ast2obj_identifier(o->v.Attribute.attr);
  4358. if (!value) goto failed;
  4359. if (PyObject_SetAttr(result, astmodulestate_global->attr, value) == -1)
  4360. goto failed;
  4361. Py_DECREF(value);
  4362. value = ast2obj_expr_context(o->v.Attribute.ctx);
  4363. if (!value) goto failed;
  4364. if (PyObject_SetAttr(result, astmodulestate_global->ctx, value) == -1)
  4365. goto failed;
  4366. Py_DECREF(value);
  4367. break;
  4368. case Subscript_kind:
  4369. tp = (PyTypeObject *)astmodulestate_global->Subscript_type;
  4370. result = PyType_GenericNew(tp, NULL, NULL);
  4371. if (!result) goto failed;
  4372. value = ast2obj_expr(o->v.Subscript.value);
  4373. if (!value) goto failed;
  4374. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4375. goto failed;
  4376. Py_DECREF(value);
  4377. value = ast2obj_expr(o->v.Subscript.slice);
  4378. if (!value) goto failed;
  4379. if (PyObject_SetAttr(result, astmodulestate_global->slice, value) == -1)
  4380. goto failed;
  4381. Py_DECREF(value);
  4382. value = ast2obj_expr_context(o->v.Subscript.ctx);
  4383. if (!value) goto failed;
  4384. if (PyObject_SetAttr(result, astmodulestate_global->ctx, value) == -1)
  4385. goto failed;
  4386. Py_DECREF(value);
  4387. break;
  4388. case Starred_kind:
  4389. tp = (PyTypeObject *)astmodulestate_global->Starred_type;
  4390. result = PyType_GenericNew(tp, NULL, NULL);
  4391. if (!result) goto failed;
  4392. value = ast2obj_expr(o->v.Starred.value);
  4393. if (!value) goto failed;
  4394. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4395. goto failed;
  4396. Py_DECREF(value);
  4397. value = ast2obj_expr_context(o->v.Starred.ctx);
  4398. if (!value) goto failed;
  4399. if (PyObject_SetAttr(result, astmodulestate_global->ctx, value) == -1)
  4400. goto failed;
  4401. Py_DECREF(value);
  4402. break;
  4403. case Name_kind:
  4404. tp = (PyTypeObject *)astmodulestate_global->Name_type;
  4405. result = PyType_GenericNew(tp, NULL, NULL);
  4406. if (!result) goto failed;
  4407. value = ast2obj_identifier(o->v.Name.id);
  4408. if (!value) goto failed;
  4409. if (PyObject_SetAttr(result, astmodulestate_global->id, value) == -1)
  4410. goto failed;
  4411. Py_DECREF(value);
  4412. value = ast2obj_expr_context(o->v.Name.ctx);
  4413. if (!value) goto failed;
  4414. if (PyObject_SetAttr(result, astmodulestate_global->ctx, value) == -1)
  4415. goto failed;
  4416. Py_DECREF(value);
  4417. break;
  4418. case List_kind:
  4419. tp = (PyTypeObject *)astmodulestate_global->List_type;
  4420. result = PyType_GenericNew(tp, NULL, NULL);
  4421. if (!result) goto failed;
  4422. value = ast2obj_list(o->v.List.elts, ast2obj_expr);
  4423. if (!value) goto failed;
  4424. if (PyObject_SetAttr(result, astmodulestate_global->elts, value) == -1)
  4425. goto failed;
  4426. Py_DECREF(value);
  4427. value = ast2obj_expr_context(o->v.List.ctx);
  4428. if (!value) goto failed;
  4429. if (PyObject_SetAttr(result, astmodulestate_global->ctx, value) == -1)
  4430. goto failed;
  4431. Py_DECREF(value);
  4432. break;
  4433. case Tuple_kind:
  4434. tp = (PyTypeObject *)astmodulestate_global->Tuple_type;
  4435. result = PyType_GenericNew(tp, NULL, NULL);
  4436. if (!result) goto failed;
  4437. value = ast2obj_list(o->v.Tuple.elts, ast2obj_expr);
  4438. if (!value) goto failed;
  4439. if (PyObject_SetAttr(result, astmodulestate_global->elts, value) == -1)
  4440. goto failed;
  4441. Py_DECREF(value);
  4442. value = ast2obj_expr_context(o->v.Tuple.ctx);
  4443. if (!value) goto failed;
  4444. if (PyObject_SetAttr(result, astmodulestate_global->ctx, value) == -1)
  4445. goto failed;
  4446. Py_DECREF(value);
  4447. break;
  4448. case Slice_kind:
  4449. tp = (PyTypeObject *)astmodulestate_global->Slice_type;
  4450. result = PyType_GenericNew(tp, NULL, NULL);
  4451. if (!result) goto failed;
  4452. value = ast2obj_expr(o->v.Slice.lower);
  4453. if (!value) goto failed;
  4454. if (PyObject_SetAttr(result, astmodulestate_global->lower, value) == -1)
  4455. goto failed;
  4456. Py_DECREF(value);
  4457. value = ast2obj_expr(o->v.Slice.upper);
  4458. if (!value) goto failed;
  4459. if (PyObject_SetAttr(result, astmodulestate_global->upper, value) == -1)
  4460. goto failed;
  4461. Py_DECREF(value);
  4462. value = ast2obj_expr(o->v.Slice.step);
  4463. if (!value) goto failed;
  4464. if (PyObject_SetAttr(result, astmodulestate_global->step, value) == -1)
  4465. goto failed;
  4466. Py_DECREF(value);
  4467. break;
  4468. }
  4469. value = ast2obj_int(o->lineno);
  4470. if (!value) goto failed;
  4471. if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) < 0)
  4472. goto failed;
  4473. Py_DECREF(value);
  4474. value = ast2obj_int(o->col_offset);
  4475. if (!value) goto failed;
  4476. if (PyObject_SetAttr(result, astmodulestate_global->col_offset, value) < 0)
  4477. goto failed;
  4478. Py_DECREF(value);
  4479. value = ast2obj_int(o->end_lineno);
  4480. if (!value) goto failed;
  4481. if (PyObject_SetAttr(result, astmodulestate_global->end_lineno, value) < 0)
  4482. goto failed;
  4483. Py_DECREF(value);
  4484. value = ast2obj_int(o->end_col_offset);
  4485. if (!value) goto failed;
  4486. if (PyObject_SetAttr(result, astmodulestate_global->end_col_offset, value)
  4487. < 0)
  4488. goto failed;
  4489. Py_DECREF(value);
  4490. return result;
  4491. failed:
  4492. Py_XDECREF(value);
  4493. Py_XDECREF(result);
  4494. return NULL;
  4495. }
  4496. PyObject* ast2obj_expr_context(expr_context_ty o)
  4497. {
  4498. switch(o) {
  4499. case Load:
  4500. Py_INCREF(astmodulestate_global->Load_singleton);
  4501. return astmodulestate_global->Load_singleton;
  4502. case Store:
  4503. Py_INCREF(astmodulestate_global->Store_singleton);
  4504. return astmodulestate_global->Store_singleton;
  4505. case Del:
  4506. Py_INCREF(astmodulestate_global->Del_singleton);
  4507. return astmodulestate_global->Del_singleton;
  4508. }
  4509. Py_UNREACHABLE();
  4510. }
  4511. PyObject* ast2obj_boolop(boolop_ty o)
  4512. {
  4513. switch(o) {
  4514. case And:
  4515. Py_INCREF(astmodulestate_global->And_singleton);
  4516. return astmodulestate_global->And_singleton;
  4517. case Or:
  4518. Py_INCREF(astmodulestate_global->Or_singleton);
  4519. return astmodulestate_global->Or_singleton;
  4520. }
  4521. Py_UNREACHABLE();
  4522. }
  4523. PyObject* ast2obj_operator(operator_ty o)
  4524. {
  4525. switch(o) {
  4526. case Add:
  4527. Py_INCREF(astmodulestate_global->Add_singleton);
  4528. return astmodulestate_global->Add_singleton;
  4529. case Sub:
  4530. Py_INCREF(astmodulestate_global->Sub_singleton);
  4531. return astmodulestate_global->Sub_singleton;
  4532. case Mult:
  4533. Py_INCREF(astmodulestate_global->Mult_singleton);
  4534. return astmodulestate_global->Mult_singleton;
  4535. case MatMult:
  4536. Py_INCREF(astmodulestate_global->MatMult_singleton);
  4537. return astmodulestate_global->MatMult_singleton;
  4538. case Div:
  4539. Py_INCREF(astmodulestate_global->Div_singleton);
  4540. return astmodulestate_global->Div_singleton;
  4541. case Mod:
  4542. Py_INCREF(astmodulestate_global->Mod_singleton);
  4543. return astmodulestate_global->Mod_singleton;
  4544. case Pow:
  4545. Py_INCREF(astmodulestate_global->Pow_singleton);
  4546. return astmodulestate_global->Pow_singleton;
  4547. case LShift:
  4548. Py_INCREF(astmodulestate_global->LShift_singleton);
  4549. return astmodulestate_global->LShift_singleton;
  4550. case RShift:
  4551. Py_INCREF(astmodulestate_global->RShift_singleton);
  4552. return astmodulestate_global->RShift_singleton;
  4553. case BitOr:
  4554. Py_INCREF(astmodulestate_global->BitOr_singleton);
  4555. return astmodulestate_global->BitOr_singleton;
  4556. case BitXor:
  4557. Py_INCREF(astmodulestate_global->BitXor_singleton);
  4558. return astmodulestate_global->BitXor_singleton;
  4559. case BitAnd:
  4560. Py_INCREF(astmodulestate_global->BitAnd_singleton);
  4561. return astmodulestate_global->BitAnd_singleton;
  4562. case FloorDiv:
  4563. Py_INCREF(astmodulestate_global->FloorDiv_singleton);
  4564. return astmodulestate_global->FloorDiv_singleton;
  4565. }
  4566. Py_UNREACHABLE();
  4567. }
  4568. PyObject* ast2obj_unaryop(unaryop_ty o)
  4569. {
  4570. switch(o) {
  4571. case Invert:
  4572. Py_INCREF(astmodulestate_global->Invert_singleton);
  4573. return astmodulestate_global->Invert_singleton;
  4574. case Not:
  4575. Py_INCREF(astmodulestate_global->Not_singleton);
  4576. return astmodulestate_global->Not_singleton;
  4577. case UAdd:
  4578. Py_INCREF(astmodulestate_global->UAdd_singleton);
  4579. return astmodulestate_global->UAdd_singleton;
  4580. case USub:
  4581. Py_INCREF(astmodulestate_global->USub_singleton);
  4582. return astmodulestate_global->USub_singleton;
  4583. }
  4584. Py_UNREACHABLE();
  4585. }
  4586. PyObject* ast2obj_cmpop(cmpop_ty o)
  4587. {
  4588. switch(o) {
  4589. case Eq:
  4590. Py_INCREF(astmodulestate_global->Eq_singleton);
  4591. return astmodulestate_global->Eq_singleton;
  4592. case NotEq:
  4593. Py_INCREF(astmodulestate_global->NotEq_singleton);
  4594. return astmodulestate_global->NotEq_singleton;
  4595. case Lt:
  4596. Py_INCREF(astmodulestate_global->Lt_singleton);
  4597. return astmodulestate_global->Lt_singleton;
  4598. case LtE:
  4599. Py_INCREF(astmodulestate_global->LtE_singleton);
  4600. return astmodulestate_global->LtE_singleton;
  4601. case Gt:
  4602. Py_INCREF(astmodulestate_global->Gt_singleton);
  4603. return astmodulestate_global->Gt_singleton;
  4604. case GtE:
  4605. Py_INCREF(astmodulestate_global->GtE_singleton);
  4606. return astmodulestate_global->GtE_singleton;
  4607. case Is:
  4608. Py_INCREF(astmodulestate_global->Is_singleton);
  4609. return astmodulestate_global->Is_singleton;
  4610. case IsNot:
  4611. Py_INCREF(astmodulestate_global->IsNot_singleton);
  4612. return astmodulestate_global->IsNot_singleton;
  4613. case In:
  4614. Py_INCREF(astmodulestate_global->In_singleton);
  4615. return astmodulestate_global->In_singleton;
  4616. case NotIn:
  4617. Py_INCREF(astmodulestate_global->NotIn_singleton);
  4618. return astmodulestate_global->NotIn_singleton;
  4619. }
  4620. Py_UNREACHABLE();
  4621. }
  4622. PyObject*
  4623. ast2obj_comprehension(void* _o)
  4624. {
  4625. comprehension_ty o = (comprehension_ty)_o;
  4626. PyObject *result = NULL, *value = NULL;
  4627. PyTypeObject *tp;
  4628. if (!o) {
  4629. Py_RETURN_NONE;
  4630. }
  4631. tp = (PyTypeObject *)astmodulestate_global->comprehension_type;
  4632. result = PyType_GenericNew(tp, NULL, NULL);
  4633. if (!result) return NULL;
  4634. value = ast2obj_expr(o->target);
  4635. if (!value) goto failed;
  4636. if (PyObject_SetAttr(result, astmodulestate_global->target, value) == -1)
  4637. goto failed;
  4638. Py_DECREF(value);
  4639. value = ast2obj_expr(o->iter);
  4640. if (!value) goto failed;
  4641. if (PyObject_SetAttr(result, astmodulestate_global->iter, value) == -1)
  4642. goto failed;
  4643. Py_DECREF(value);
  4644. value = ast2obj_list(o->ifs, ast2obj_expr);
  4645. if (!value) goto failed;
  4646. if (PyObject_SetAttr(result, astmodulestate_global->ifs, value) == -1)
  4647. goto failed;
  4648. Py_DECREF(value);
  4649. value = ast2obj_int(o->is_async);
  4650. if (!value) goto failed;
  4651. if (PyObject_SetAttr(result, astmodulestate_global->is_async, value) == -1)
  4652. goto failed;
  4653. Py_DECREF(value);
  4654. return result;
  4655. failed:
  4656. Py_XDECREF(value);
  4657. Py_XDECREF(result);
  4658. return NULL;
  4659. }
  4660. PyObject*
  4661. ast2obj_excepthandler(void* _o)
  4662. {
  4663. excepthandler_ty o = (excepthandler_ty)_o;
  4664. PyObject *result = NULL, *value = NULL;
  4665. PyTypeObject *tp;
  4666. if (!o) {
  4667. Py_RETURN_NONE;
  4668. }
  4669. switch (o->kind) {
  4670. case ExceptHandler_kind:
  4671. tp = (PyTypeObject *)astmodulestate_global->ExceptHandler_type;
  4672. result = PyType_GenericNew(tp, NULL, NULL);
  4673. if (!result) goto failed;
  4674. value = ast2obj_expr(o->v.ExceptHandler.type);
  4675. if (!value) goto failed;
  4676. if (PyObject_SetAttr(result, astmodulestate_global->type, value) == -1)
  4677. goto failed;
  4678. Py_DECREF(value);
  4679. value = ast2obj_identifier(o->v.ExceptHandler.name);
  4680. if (!value) goto failed;
  4681. if (PyObject_SetAttr(result, astmodulestate_global->name, value) == -1)
  4682. goto failed;
  4683. Py_DECREF(value);
  4684. value = ast2obj_list(o->v.ExceptHandler.body, ast2obj_stmt);
  4685. if (!value) goto failed;
  4686. if (PyObject_SetAttr(result, astmodulestate_global->body, value) == -1)
  4687. goto failed;
  4688. Py_DECREF(value);
  4689. break;
  4690. }
  4691. value = ast2obj_int(o->lineno);
  4692. if (!value) goto failed;
  4693. if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) < 0)
  4694. goto failed;
  4695. Py_DECREF(value);
  4696. value = ast2obj_int(o->col_offset);
  4697. if (!value) goto failed;
  4698. if (PyObject_SetAttr(result, astmodulestate_global->col_offset, value) < 0)
  4699. goto failed;
  4700. Py_DECREF(value);
  4701. value = ast2obj_int(o->end_lineno);
  4702. if (!value) goto failed;
  4703. if (PyObject_SetAttr(result, astmodulestate_global->end_lineno, value) < 0)
  4704. goto failed;
  4705. Py_DECREF(value);
  4706. value = ast2obj_int(o->end_col_offset);
  4707. if (!value) goto failed;
  4708. if (PyObject_SetAttr(result, astmodulestate_global->end_col_offset, value)
  4709. < 0)
  4710. goto failed;
  4711. Py_DECREF(value);
  4712. return result;
  4713. failed:
  4714. Py_XDECREF(value);
  4715. Py_XDECREF(result);
  4716. return NULL;
  4717. }
  4718. PyObject*
  4719. ast2obj_arguments(void* _o)
  4720. {
  4721. arguments_ty o = (arguments_ty)_o;
  4722. PyObject *result = NULL, *value = NULL;
  4723. PyTypeObject *tp;
  4724. if (!o) {
  4725. Py_RETURN_NONE;
  4726. }
  4727. tp = (PyTypeObject *)astmodulestate_global->arguments_type;
  4728. result = PyType_GenericNew(tp, NULL, NULL);
  4729. if (!result) return NULL;
  4730. value = ast2obj_list(o->posonlyargs, ast2obj_arg);
  4731. if (!value) goto failed;
  4732. if (PyObject_SetAttr(result, astmodulestate_global->posonlyargs, value) ==
  4733. -1)
  4734. goto failed;
  4735. Py_DECREF(value);
  4736. value = ast2obj_list(o->args, ast2obj_arg);
  4737. if (!value) goto failed;
  4738. if (PyObject_SetAttr(result, astmodulestate_global->args, value) == -1)
  4739. goto failed;
  4740. Py_DECREF(value);
  4741. value = ast2obj_arg(o->vararg);
  4742. if (!value) goto failed;
  4743. if (PyObject_SetAttr(result, astmodulestate_global->vararg, value) == -1)
  4744. goto failed;
  4745. Py_DECREF(value);
  4746. value = ast2obj_list(o->kwonlyargs, ast2obj_arg);
  4747. if (!value) goto failed;
  4748. if (PyObject_SetAttr(result, astmodulestate_global->kwonlyargs, value) ==
  4749. -1)
  4750. goto failed;
  4751. Py_DECREF(value);
  4752. value = ast2obj_list(o->kw_defaults, ast2obj_expr);
  4753. if (!value) goto failed;
  4754. if (PyObject_SetAttr(result, astmodulestate_global->kw_defaults, value) ==
  4755. -1)
  4756. goto failed;
  4757. Py_DECREF(value);
  4758. value = ast2obj_arg(o->kwarg);
  4759. if (!value) goto failed;
  4760. if (PyObject_SetAttr(result, astmodulestate_global->kwarg, value) == -1)
  4761. goto failed;
  4762. Py_DECREF(value);
  4763. value = ast2obj_list(o->defaults, ast2obj_expr);
  4764. if (!value) goto failed;
  4765. if (PyObject_SetAttr(result, astmodulestate_global->defaults, value) == -1)
  4766. goto failed;
  4767. Py_DECREF(value);
  4768. return result;
  4769. failed:
  4770. Py_XDECREF(value);
  4771. Py_XDECREF(result);
  4772. return NULL;
  4773. }
  4774. PyObject*
  4775. ast2obj_arg(void* _o)
  4776. {
  4777. arg_ty o = (arg_ty)_o;
  4778. PyObject *result = NULL, *value = NULL;
  4779. PyTypeObject *tp;
  4780. if (!o) {
  4781. Py_RETURN_NONE;
  4782. }
  4783. tp = (PyTypeObject *)astmodulestate_global->arg_type;
  4784. result = PyType_GenericNew(tp, NULL, NULL);
  4785. if (!result) return NULL;
  4786. value = ast2obj_identifier(o->arg);
  4787. if (!value) goto failed;
  4788. if (PyObject_SetAttr(result, astmodulestate_global->arg, value) == -1)
  4789. goto failed;
  4790. Py_DECREF(value);
  4791. value = ast2obj_expr(o->annotation);
  4792. if (!value) goto failed;
  4793. if (PyObject_SetAttr(result, astmodulestate_global->annotation, value) ==
  4794. -1)
  4795. goto failed;
  4796. Py_DECREF(value);
  4797. value = ast2obj_string(o->type_comment);
  4798. if (!value) goto failed;
  4799. if (PyObject_SetAttr(result, astmodulestate_global->type_comment, value) ==
  4800. -1)
  4801. goto failed;
  4802. Py_DECREF(value);
  4803. value = ast2obj_int(o->lineno);
  4804. if (!value) goto failed;
  4805. if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) < 0)
  4806. goto failed;
  4807. Py_DECREF(value);
  4808. value = ast2obj_int(o->col_offset);
  4809. if (!value) goto failed;
  4810. if (PyObject_SetAttr(result, astmodulestate_global->col_offset, value) < 0)
  4811. goto failed;
  4812. Py_DECREF(value);
  4813. value = ast2obj_int(o->end_lineno);
  4814. if (!value) goto failed;
  4815. if (PyObject_SetAttr(result, astmodulestate_global->end_lineno, value) < 0)
  4816. goto failed;
  4817. Py_DECREF(value);
  4818. value = ast2obj_int(o->end_col_offset);
  4819. if (!value) goto failed;
  4820. if (PyObject_SetAttr(result, astmodulestate_global->end_col_offset, value)
  4821. < 0)
  4822. goto failed;
  4823. Py_DECREF(value);
  4824. return result;
  4825. failed:
  4826. Py_XDECREF(value);
  4827. Py_XDECREF(result);
  4828. return NULL;
  4829. }
  4830. PyObject*
  4831. ast2obj_keyword(void* _o)
  4832. {
  4833. keyword_ty o = (keyword_ty)_o;
  4834. PyObject *result = NULL, *value = NULL;
  4835. PyTypeObject *tp;
  4836. if (!o) {
  4837. Py_RETURN_NONE;
  4838. }
  4839. tp = (PyTypeObject *)astmodulestate_global->keyword_type;
  4840. result = PyType_GenericNew(tp, NULL, NULL);
  4841. if (!result) return NULL;
  4842. value = ast2obj_identifier(o->arg);
  4843. if (!value) goto failed;
  4844. if (PyObject_SetAttr(result, astmodulestate_global->arg, value) == -1)
  4845. goto failed;
  4846. Py_DECREF(value);
  4847. value = ast2obj_expr(o->value);
  4848. if (!value) goto failed;
  4849. if (PyObject_SetAttr(result, astmodulestate_global->value, value) == -1)
  4850. goto failed;
  4851. Py_DECREF(value);
  4852. value = ast2obj_int(o->lineno);
  4853. if (!value) goto failed;
  4854. if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) < 0)
  4855. goto failed;
  4856. Py_DECREF(value);
  4857. value = ast2obj_int(o->col_offset);
  4858. if (!value) goto failed;
  4859. if (PyObject_SetAttr(result, astmodulestate_global->col_offset, value) < 0)
  4860. goto failed;
  4861. Py_DECREF(value);
  4862. value = ast2obj_int(o->end_lineno);
  4863. if (!value) goto failed;
  4864. if (PyObject_SetAttr(result, astmodulestate_global->end_lineno, value) < 0)
  4865. goto failed;
  4866. Py_DECREF(value);
  4867. value = ast2obj_int(o->end_col_offset);
  4868. if (!value) goto failed;
  4869. if (PyObject_SetAttr(result, astmodulestate_global->end_col_offset, value)
  4870. < 0)
  4871. goto failed;
  4872. Py_DECREF(value);
  4873. return result;
  4874. failed:
  4875. Py_XDECREF(value);
  4876. Py_XDECREF(result);
  4877. return NULL;
  4878. }
  4879. PyObject*
  4880. ast2obj_alias(void* _o)
  4881. {
  4882. alias_ty o = (alias_ty)_o;
  4883. PyObject *result = NULL, *value = NULL;
  4884. PyTypeObject *tp;
  4885. if (!o) {
  4886. Py_RETURN_NONE;
  4887. }
  4888. tp = (PyTypeObject *)astmodulestate_global->alias_type;
  4889. result = PyType_GenericNew(tp, NULL, NULL);
  4890. if (!result) return NULL;
  4891. value = ast2obj_identifier(o->name);
  4892. if (!value) goto failed;
  4893. if (PyObject_SetAttr(result, astmodulestate_global->name, value) == -1)
  4894. goto failed;
  4895. Py_DECREF(value);
  4896. value = ast2obj_identifier(o->asname);
  4897. if (!value) goto failed;
  4898. if (PyObject_SetAttr(result, astmodulestate_global->asname, value) == -1)
  4899. goto failed;
  4900. Py_DECREF(value);
  4901. return result;
  4902. failed:
  4903. Py_XDECREF(value);
  4904. Py_XDECREF(result);
  4905. return NULL;
  4906. }
  4907. PyObject*
  4908. ast2obj_withitem(void* _o)
  4909. {
  4910. withitem_ty o = (withitem_ty)_o;
  4911. PyObject *result = NULL, *value = NULL;
  4912. PyTypeObject *tp;
  4913. if (!o) {
  4914. Py_RETURN_NONE;
  4915. }
  4916. tp = (PyTypeObject *)astmodulestate_global->withitem_type;
  4917. result = PyType_GenericNew(tp, NULL, NULL);
  4918. if (!result) return NULL;
  4919. value = ast2obj_expr(o->context_expr);
  4920. if (!value) goto failed;
  4921. if (PyObject_SetAttr(result, astmodulestate_global->context_expr, value) ==
  4922. -1)
  4923. goto failed;
  4924. Py_DECREF(value);
  4925. value = ast2obj_expr(o->optional_vars);
  4926. if (!value) goto failed;
  4927. if (PyObject_SetAttr(result, astmodulestate_global->optional_vars, value)
  4928. == -1)
  4929. goto failed;
  4930. Py_DECREF(value);
  4931. return result;
  4932. failed:
  4933. Py_XDECREF(value);
  4934. Py_XDECREF(result);
  4935. return NULL;
  4936. }
  4937. PyObject*
  4938. ast2obj_type_ignore(void* _o)
  4939. {
  4940. type_ignore_ty o = (type_ignore_ty)_o;
  4941. PyObject *result = NULL, *value = NULL;
  4942. PyTypeObject *tp;
  4943. if (!o) {
  4944. Py_RETURN_NONE;
  4945. }
  4946. switch (o->kind) {
  4947. case TypeIgnore_kind:
  4948. tp = (PyTypeObject *)astmodulestate_global->TypeIgnore_type;
  4949. result = PyType_GenericNew(tp, NULL, NULL);
  4950. if (!result) goto failed;
  4951. value = ast2obj_int(o->v.TypeIgnore.lineno);
  4952. if (!value) goto failed;
  4953. if (PyObject_SetAttr(result, astmodulestate_global->lineno, value) ==
  4954. -1)
  4955. goto failed;
  4956. Py_DECREF(value);
  4957. value = ast2obj_string(o->v.TypeIgnore.tag);
  4958. if (!value) goto failed;
  4959. if (PyObject_SetAttr(result, astmodulestate_global->tag, value) == -1)
  4960. goto failed;
  4961. Py_DECREF(value);
  4962. break;
  4963. }
  4964. return result;
  4965. failed:
  4966. Py_XDECREF(value);
  4967. Py_XDECREF(result);
  4968. return NULL;
  4969. }
  4970. int
  4971. obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
  4972. {
  4973. int isinstance;
  4974. PyObject *tmp = NULL;
  4975. PyObject *tp;
  4976. if (obj == Py_None) {
  4977. *out = NULL;
  4978. return 0;
  4979. }
  4980. tp = astmodulestate_global->Module_type;
  4981. isinstance = PyObject_IsInstance(obj, tp);
  4982. if (isinstance == -1) {
  4983. return 1;
  4984. }
  4985. if (isinstance) {
  4986. asdl_seq* body;
  4987. asdl_seq* type_ignores;
  4988. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  4989. return 1;
  4990. }
  4991. if (tmp == NULL) {
  4992. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Module");
  4993. return 1;
  4994. }
  4995. else {
  4996. int res;
  4997. Py_ssize_t len;
  4998. Py_ssize_t i;
  4999. if (!PyList_Check(tmp)) {
  5000. PyErr_Format(PyExc_TypeError, "Module field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5001. goto failed;
  5002. }
  5003. len = PyList_GET_SIZE(tmp);
  5004. body = _Py_asdl_seq_new(len, arena);
  5005. if (body == NULL) goto failed;
  5006. for (i = 0; i < len; i++) {
  5007. stmt_ty val;
  5008. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5009. Py_INCREF(tmp2);
  5010. res = obj2ast_stmt(tmp2, &val, arena);
  5011. Py_DECREF(tmp2);
  5012. if (res != 0) goto failed;
  5013. if (len != PyList_GET_SIZE(tmp)) {
  5014. PyErr_SetString(PyExc_RuntimeError, "Module field \"body\" changed size during iteration");
  5015. goto failed;
  5016. }
  5017. asdl_seq_SET(body, i, val);
  5018. }
  5019. Py_CLEAR(tmp);
  5020. }
  5021. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_ignores,
  5022. &tmp) < 0) {
  5023. return 1;
  5024. }
  5025. if (tmp == NULL) {
  5026. PyErr_SetString(PyExc_TypeError, "required field \"type_ignores\" missing from Module");
  5027. return 1;
  5028. }
  5029. else {
  5030. int res;
  5031. Py_ssize_t len;
  5032. Py_ssize_t i;
  5033. if (!PyList_Check(tmp)) {
  5034. PyErr_Format(PyExc_TypeError, "Module field \"type_ignores\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5035. goto failed;
  5036. }
  5037. len = PyList_GET_SIZE(tmp);
  5038. type_ignores = _Py_asdl_seq_new(len, arena);
  5039. if (type_ignores == NULL) goto failed;
  5040. for (i = 0; i < len; i++) {
  5041. type_ignore_ty val;
  5042. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5043. Py_INCREF(tmp2);
  5044. res = obj2ast_type_ignore(tmp2, &val, arena);
  5045. Py_DECREF(tmp2);
  5046. if (res != 0) goto failed;
  5047. if (len != PyList_GET_SIZE(tmp)) {
  5048. PyErr_SetString(PyExc_RuntimeError, "Module field \"type_ignores\" changed size during iteration");
  5049. goto failed;
  5050. }
  5051. asdl_seq_SET(type_ignores, i, val);
  5052. }
  5053. Py_CLEAR(tmp);
  5054. }
  5055. *out = Module(body, type_ignores, arena);
  5056. if (*out == NULL) goto failed;
  5057. return 0;
  5058. }
  5059. tp = astmodulestate_global->Interactive_type;
  5060. isinstance = PyObject_IsInstance(obj, tp);
  5061. if (isinstance == -1) {
  5062. return 1;
  5063. }
  5064. if (isinstance) {
  5065. asdl_seq* body;
  5066. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  5067. return 1;
  5068. }
  5069. if (tmp == NULL) {
  5070. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Interactive");
  5071. return 1;
  5072. }
  5073. else {
  5074. int res;
  5075. Py_ssize_t len;
  5076. Py_ssize_t i;
  5077. if (!PyList_Check(tmp)) {
  5078. PyErr_Format(PyExc_TypeError, "Interactive field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5079. goto failed;
  5080. }
  5081. len = PyList_GET_SIZE(tmp);
  5082. body = _Py_asdl_seq_new(len, arena);
  5083. if (body == NULL) goto failed;
  5084. for (i = 0; i < len; i++) {
  5085. stmt_ty val;
  5086. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5087. Py_INCREF(tmp2);
  5088. res = obj2ast_stmt(tmp2, &val, arena);
  5089. Py_DECREF(tmp2);
  5090. if (res != 0) goto failed;
  5091. if (len != PyList_GET_SIZE(tmp)) {
  5092. PyErr_SetString(PyExc_RuntimeError, "Interactive field \"body\" changed size during iteration");
  5093. goto failed;
  5094. }
  5095. asdl_seq_SET(body, i, val);
  5096. }
  5097. Py_CLEAR(tmp);
  5098. }
  5099. *out = Interactive(body, arena);
  5100. if (*out == NULL) goto failed;
  5101. return 0;
  5102. }
  5103. tp = astmodulestate_global->Expression_type;
  5104. isinstance = PyObject_IsInstance(obj, tp);
  5105. if (isinstance == -1) {
  5106. return 1;
  5107. }
  5108. if (isinstance) {
  5109. expr_ty body;
  5110. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  5111. return 1;
  5112. }
  5113. if (tmp == NULL) {
  5114. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Expression");
  5115. return 1;
  5116. }
  5117. else {
  5118. int res;
  5119. res = obj2ast_expr(tmp, &body, arena);
  5120. if (res != 0) goto failed;
  5121. Py_CLEAR(tmp);
  5122. }
  5123. *out = Expression(body, arena);
  5124. if (*out == NULL) goto failed;
  5125. return 0;
  5126. }
  5127. tp = astmodulestate_global->FunctionType_type;
  5128. isinstance = PyObject_IsInstance(obj, tp);
  5129. if (isinstance == -1) {
  5130. return 1;
  5131. }
  5132. if (isinstance) {
  5133. asdl_seq* argtypes;
  5134. expr_ty returns;
  5135. if (_PyObject_LookupAttr(obj, astmodulestate_global->argtypes, &tmp) <
  5136. 0) {
  5137. return 1;
  5138. }
  5139. if (tmp == NULL) {
  5140. PyErr_SetString(PyExc_TypeError, "required field \"argtypes\" missing from FunctionType");
  5141. return 1;
  5142. }
  5143. else {
  5144. int res;
  5145. Py_ssize_t len;
  5146. Py_ssize_t i;
  5147. if (!PyList_Check(tmp)) {
  5148. PyErr_Format(PyExc_TypeError, "FunctionType field \"argtypes\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5149. goto failed;
  5150. }
  5151. len = PyList_GET_SIZE(tmp);
  5152. argtypes = _Py_asdl_seq_new(len, arena);
  5153. if (argtypes == NULL) goto failed;
  5154. for (i = 0; i < len; i++) {
  5155. expr_ty val;
  5156. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5157. Py_INCREF(tmp2);
  5158. res = obj2ast_expr(tmp2, &val, arena);
  5159. Py_DECREF(tmp2);
  5160. if (res != 0) goto failed;
  5161. if (len != PyList_GET_SIZE(tmp)) {
  5162. PyErr_SetString(PyExc_RuntimeError, "FunctionType field \"argtypes\" changed size during iteration");
  5163. goto failed;
  5164. }
  5165. asdl_seq_SET(argtypes, i, val);
  5166. }
  5167. Py_CLEAR(tmp);
  5168. }
  5169. if (_PyObject_LookupAttr(obj, astmodulestate_global->returns, &tmp) <
  5170. 0) {
  5171. return 1;
  5172. }
  5173. if (tmp == NULL) {
  5174. PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType");
  5175. return 1;
  5176. }
  5177. else {
  5178. int res;
  5179. res = obj2ast_expr(tmp, &returns, arena);
  5180. if (res != 0) goto failed;
  5181. Py_CLEAR(tmp);
  5182. }
  5183. *out = FunctionType(argtypes, returns, arena);
  5184. if (*out == NULL) goto failed;
  5185. return 0;
  5186. }
  5187. PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %R", obj);
  5188. failed:
  5189. Py_XDECREF(tmp);
  5190. return 1;
  5191. }
  5192. int
  5193. obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
  5194. {
  5195. int isinstance;
  5196. PyObject *tmp = NULL;
  5197. PyObject *tp;
  5198. int lineno;
  5199. int col_offset;
  5200. int end_lineno;
  5201. int end_col_offset;
  5202. if (obj == Py_None) {
  5203. *out = NULL;
  5204. return 0;
  5205. }
  5206. if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0) {
  5207. return 1;
  5208. }
  5209. if (tmp == NULL) {
  5210. PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt");
  5211. return 1;
  5212. }
  5213. else {
  5214. int res;
  5215. res = obj2ast_int(tmp, &lineno, arena);
  5216. if (res != 0) goto failed;
  5217. Py_CLEAR(tmp);
  5218. }
  5219. if (_PyObject_LookupAttr(obj, astmodulestate_global->col_offset, &tmp) < 0)
  5220. {
  5221. return 1;
  5222. }
  5223. if (tmp == NULL) {
  5224. PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt");
  5225. return 1;
  5226. }
  5227. else {
  5228. int res;
  5229. res = obj2ast_int(tmp, &col_offset, arena);
  5230. if (res != 0) goto failed;
  5231. Py_CLEAR(tmp);
  5232. }
  5233. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_lineno, &tmp) < 0)
  5234. {
  5235. return 1;
  5236. }
  5237. if (tmp == NULL || tmp == Py_None) {
  5238. Py_CLEAR(tmp);
  5239. end_lineno = 0;
  5240. }
  5241. else {
  5242. int res;
  5243. res = obj2ast_int(tmp, &end_lineno, arena);
  5244. if (res != 0) goto failed;
  5245. Py_CLEAR(tmp);
  5246. }
  5247. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_col_offset, &tmp)
  5248. < 0) {
  5249. return 1;
  5250. }
  5251. if (tmp == NULL || tmp == Py_None) {
  5252. Py_CLEAR(tmp);
  5253. end_col_offset = 0;
  5254. }
  5255. else {
  5256. int res;
  5257. res = obj2ast_int(tmp, &end_col_offset, arena);
  5258. if (res != 0) goto failed;
  5259. Py_CLEAR(tmp);
  5260. }
  5261. tp = astmodulestate_global->FunctionDef_type;
  5262. isinstance = PyObject_IsInstance(obj, tp);
  5263. if (isinstance == -1) {
  5264. return 1;
  5265. }
  5266. if (isinstance) {
  5267. identifier name;
  5268. arguments_ty args;
  5269. asdl_seq* body;
  5270. asdl_seq* decorator_list;
  5271. expr_ty returns;
  5272. string type_comment;
  5273. if (_PyObject_LookupAttr(obj, astmodulestate_global->name, &tmp) < 0) {
  5274. return 1;
  5275. }
  5276. if (tmp == NULL) {
  5277. PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef");
  5278. return 1;
  5279. }
  5280. else {
  5281. int res;
  5282. res = obj2ast_identifier(tmp, &name, arena);
  5283. if (res != 0) goto failed;
  5284. Py_CLEAR(tmp);
  5285. }
  5286. if (_PyObject_LookupAttr(obj, astmodulestate_global->args, &tmp) < 0) {
  5287. return 1;
  5288. }
  5289. if (tmp == NULL) {
  5290. PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef");
  5291. return 1;
  5292. }
  5293. else {
  5294. int res;
  5295. res = obj2ast_arguments(tmp, &args, arena);
  5296. if (res != 0) goto failed;
  5297. Py_CLEAR(tmp);
  5298. }
  5299. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  5300. return 1;
  5301. }
  5302. if (tmp == NULL) {
  5303. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from FunctionDef");
  5304. return 1;
  5305. }
  5306. else {
  5307. int res;
  5308. Py_ssize_t len;
  5309. Py_ssize_t i;
  5310. if (!PyList_Check(tmp)) {
  5311. PyErr_Format(PyExc_TypeError, "FunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5312. goto failed;
  5313. }
  5314. len = PyList_GET_SIZE(tmp);
  5315. body = _Py_asdl_seq_new(len, arena);
  5316. if (body == NULL) goto failed;
  5317. for (i = 0; i < len; i++) {
  5318. stmt_ty val;
  5319. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5320. Py_INCREF(tmp2);
  5321. res = obj2ast_stmt(tmp2, &val, arena);
  5322. Py_DECREF(tmp2);
  5323. if (res != 0) goto failed;
  5324. if (len != PyList_GET_SIZE(tmp)) {
  5325. PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"body\" changed size during iteration");
  5326. goto failed;
  5327. }
  5328. asdl_seq_SET(body, i, val);
  5329. }
  5330. Py_CLEAR(tmp);
  5331. }
  5332. if (_PyObject_LookupAttr(obj, astmodulestate_global->decorator_list,
  5333. &tmp) < 0) {
  5334. return 1;
  5335. }
  5336. if (tmp == NULL) {
  5337. PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef");
  5338. return 1;
  5339. }
  5340. else {
  5341. int res;
  5342. Py_ssize_t len;
  5343. Py_ssize_t i;
  5344. if (!PyList_Check(tmp)) {
  5345. PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5346. goto failed;
  5347. }
  5348. len = PyList_GET_SIZE(tmp);
  5349. decorator_list = _Py_asdl_seq_new(len, arena);
  5350. if (decorator_list == NULL) goto failed;
  5351. for (i = 0; i < len; i++) {
  5352. expr_ty val;
  5353. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5354. Py_INCREF(tmp2);
  5355. res = obj2ast_expr(tmp2, &val, arena);
  5356. Py_DECREF(tmp2);
  5357. if (res != 0) goto failed;
  5358. if (len != PyList_GET_SIZE(tmp)) {
  5359. PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"decorator_list\" changed size during iteration");
  5360. goto failed;
  5361. }
  5362. asdl_seq_SET(decorator_list, i, val);
  5363. }
  5364. Py_CLEAR(tmp);
  5365. }
  5366. if (_PyObject_LookupAttr(obj, astmodulestate_global->returns, &tmp) <
  5367. 0) {
  5368. return 1;
  5369. }
  5370. if (tmp == NULL || tmp == Py_None) {
  5371. Py_CLEAR(tmp);
  5372. returns = NULL;
  5373. }
  5374. else {
  5375. int res;
  5376. res = obj2ast_expr(tmp, &returns, arena);
  5377. if (res != 0) goto failed;
  5378. Py_CLEAR(tmp);
  5379. }
  5380. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  5381. &tmp) < 0) {
  5382. return 1;
  5383. }
  5384. if (tmp == NULL || tmp == Py_None) {
  5385. Py_CLEAR(tmp);
  5386. type_comment = NULL;
  5387. }
  5388. else {
  5389. int res;
  5390. res = obj2ast_string(tmp, &type_comment, arena);
  5391. if (res != 0) goto failed;
  5392. Py_CLEAR(tmp);
  5393. }
  5394. *out = FunctionDef(name, args, body, decorator_list, returns,
  5395. type_comment, lineno, col_offset, end_lineno,
  5396. end_col_offset, arena);
  5397. if (*out == NULL) goto failed;
  5398. return 0;
  5399. }
  5400. tp = astmodulestate_global->AsyncFunctionDef_type;
  5401. isinstance = PyObject_IsInstance(obj, tp);
  5402. if (isinstance == -1) {
  5403. return 1;
  5404. }
  5405. if (isinstance) {
  5406. identifier name;
  5407. arguments_ty args;
  5408. asdl_seq* body;
  5409. asdl_seq* decorator_list;
  5410. expr_ty returns;
  5411. string type_comment;
  5412. if (_PyObject_LookupAttr(obj, astmodulestate_global->name, &tmp) < 0) {
  5413. return 1;
  5414. }
  5415. if (tmp == NULL) {
  5416. PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef");
  5417. return 1;
  5418. }
  5419. else {
  5420. int res;
  5421. res = obj2ast_identifier(tmp, &name, arena);
  5422. if (res != 0) goto failed;
  5423. Py_CLEAR(tmp);
  5424. }
  5425. if (_PyObject_LookupAttr(obj, astmodulestate_global->args, &tmp) < 0) {
  5426. return 1;
  5427. }
  5428. if (tmp == NULL) {
  5429. PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef");
  5430. return 1;
  5431. }
  5432. else {
  5433. int res;
  5434. res = obj2ast_arguments(tmp, &args, arena);
  5435. if (res != 0) goto failed;
  5436. Py_CLEAR(tmp);
  5437. }
  5438. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  5439. return 1;
  5440. }
  5441. if (tmp == NULL) {
  5442. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFunctionDef");
  5443. return 1;
  5444. }
  5445. else {
  5446. int res;
  5447. Py_ssize_t len;
  5448. Py_ssize_t i;
  5449. if (!PyList_Check(tmp)) {
  5450. PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5451. goto failed;
  5452. }
  5453. len = PyList_GET_SIZE(tmp);
  5454. body = _Py_asdl_seq_new(len, arena);
  5455. if (body == NULL) goto failed;
  5456. for (i = 0; i < len; i++) {
  5457. stmt_ty val;
  5458. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5459. Py_INCREF(tmp2);
  5460. res = obj2ast_stmt(tmp2, &val, arena);
  5461. Py_DECREF(tmp2);
  5462. if (res != 0) goto failed;
  5463. if (len != PyList_GET_SIZE(tmp)) {
  5464. PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"body\" changed size during iteration");
  5465. goto failed;
  5466. }
  5467. asdl_seq_SET(body, i, val);
  5468. }
  5469. Py_CLEAR(tmp);
  5470. }
  5471. if (_PyObject_LookupAttr(obj, astmodulestate_global->decorator_list,
  5472. &tmp) < 0) {
  5473. return 1;
  5474. }
  5475. if (tmp == NULL) {
  5476. PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from AsyncFunctionDef");
  5477. return 1;
  5478. }
  5479. else {
  5480. int res;
  5481. Py_ssize_t len;
  5482. Py_ssize_t i;
  5483. if (!PyList_Check(tmp)) {
  5484. PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5485. goto failed;
  5486. }
  5487. len = PyList_GET_SIZE(tmp);
  5488. decorator_list = _Py_asdl_seq_new(len, arena);
  5489. if (decorator_list == NULL) goto failed;
  5490. for (i = 0; i < len; i++) {
  5491. expr_ty val;
  5492. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5493. Py_INCREF(tmp2);
  5494. res = obj2ast_expr(tmp2, &val, arena);
  5495. Py_DECREF(tmp2);
  5496. if (res != 0) goto failed;
  5497. if (len != PyList_GET_SIZE(tmp)) {
  5498. PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"decorator_list\" changed size during iteration");
  5499. goto failed;
  5500. }
  5501. asdl_seq_SET(decorator_list, i, val);
  5502. }
  5503. Py_CLEAR(tmp);
  5504. }
  5505. if (_PyObject_LookupAttr(obj, astmodulestate_global->returns, &tmp) <
  5506. 0) {
  5507. return 1;
  5508. }
  5509. if (tmp == NULL || tmp == Py_None) {
  5510. Py_CLEAR(tmp);
  5511. returns = NULL;
  5512. }
  5513. else {
  5514. int res;
  5515. res = obj2ast_expr(tmp, &returns, arena);
  5516. if (res != 0) goto failed;
  5517. Py_CLEAR(tmp);
  5518. }
  5519. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  5520. &tmp) < 0) {
  5521. return 1;
  5522. }
  5523. if (tmp == NULL || tmp == Py_None) {
  5524. Py_CLEAR(tmp);
  5525. type_comment = NULL;
  5526. }
  5527. else {
  5528. int res;
  5529. res = obj2ast_string(tmp, &type_comment, arena);
  5530. if (res != 0) goto failed;
  5531. Py_CLEAR(tmp);
  5532. }
  5533. *out = AsyncFunctionDef(name, args, body, decorator_list, returns,
  5534. type_comment, lineno, col_offset, end_lineno,
  5535. end_col_offset, arena);
  5536. if (*out == NULL) goto failed;
  5537. return 0;
  5538. }
  5539. tp = astmodulestate_global->ClassDef_type;
  5540. isinstance = PyObject_IsInstance(obj, tp);
  5541. if (isinstance == -1) {
  5542. return 1;
  5543. }
  5544. if (isinstance) {
  5545. identifier name;
  5546. asdl_seq* bases;
  5547. asdl_seq* keywords;
  5548. asdl_seq* body;
  5549. asdl_seq* decorator_list;
  5550. if (_PyObject_LookupAttr(obj, astmodulestate_global->name, &tmp) < 0) {
  5551. return 1;
  5552. }
  5553. if (tmp == NULL) {
  5554. PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef");
  5555. return 1;
  5556. }
  5557. else {
  5558. int res;
  5559. res = obj2ast_identifier(tmp, &name, arena);
  5560. if (res != 0) goto failed;
  5561. Py_CLEAR(tmp);
  5562. }
  5563. if (_PyObject_LookupAttr(obj, astmodulestate_global->bases, &tmp) < 0) {
  5564. return 1;
  5565. }
  5566. if (tmp == NULL) {
  5567. PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef");
  5568. return 1;
  5569. }
  5570. else {
  5571. int res;
  5572. Py_ssize_t len;
  5573. Py_ssize_t i;
  5574. if (!PyList_Check(tmp)) {
  5575. PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5576. goto failed;
  5577. }
  5578. len = PyList_GET_SIZE(tmp);
  5579. bases = _Py_asdl_seq_new(len, arena);
  5580. if (bases == NULL) goto failed;
  5581. for (i = 0; i < len; i++) {
  5582. expr_ty val;
  5583. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5584. Py_INCREF(tmp2);
  5585. res = obj2ast_expr(tmp2, &val, arena);
  5586. Py_DECREF(tmp2);
  5587. if (res != 0) goto failed;
  5588. if (len != PyList_GET_SIZE(tmp)) {
  5589. PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"bases\" changed size during iteration");
  5590. goto failed;
  5591. }
  5592. asdl_seq_SET(bases, i, val);
  5593. }
  5594. Py_CLEAR(tmp);
  5595. }
  5596. if (_PyObject_LookupAttr(obj, astmodulestate_global->keywords, &tmp) <
  5597. 0) {
  5598. return 1;
  5599. }
  5600. if (tmp == NULL) {
  5601. PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef");
  5602. return 1;
  5603. }
  5604. else {
  5605. int res;
  5606. Py_ssize_t len;
  5607. Py_ssize_t i;
  5608. if (!PyList_Check(tmp)) {
  5609. PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5610. goto failed;
  5611. }
  5612. len = PyList_GET_SIZE(tmp);
  5613. keywords = _Py_asdl_seq_new(len, arena);
  5614. if (keywords == NULL) goto failed;
  5615. for (i = 0; i < len; i++) {
  5616. keyword_ty val;
  5617. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5618. Py_INCREF(tmp2);
  5619. res = obj2ast_keyword(tmp2, &val, arena);
  5620. Py_DECREF(tmp2);
  5621. if (res != 0) goto failed;
  5622. if (len != PyList_GET_SIZE(tmp)) {
  5623. PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"keywords\" changed size during iteration");
  5624. goto failed;
  5625. }
  5626. asdl_seq_SET(keywords, i, val);
  5627. }
  5628. Py_CLEAR(tmp);
  5629. }
  5630. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  5631. return 1;
  5632. }
  5633. if (tmp == NULL) {
  5634. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ClassDef");
  5635. return 1;
  5636. }
  5637. else {
  5638. int res;
  5639. Py_ssize_t len;
  5640. Py_ssize_t i;
  5641. if (!PyList_Check(tmp)) {
  5642. PyErr_Format(PyExc_TypeError, "ClassDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5643. goto failed;
  5644. }
  5645. len = PyList_GET_SIZE(tmp);
  5646. body = _Py_asdl_seq_new(len, arena);
  5647. if (body == NULL) goto failed;
  5648. for (i = 0; i < len; i++) {
  5649. stmt_ty val;
  5650. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5651. Py_INCREF(tmp2);
  5652. res = obj2ast_stmt(tmp2, &val, arena);
  5653. Py_DECREF(tmp2);
  5654. if (res != 0) goto failed;
  5655. if (len != PyList_GET_SIZE(tmp)) {
  5656. PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"body\" changed size during iteration");
  5657. goto failed;
  5658. }
  5659. asdl_seq_SET(body, i, val);
  5660. }
  5661. Py_CLEAR(tmp);
  5662. }
  5663. if (_PyObject_LookupAttr(obj, astmodulestate_global->decorator_list,
  5664. &tmp) < 0) {
  5665. return 1;
  5666. }
  5667. if (tmp == NULL) {
  5668. PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef");
  5669. return 1;
  5670. }
  5671. else {
  5672. int res;
  5673. Py_ssize_t len;
  5674. Py_ssize_t i;
  5675. if (!PyList_Check(tmp)) {
  5676. PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5677. goto failed;
  5678. }
  5679. len = PyList_GET_SIZE(tmp);
  5680. decorator_list = _Py_asdl_seq_new(len, arena);
  5681. if (decorator_list == NULL) goto failed;
  5682. for (i = 0; i < len; i++) {
  5683. expr_ty val;
  5684. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5685. Py_INCREF(tmp2);
  5686. res = obj2ast_expr(tmp2, &val, arena);
  5687. Py_DECREF(tmp2);
  5688. if (res != 0) goto failed;
  5689. if (len != PyList_GET_SIZE(tmp)) {
  5690. PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"decorator_list\" changed size during iteration");
  5691. goto failed;
  5692. }
  5693. asdl_seq_SET(decorator_list, i, val);
  5694. }
  5695. Py_CLEAR(tmp);
  5696. }
  5697. *out = ClassDef(name, bases, keywords, body, decorator_list, lineno,
  5698. col_offset, end_lineno, end_col_offset, arena);
  5699. if (*out == NULL) goto failed;
  5700. return 0;
  5701. }
  5702. tp = astmodulestate_global->Return_type;
  5703. isinstance = PyObject_IsInstance(obj, tp);
  5704. if (isinstance == -1) {
  5705. return 1;
  5706. }
  5707. if (isinstance) {
  5708. expr_ty value;
  5709. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  5710. return 1;
  5711. }
  5712. if (tmp == NULL || tmp == Py_None) {
  5713. Py_CLEAR(tmp);
  5714. value = NULL;
  5715. }
  5716. else {
  5717. int res;
  5718. res = obj2ast_expr(tmp, &value, arena);
  5719. if (res != 0) goto failed;
  5720. Py_CLEAR(tmp);
  5721. }
  5722. *out = Return(value, lineno, col_offset, end_lineno, end_col_offset,
  5723. arena);
  5724. if (*out == NULL) goto failed;
  5725. return 0;
  5726. }
  5727. tp = astmodulestate_global->Delete_type;
  5728. isinstance = PyObject_IsInstance(obj, tp);
  5729. if (isinstance == -1) {
  5730. return 1;
  5731. }
  5732. if (isinstance) {
  5733. asdl_seq* targets;
  5734. if (_PyObject_LookupAttr(obj, astmodulestate_global->targets, &tmp) <
  5735. 0) {
  5736. return 1;
  5737. }
  5738. if (tmp == NULL) {
  5739. PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Delete");
  5740. return 1;
  5741. }
  5742. else {
  5743. int res;
  5744. Py_ssize_t len;
  5745. Py_ssize_t i;
  5746. if (!PyList_Check(tmp)) {
  5747. PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5748. goto failed;
  5749. }
  5750. len = PyList_GET_SIZE(tmp);
  5751. targets = _Py_asdl_seq_new(len, arena);
  5752. if (targets == NULL) goto failed;
  5753. for (i = 0; i < len; i++) {
  5754. expr_ty val;
  5755. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5756. Py_INCREF(tmp2);
  5757. res = obj2ast_expr(tmp2, &val, arena);
  5758. Py_DECREF(tmp2);
  5759. if (res != 0) goto failed;
  5760. if (len != PyList_GET_SIZE(tmp)) {
  5761. PyErr_SetString(PyExc_RuntimeError, "Delete field \"targets\" changed size during iteration");
  5762. goto failed;
  5763. }
  5764. asdl_seq_SET(targets, i, val);
  5765. }
  5766. Py_CLEAR(tmp);
  5767. }
  5768. *out = Delete(targets, lineno, col_offset, end_lineno, end_col_offset,
  5769. arena);
  5770. if (*out == NULL) goto failed;
  5771. return 0;
  5772. }
  5773. tp = astmodulestate_global->Assign_type;
  5774. isinstance = PyObject_IsInstance(obj, tp);
  5775. if (isinstance == -1) {
  5776. return 1;
  5777. }
  5778. if (isinstance) {
  5779. asdl_seq* targets;
  5780. expr_ty value;
  5781. string type_comment;
  5782. if (_PyObject_LookupAttr(obj, astmodulestate_global->targets, &tmp) <
  5783. 0) {
  5784. return 1;
  5785. }
  5786. if (tmp == NULL) {
  5787. PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign");
  5788. return 1;
  5789. }
  5790. else {
  5791. int res;
  5792. Py_ssize_t len;
  5793. Py_ssize_t i;
  5794. if (!PyList_Check(tmp)) {
  5795. PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  5796. goto failed;
  5797. }
  5798. len = PyList_GET_SIZE(tmp);
  5799. targets = _Py_asdl_seq_new(len, arena);
  5800. if (targets == NULL) goto failed;
  5801. for (i = 0; i < len; i++) {
  5802. expr_ty val;
  5803. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  5804. Py_INCREF(tmp2);
  5805. res = obj2ast_expr(tmp2, &val, arena);
  5806. Py_DECREF(tmp2);
  5807. if (res != 0) goto failed;
  5808. if (len != PyList_GET_SIZE(tmp)) {
  5809. PyErr_SetString(PyExc_RuntimeError, "Assign field \"targets\" changed size during iteration");
  5810. goto failed;
  5811. }
  5812. asdl_seq_SET(targets, i, val);
  5813. }
  5814. Py_CLEAR(tmp);
  5815. }
  5816. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  5817. return 1;
  5818. }
  5819. if (tmp == NULL) {
  5820. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign");
  5821. return 1;
  5822. }
  5823. else {
  5824. int res;
  5825. res = obj2ast_expr(tmp, &value, arena);
  5826. if (res != 0) goto failed;
  5827. Py_CLEAR(tmp);
  5828. }
  5829. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  5830. &tmp) < 0) {
  5831. return 1;
  5832. }
  5833. if (tmp == NULL || tmp == Py_None) {
  5834. Py_CLEAR(tmp);
  5835. type_comment = NULL;
  5836. }
  5837. else {
  5838. int res;
  5839. res = obj2ast_string(tmp, &type_comment, arena);
  5840. if (res != 0) goto failed;
  5841. Py_CLEAR(tmp);
  5842. }
  5843. *out = Assign(targets, value, type_comment, lineno, col_offset,
  5844. end_lineno, end_col_offset, arena);
  5845. if (*out == NULL) goto failed;
  5846. return 0;
  5847. }
  5848. tp = astmodulestate_global->AugAssign_type;
  5849. isinstance = PyObject_IsInstance(obj, tp);
  5850. if (isinstance == -1) {
  5851. return 1;
  5852. }
  5853. if (isinstance) {
  5854. expr_ty target;
  5855. operator_ty op;
  5856. expr_ty value;
  5857. if (_PyObject_LookupAttr(obj, astmodulestate_global->target, &tmp) < 0)
  5858. {
  5859. return 1;
  5860. }
  5861. if (tmp == NULL) {
  5862. PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign");
  5863. return 1;
  5864. }
  5865. else {
  5866. int res;
  5867. res = obj2ast_expr(tmp, &target, arena);
  5868. if (res != 0) goto failed;
  5869. Py_CLEAR(tmp);
  5870. }
  5871. if (_PyObject_LookupAttr(obj, astmodulestate_global->op, &tmp) < 0) {
  5872. return 1;
  5873. }
  5874. if (tmp == NULL) {
  5875. PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign");
  5876. return 1;
  5877. }
  5878. else {
  5879. int res;
  5880. res = obj2ast_operator(tmp, &op, arena);
  5881. if (res != 0) goto failed;
  5882. Py_CLEAR(tmp);
  5883. }
  5884. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  5885. return 1;
  5886. }
  5887. if (tmp == NULL) {
  5888. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from AugAssign");
  5889. return 1;
  5890. }
  5891. else {
  5892. int res;
  5893. res = obj2ast_expr(tmp, &value, arena);
  5894. if (res != 0) goto failed;
  5895. Py_CLEAR(tmp);
  5896. }
  5897. *out = AugAssign(target, op, value, lineno, col_offset, end_lineno,
  5898. end_col_offset, arena);
  5899. if (*out == NULL) goto failed;
  5900. return 0;
  5901. }
  5902. tp = astmodulestate_global->AnnAssign_type;
  5903. isinstance = PyObject_IsInstance(obj, tp);
  5904. if (isinstance == -1) {
  5905. return 1;
  5906. }
  5907. if (isinstance) {
  5908. expr_ty target;
  5909. expr_ty annotation;
  5910. expr_ty value;
  5911. int simple;
  5912. if (_PyObject_LookupAttr(obj, astmodulestate_global->target, &tmp) < 0)
  5913. {
  5914. return 1;
  5915. }
  5916. if (tmp == NULL) {
  5917. PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign");
  5918. return 1;
  5919. }
  5920. else {
  5921. int res;
  5922. res = obj2ast_expr(tmp, &target, arena);
  5923. if (res != 0) goto failed;
  5924. Py_CLEAR(tmp);
  5925. }
  5926. if (_PyObject_LookupAttr(obj, astmodulestate_global->annotation, &tmp)
  5927. < 0) {
  5928. return 1;
  5929. }
  5930. if (tmp == NULL) {
  5931. PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign");
  5932. return 1;
  5933. }
  5934. else {
  5935. int res;
  5936. res = obj2ast_expr(tmp, &annotation, arena);
  5937. if (res != 0) goto failed;
  5938. Py_CLEAR(tmp);
  5939. }
  5940. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  5941. return 1;
  5942. }
  5943. if (tmp == NULL || tmp == Py_None) {
  5944. Py_CLEAR(tmp);
  5945. value = NULL;
  5946. }
  5947. else {
  5948. int res;
  5949. res = obj2ast_expr(tmp, &value, arena);
  5950. if (res != 0) goto failed;
  5951. Py_CLEAR(tmp);
  5952. }
  5953. if (_PyObject_LookupAttr(obj, astmodulestate_global->simple, &tmp) < 0)
  5954. {
  5955. return 1;
  5956. }
  5957. if (tmp == NULL) {
  5958. PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign");
  5959. return 1;
  5960. }
  5961. else {
  5962. int res;
  5963. res = obj2ast_int(tmp, &simple, arena);
  5964. if (res != 0) goto failed;
  5965. Py_CLEAR(tmp);
  5966. }
  5967. *out = AnnAssign(target, annotation, value, simple, lineno, col_offset,
  5968. end_lineno, end_col_offset, arena);
  5969. if (*out == NULL) goto failed;
  5970. return 0;
  5971. }
  5972. tp = astmodulestate_global->For_type;
  5973. isinstance = PyObject_IsInstance(obj, tp);
  5974. if (isinstance == -1) {
  5975. return 1;
  5976. }
  5977. if (isinstance) {
  5978. expr_ty target;
  5979. expr_ty iter;
  5980. asdl_seq* body;
  5981. asdl_seq* orelse;
  5982. string type_comment;
  5983. if (_PyObject_LookupAttr(obj, astmodulestate_global->target, &tmp) < 0)
  5984. {
  5985. return 1;
  5986. }
  5987. if (tmp == NULL) {
  5988. PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For");
  5989. return 1;
  5990. }
  5991. else {
  5992. int res;
  5993. res = obj2ast_expr(tmp, &target, arena);
  5994. if (res != 0) goto failed;
  5995. Py_CLEAR(tmp);
  5996. }
  5997. if (_PyObject_LookupAttr(obj, astmodulestate_global->iter, &tmp) < 0) {
  5998. return 1;
  5999. }
  6000. if (tmp == NULL) {
  6001. PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For");
  6002. return 1;
  6003. }
  6004. else {
  6005. int res;
  6006. res = obj2ast_expr(tmp, &iter, arena);
  6007. if (res != 0) goto failed;
  6008. Py_CLEAR(tmp);
  6009. }
  6010. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6011. return 1;
  6012. }
  6013. if (tmp == NULL) {
  6014. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from For");
  6015. return 1;
  6016. }
  6017. else {
  6018. int res;
  6019. Py_ssize_t len;
  6020. Py_ssize_t i;
  6021. if (!PyList_Check(tmp)) {
  6022. PyErr_Format(PyExc_TypeError, "For field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6023. goto failed;
  6024. }
  6025. len = PyList_GET_SIZE(tmp);
  6026. body = _Py_asdl_seq_new(len, arena);
  6027. if (body == NULL) goto failed;
  6028. for (i = 0; i < len; i++) {
  6029. stmt_ty val;
  6030. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6031. Py_INCREF(tmp2);
  6032. res = obj2ast_stmt(tmp2, &val, arena);
  6033. Py_DECREF(tmp2);
  6034. if (res != 0) goto failed;
  6035. if (len != PyList_GET_SIZE(tmp)) {
  6036. PyErr_SetString(PyExc_RuntimeError, "For field \"body\" changed size during iteration");
  6037. goto failed;
  6038. }
  6039. asdl_seq_SET(body, i, val);
  6040. }
  6041. Py_CLEAR(tmp);
  6042. }
  6043. if (_PyObject_LookupAttr(obj, astmodulestate_global->orelse, &tmp) < 0)
  6044. {
  6045. return 1;
  6046. }
  6047. if (tmp == NULL) {
  6048. PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from For");
  6049. return 1;
  6050. }
  6051. else {
  6052. int res;
  6053. Py_ssize_t len;
  6054. Py_ssize_t i;
  6055. if (!PyList_Check(tmp)) {
  6056. PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6057. goto failed;
  6058. }
  6059. len = PyList_GET_SIZE(tmp);
  6060. orelse = _Py_asdl_seq_new(len, arena);
  6061. if (orelse == NULL) goto failed;
  6062. for (i = 0; i < len; i++) {
  6063. stmt_ty val;
  6064. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6065. Py_INCREF(tmp2);
  6066. res = obj2ast_stmt(tmp2, &val, arena);
  6067. Py_DECREF(tmp2);
  6068. if (res != 0) goto failed;
  6069. if (len != PyList_GET_SIZE(tmp)) {
  6070. PyErr_SetString(PyExc_RuntimeError, "For field \"orelse\" changed size during iteration");
  6071. goto failed;
  6072. }
  6073. asdl_seq_SET(orelse, i, val);
  6074. }
  6075. Py_CLEAR(tmp);
  6076. }
  6077. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  6078. &tmp) < 0) {
  6079. return 1;
  6080. }
  6081. if (tmp == NULL || tmp == Py_None) {
  6082. Py_CLEAR(tmp);
  6083. type_comment = NULL;
  6084. }
  6085. else {
  6086. int res;
  6087. res = obj2ast_string(tmp, &type_comment, arena);
  6088. if (res != 0) goto failed;
  6089. Py_CLEAR(tmp);
  6090. }
  6091. *out = For(target, iter, body, orelse, type_comment, lineno,
  6092. col_offset, end_lineno, end_col_offset, arena);
  6093. if (*out == NULL) goto failed;
  6094. return 0;
  6095. }
  6096. tp = astmodulestate_global->AsyncFor_type;
  6097. isinstance = PyObject_IsInstance(obj, tp);
  6098. if (isinstance == -1) {
  6099. return 1;
  6100. }
  6101. if (isinstance) {
  6102. expr_ty target;
  6103. expr_ty iter;
  6104. asdl_seq* body;
  6105. asdl_seq* orelse;
  6106. string type_comment;
  6107. if (_PyObject_LookupAttr(obj, astmodulestate_global->target, &tmp) < 0)
  6108. {
  6109. return 1;
  6110. }
  6111. if (tmp == NULL) {
  6112. PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor");
  6113. return 1;
  6114. }
  6115. else {
  6116. int res;
  6117. res = obj2ast_expr(tmp, &target, arena);
  6118. if (res != 0) goto failed;
  6119. Py_CLEAR(tmp);
  6120. }
  6121. if (_PyObject_LookupAttr(obj, astmodulestate_global->iter, &tmp) < 0) {
  6122. return 1;
  6123. }
  6124. if (tmp == NULL) {
  6125. PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor");
  6126. return 1;
  6127. }
  6128. else {
  6129. int res;
  6130. res = obj2ast_expr(tmp, &iter, arena);
  6131. if (res != 0) goto failed;
  6132. Py_CLEAR(tmp);
  6133. }
  6134. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6135. return 1;
  6136. }
  6137. if (tmp == NULL) {
  6138. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFor");
  6139. return 1;
  6140. }
  6141. else {
  6142. int res;
  6143. Py_ssize_t len;
  6144. Py_ssize_t i;
  6145. if (!PyList_Check(tmp)) {
  6146. PyErr_Format(PyExc_TypeError, "AsyncFor field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6147. goto failed;
  6148. }
  6149. len = PyList_GET_SIZE(tmp);
  6150. body = _Py_asdl_seq_new(len, arena);
  6151. if (body == NULL) goto failed;
  6152. for (i = 0; i < len; i++) {
  6153. stmt_ty val;
  6154. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6155. Py_INCREF(tmp2);
  6156. res = obj2ast_stmt(tmp2, &val, arena);
  6157. Py_DECREF(tmp2);
  6158. if (res != 0) goto failed;
  6159. if (len != PyList_GET_SIZE(tmp)) {
  6160. PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"body\" changed size during iteration");
  6161. goto failed;
  6162. }
  6163. asdl_seq_SET(body, i, val);
  6164. }
  6165. Py_CLEAR(tmp);
  6166. }
  6167. if (_PyObject_LookupAttr(obj, astmodulestate_global->orelse, &tmp) < 0)
  6168. {
  6169. return 1;
  6170. }
  6171. if (tmp == NULL) {
  6172. PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from AsyncFor");
  6173. return 1;
  6174. }
  6175. else {
  6176. int res;
  6177. Py_ssize_t len;
  6178. Py_ssize_t i;
  6179. if (!PyList_Check(tmp)) {
  6180. PyErr_Format(PyExc_TypeError, "AsyncFor field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6181. goto failed;
  6182. }
  6183. len = PyList_GET_SIZE(tmp);
  6184. orelse = _Py_asdl_seq_new(len, arena);
  6185. if (orelse == NULL) goto failed;
  6186. for (i = 0; i < len; i++) {
  6187. stmt_ty val;
  6188. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6189. Py_INCREF(tmp2);
  6190. res = obj2ast_stmt(tmp2, &val, arena);
  6191. Py_DECREF(tmp2);
  6192. if (res != 0) goto failed;
  6193. if (len != PyList_GET_SIZE(tmp)) {
  6194. PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"orelse\" changed size during iteration");
  6195. goto failed;
  6196. }
  6197. asdl_seq_SET(orelse, i, val);
  6198. }
  6199. Py_CLEAR(tmp);
  6200. }
  6201. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  6202. &tmp) < 0) {
  6203. return 1;
  6204. }
  6205. if (tmp == NULL || tmp == Py_None) {
  6206. Py_CLEAR(tmp);
  6207. type_comment = NULL;
  6208. }
  6209. else {
  6210. int res;
  6211. res = obj2ast_string(tmp, &type_comment, arena);
  6212. if (res != 0) goto failed;
  6213. Py_CLEAR(tmp);
  6214. }
  6215. *out = AsyncFor(target, iter, body, orelse, type_comment, lineno,
  6216. col_offset, end_lineno, end_col_offset, arena);
  6217. if (*out == NULL) goto failed;
  6218. return 0;
  6219. }
  6220. tp = astmodulestate_global->While_type;
  6221. isinstance = PyObject_IsInstance(obj, tp);
  6222. if (isinstance == -1) {
  6223. return 1;
  6224. }
  6225. if (isinstance) {
  6226. expr_ty test;
  6227. asdl_seq* body;
  6228. asdl_seq* orelse;
  6229. if (_PyObject_LookupAttr(obj, astmodulestate_global->test, &tmp) < 0) {
  6230. return 1;
  6231. }
  6232. if (tmp == NULL) {
  6233. PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While");
  6234. return 1;
  6235. }
  6236. else {
  6237. int res;
  6238. res = obj2ast_expr(tmp, &test, arena);
  6239. if (res != 0) goto failed;
  6240. Py_CLEAR(tmp);
  6241. }
  6242. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6243. return 1;
  6244. }
  6245. if (tmp == NULL) {
  6246. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from While");
  6247. return 1;
  6248. }
  6249. else {
  6250. int res;
  6251. Py_ssize_t len;
  6252. Py_ssize_t i;
  6253. if (!PyList_Check(tmp)) {
  6254. PyErr_Format(PyExc_TypeError, "While field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6255. goto failed;
  6256. }
  6257. len = PyList_GET_SIZE(tmp);
  6258. body = _Py_asdl_seq_new(len, arena);
  6259. if (body == NULL) goto failed;
  6260. for (i = 0; i < len; i++) {
  6261. stmt_ty val;
  6262. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6263. Py_INCREF(tmp2);
  6264. res = obj2ast_stmt(tmp2, &val, arena);
  6265. Py_DECREF(tmp2);
  6266. if (res != 0) goto failed;
  6267. if (len != PyList_GET_SIZE(tmp)) {
  6268. PyErr_SetString(PyExc_RuntimeError, "While field \"body\" changed size during iteration");
  6269. goto failed;
  6270. }
  6271. asdl_seq_SET(body, i, val);
  6272. }
  6273. Py_CLEAR(tmp);
  6274. }
  6275. if (_PyObject_LookupAttr(obj, astmodulestate_global->orelse, &tmp) < 0)
  6276. {
  6277. return 1;
  6278. }
  6279. if (tmp == NULL) {
  6280. PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from While");
  6281. return 1;
  6282. }
  6283. else {
  6284. int res;
  6285. Py_ssize_t len;
  6286. Py_ssize_t i;
  6287. if (!PyList_Check(tmp)) {
  6288. PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6289. goto failed;
  6290. }
  6291. len = PyList_GET_SIZE(tmp);
  6292. orelse = _Py_asdl_seq_new(len, arena);
  6293. if (orelse == NULL) goto failed;
  6294. for (i = 0; i < len; i++) {
  6295. stmt_ty val;
  6296. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6297. Py_INCREF(tmp2);
  6298. res = obj2ast_stmt(tmp2, &val, arena);
  6299. Py_DECREF(tmp2);
  6300. if (res != 0) goto failed;
  6301. if (len != PyList_GET_SIZE(tmp)) {
  6302. PyErr_SetString(PyExc_RuntimeError, "While field \"orelse\" changed size during iteration");
  6303. goto failed;
  6304. }
  6305. asdl_seq_SET(orelse, i, val);
  6306. }
  6307. Py_CLEAR(tmp);
  6308. }
  6309. *out = While(test, body, orelse, lineno, col_offset, end_lineno,
  6310. end_col_offset, arena);
  6311. if (*out == NULL) goto failed;
  6312. return 0;
  6313. }
  6314. tp = astmodulestate_global->If_type;
  6315. isinstance = PyObject_IsInstance(obj, tp);
  6316. if (isinstance == -1) {
  6317. return 1;
  6318. }
  6319. if (isinstance) {
  6320. expr_ty test;
  6321. asdl_seq* body;
  6322. asdl_seq* orelse;
  6323. if (_PyObject_LookupAttr(obj, astmodulestate_global->test, &tmp) < 0) {
  6324. return 1;
  6325. }
  6326. if (tmp == NULL) {
  6327. PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If");
  6328. return 1;
  6329. }
  6330. else {
  6331. int res;
  6332. res = obj2ast_expr(tmp, &test, arena);
  6333. if (res != 0) goto failed;
  6334. Py_CLEAR(tmp);
  6335. }
  6336. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6337. return 1;
  6338. }
  6339. if (tmp == NULL) {
  6340. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from If");
  6341. return 1;
  6342. }
  6343. else {
  6344. int res;
  6345. Py_ssize_t len;
  6346. Py_ssize_t i;
  6347. if (!PyList_Check(tmp)) {
  6348. PyErr_Format(PyExc_TypeError, "If field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6349. goto failed;
  6350. }
  6351. len = PyList_GET_SIZE(tmp);
  6352. body = _Py_asdl_seq_new(len, arena);
  6353. if (body == NULL) goto failed;
  6354. for (i = 0; i < len; i++) {
  6355. stmt_ty val;
  6356. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6357. Py_INCREF(tmp2);
  6358. res = obj2ast_stmt(tmp2, &val, arena);
  6359. Py_DECREF(tmp2);
  6360. if (res != 0) goto failed;
  6361. if (len != PyList_GET_SIZE(tmp)) {
  6362. PyErr_SetString(PyExc_RuntimeError, "If field \"body\" changed size during iteration");
  6363. goto failed;
  6364. }
  6365. asdl_seq_SET(body, i, val);
  6366. }
  6367. Py_CLEAR(tmp);
  6368. }
  6369. if (_PyObject_LookupAttr(obj, astmodulestate_global->orelse, &tmp) < 0)
  6370. {
  6371. return 1;
  6372. }
  6373. if (tmp == NULL) {
  6374. PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from If");
  6375. return 1;
  6376. }
  6377. else {
  6378. int res;
  6379. Py_ssize_t len;
  6380. Py_ssize_t i;
  6381. if (!PyList_Check(tmp)) {
  6382. PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6383. goto failed;
  6384. }
  6385. len = PyList_GET_SIZE(tmp);
  6386. orelse = _Py_asdl_seq_new(len, arena);
  6387. if (orelse == NULL) goto failed;
  6388. for (i = 0; i < len; i++) {
  6389. stmt_ty val;
  6390. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6391. Py_INCREF(tmp2);
  6392. res = obj2ast_stmt(tmp2, &val, arena);
  6393. Py_DECREF(tmp2);
  6394. if (res != 0) goto failed;
  6395. if (len != PyList_GET_SIZE(tmp)) {
  6396. PyErr_SetString(PyExc_RuntimeError, "If field \"orelse\" changed size during iteration");
  6397. goto failed;
  6398. }
  6399. asdl_seq_SET(orelse, i, val);
  6400. }
  6401. Py_CLEAR(tmp);
  6402. }
  6403. *out = If(test, body, orelse, lineno, col_offset, end_lineno,
  6404. end_col_offset, arena);
  6405. if (*out == NULL) goto failed;
  6406. return 0;
  6407. }
  6408. tp = astmodulestate_global->With_type;
  6409. isinstance = PyObject_IsInstance(obj, tp);
  6410. if (isinstance == -1) {
  6411. return 1;
  6412. }
  6413. if (isinstance) {
  6414. asdl_seq* items;
  6415. asdl_seq* body;
  6416. string type_comment;
  6417. if (_PyObject_LookupAttr(obj, astmodulestate_global->items, &tmp) < 0) {
  6418. return 1;
  6419. }
  6420. if (tmp == NULL) {
  6421. PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With");
  6422. return 1;
  6423. }
  6424. else {
  6425. int res;
  6426. Py_ssize_t len;
  6427. Py_ssize_t i;
  6428. if (!PyList_Check(tmp)) {
  6429. PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6430. goto failed;
  6431. }
  6432. len = PyList_GET_SIZE(tmp);
  6433. items = _Py_asdl_seq_new(len, arena);
  6434. if (items == NULL) goto failed;
  6435. for (i = 0; i < len; i++) {
  6436. withitem_ty val;
  6437. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6438. Py_INCREF(tmp2);
  6439. res = obj2ast_withitem(tmp2, &val, arena);
  6440. Py_DECREF(tmp2);
  6441. if (res != 0) goto failed;
  6442. if (len != PyList_GET_SIZE(tmp)) {
  6443. PyErr_SetString(PyExc_RuntimeError, "With field \"items\" changed size during iteration");
  6444. goto failed;
  6445. }
  6446. asdl_seq_SET(items, i, val);
  6447. }
  6448. Py_CLEAR(tmp);
  6449. }
  6450. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6451. return 1;
  6452. }
  6453. if (tmp == NULL) {
  6454. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With");
  6455. return 1;
  6456. }
  6457. else {
  6458. int res;
  6459. Py_ssize_t len;
  6460. Py_ssize_t i;
  6461. if (!PyList_Check(tmp)) {
  6462. PyErr_Format(PyExc_TypeError, "With field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6463. goto failed;
  6464. }
  6465. len = PyList_GET_SIZE(tmp);
  6466. body = _Py_asdl_seq_new(len, arena);
  6467. if (body == NULL) goto failed;
  6468. for (i = 0; i < len; i++) {
  6469. stmt_ty val;
  6470. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6471. Py_INCREF(tmp2);
  6472. res = obj2ast_stmt(tmp2, &val, arena);
  6473. Py_DECREF(tmp2);
  6474. if (res != 0) goto failed;
  6475. if (len != PyList_GET_SIZE(tmp)) {
  6476. PyErr_SetString(PyExc_RuntimeError, "With field \"body\" changed size during iteration");
  6477. goto failed;
  6478. }
  6479. asdl_seq_SET(body, i, val);
  6480. }
  6481. Py_CLEAR(tmp);
  6482. }
  6483. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  6484. &tmp) < 0) {
  6485. return 1;
  6486. }
  6487. if (tmp == NULL || tmp == Py_None) {
  6488. Py_CLEAR(tmp);
  6489. type_comment = NULL;
  6490. }
  6491. else {
  6492. int res;
  6493. res = obj2ast_string(tmp, &type_comment, arena);
  6494. if (res != 0) goto failed;
  6495. Py_CLEAR(tmp);
  6496. }
  6497. *out = With(items, body, type_comment, lineno, col_offset, end_lineno,
  6498. end_col_offset, arena);
  6499. if (*out == NULL) goto failed;
  6500. return 0;
  6501. }
  6502. tp = astmodulestate_global->AsyncWith_type;
  6503. isinstance = PyObject_IsInstance(obj, tp);
  6504. if (isinstance == -1) {
  6505. return 1;
  6506. }
  6507. if (isinstance) {
  6508. asdl_seq* items;
  6509. asdl_seq* body;
  6510. string type_comment;
  6511. if (_PyObject_LookupAttr(obj, astmodulestate_global->items, &tmp) < 0) {
  6512. return 1;
  6513. }
  6514. if (tmp == NULL) {
  6515. PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from AsyncWith");
  6516. return 1;
  6517. }
  6518. else {
  6519. int res;
  6520. Py_ssize_t len;
  6521. Py_ssize_t i;
  6522. if (!PyList_Check(tmp)) {
  6523. PyErr_Format(PyExc_TypeError, "AsyncWith field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6524. goto failed;
  6525. }
  6526. len = PyList_GET_SIZE(tmp);
  6527. items = _Py_asdl_seq_new(len, arena);
  6528. if (items == NULL) goto failed;
  6529. for (i = 0; i < len; i++) {
  6530. withitem_ty val;
  6531. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6532. Py_INCREF(tmp2);
  6533. res = obj2ast_withitem(tmp2, &val, arena);
  6534. Py_DECREF(tmp2);
  6535. if (res != 0) goto failed;
  6536. if (len != PyList_GET_SIZE(tmp)) {
  6537. PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"items\" changed size during iteration");
  6538. goto failed;
  6539. }
  6540. asdl_seq_SET(items, i, val);
  6541. }
  6542. Py_CLEAR(tmp);
  6543. }
  6544. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6545. return 1;
  6546. }
  6547. if (tmp == NULL) {
  6548. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncWith");
  6549. return 1;
  6550. }
  6551. else {
  6552. int res;
  6553. Py_ssize_t len;
  6554. Py_ssize_t i;
  6555. if (!PyList_Check(tmp)) {
  6556. PyErr_Format(PyExc_TypeError, "AsyncWith field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6557. goto failed;
  6558. }
  6559. len = PyList_GET_SIZE(tmp);
  6560. body = _Py_asdl_seq_new(len, arena);
  6561. if (body == NULL) goto failed;
  6562. for (i = 0; i < len; i++) {
  6563. stmt_ty val;
  6564. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6565. Py_INCREF(tmp2);
  6566. res = obj2ast_stmt(tmp2, &val, arena);
  6567. Py_DECREF(tmp2);
  6568. if (res != 0) goto failed;
  6569. if (len != PyList_GET_SIZE(tmp)) {
  6570. PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"body\" changed size during iteration");
  6571. goto failed;
  6572. }
  6573. asdl_seq_SET(body, i, val);
  6574. }
  6575. Py_CLEAR(tmp);
  6576. }
  6577. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment,
  6578. &tmp) < 0) {
  6579. return 1;
  6580. }
  6581. if (tmp == NULL || tmp == Py_None) {
  6582. Py_CLEAR(tmp);
  6583. type_comment = NULL;
  6584. }
  6585. else {
  6586. int res;
  6587. res = obj2ast_string(tmp, &type_comment, arena);
  6588. if (res != 0) goto failed;
  6589. Py_CLEAR(tmp);
  6590. }
  6591. *out = AsyncWith(items, body, type_comment, lineno, col_offset,
  6592. end_lineno, end_col_offset, arena);
  6593. if (*out == NULL) goto failed;
  6594. return 0;
  6595. }
  6596. tp = astmodulestate_global->Raise_type;
  6597. isinstance = PyObject_IsInstance(obj, tp);
  6598. if (isinstance == -1) {
  6599. return 1;
  6600. }
  6601. if (isinstance) {
  6602. expr_ty exc;
  6603. expr_ty cause;
  6604. if (_PyObject_LookupAttr(obj, astmodulestate_global->exc, &tmp) < 0) {
  6605. return 1;
  6606. }
  6607. if (tmp == NULL || tmp == Py_None) {
  6608. Py_CLEAR(tmp);
  6609. exc = NULL;
  6610. }
  6611. else {
  6612. int res;
  6613. res = obj2ast_expr(tmp, &exc, arena);
  6614. if (res != 0) goto failed;
  6615. Py_CLEAR(tmp);
  6616. }
  6617. if (_PyObject_LookupAttr(obj, astmodulestate_global->cause, &tmp) < 0) {
  6618. return 1;
  6619. }
  6620. if (tmp == NULL || tmp == Py_None) {
  6621. Py_CLEAR(tmp);
  6622. cause = NULL;
  6623. }
  6624. else {
  6625. int res;
  6626. res = obj2ast_expr(tmp, &cause, arena);
  6627. if (res != 0) goto failed;
  6628. Py_CLEAR(tmp);
  6629. }
  6630. *out = Raise(exc, cause, lineno, col_offset, end_lineno,
  6631. end_col_offset, arena);
  6632. if (*out == NULL) goto failed;
  6633. return 0;
  6634. }
  6635. tp = astmodulestate_global->Try_type;
  6636. isinstance = PyObject_IsInstance(obj, tp);
  6637. if (isinstance == -1) {
  6638. return 1;
  6639. }
  6640. if (isinstance) {
  6641. asdl_seq* body;
  6642. asdl_seq* handlers;
  6643. asdl_seq* orelse;
  6644. asdl_seq* finalbody;
  6645. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  6646. return 1;
  6647. }
  6648. if (tmp == NULL) {
  6649. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try");
  6650. return 1;
  6651. }
  6652. else {
  6653. int res;
  6654. Py_ssize_t len;
  6655. Py_ssize_t i;
  6656. if (!PyList_Check(tmp)) {
  6657. PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6658. goto failed;
  6659. }
  6660. len = PyList_GET_SIZE(tmp);
  6661. body = _Py_asdl_seq_new(len, arena);
  6662. if (body == NULL) goto failed;
  6663. for (i = 0; i < len; i++) {
  6664. stmt_ty val;
  6665. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6666. Py_INCREF(tmp2);
  6667. res = obj2ast_stmt(tmp2, &val, arena);
  6668. Py_DECREF(tmp2);
  6669. if (res != 0) goto failed;
  6670. if (len != PyList_GET_SIZE(tmp)) {
  6671. PyErr_SetString(PyExc_RuntimeError, "Try field \"body\" changed size during iteration");
  6672. goto failed;
  6673. }
  6674. asdl_seq_SET(body, i, val);
  6675. }
  6676. Py_CLEAR(tmp);
  6677. }
  6678. if (_PyObject_LookupAttr(obj, astmodulestate_global->handlers, &tmp) <
  6679. 0) {
  6680. return 1;
  6681. }
  6682. if (tmp == NULL) {
  6683. PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try");
  6684. return 1;
  6685. }
  6686. else {
  6687. int res;
  6688. Py_ssize_t len;
  6689. Py_ssize_t i;
  6690. if (!PyList_Check(tmp)) {
  6691. PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6692. goto failed;
  6693. }
  6694. len = PyList_GET_SIZE(tmp);
  6695. handlers = _Py_asdl_seq_new(len, arena);
  6696. if (handlers == NULL) goto failed;
  6697. for (i = 0; i < len; i++) {
  6698. excepthandler_ty val;
  6699. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6700. Py_INCREF(tmp2);
  6701. res = obj2ast_excepthandler(tmp2, &val, arena);
  6702. Py_DECREF(tmp2);
  6703. if (res != 0) goto failed;
  6704. if (len != PyList_GET_SIZE(tmp)) {
  6705. PyErr_SetString(PyExc_RuntimeError, "Try field \"handlers\" changed size during iteration");
  6706. goto failed;
  6707. }
  6708. asdl_seq_SET(handlers, i, val);
  6709. }
  6710. Py_CLEAR(tmp);
  6711. }
  6712. if (_PyObject_LookupAttr(obj, astmodulestate_global->orelse, &tmp) < 0)
  6713. {
  6714. return 1;
  6715. }
  6716. if (tmp == NULL) {
  6717. PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try");
  6718. return 1;
  6719. }
  6720. else {
  6721. int res;
  6722. Py_ssize_t len;
  6723. Py_ssize_t i;
  6724. if (!PyList_Check(tmp)) {
  6725. PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6726. goto failed;
  6727. }
  6728. len = PyList_GET_SIZE(tmp);
  6729. orelse = _Py_asdl_seq_new(len, arena);
  6730. if (orelse == NULL) goto failed;
  6731. for (i = 0; i < len; i++) {
  6732. stmt_ty val;
  6733. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6734. Py_INCREF(tmp2);
  6735. res = obj2ast_stmt(tmp2, &val, arena);
  6736. Py_DECREF(tmp2);
  6737. if (res != 0) goto failed;
  6738. if (len != PyList_GET_SIZE(tmp)) {
  6739. PyErr_SetString(PyExc_RuntimeError, "Try field \"orelse\" changed size during iteration");
  6740. goto failed;
  6741. }
  6742. asdl_seq_SET(orelse, i, val);
  6743. }
  6744. Py_CLEAR(tmp);
  6745. }
  6746. if (_PyObject_LookupAttr(obj, astmodulestate_global->finalbody, &tmp) <
  6747. 0) {
  6748. return 1;
  6749. }
  6750. if (tmp == NULL) {
  6751. PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try");
  6752. return 1;
  6753. }
  6754. else {
  6755. int res;
  6756. Py_ssize_t len;
  6757. Py_ssize_t i;
  6758. if (!PyList_Check(tmp)) {
  6759. PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6760. goto failed;
  6761. }
  6762. len = PyList_GET_SIZE(tmp);
  6763. finalbody = _Py_asdl_seq_new(len, arena);
  6764. if (finalbody == NULL) goto failed;
  6765. for (i = 0; i < len; i++) {
  6766. stmt_ty val;
  6767. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6768. Py_INCREF(tmp2);
  6769. res = obj2ast_stmt(tmp2, &val, arena);
  6770. Py_DECREF(tmp2);
  6771. if (res != 0) goto failed;
  6772. if (len != PyList_GET_SIZE(tmp)) {
  6773. PyErr_SetString(PyExc_RuntimeError, "Try field \"finalbody\" changed size during iteration");
  6774. goto failed;
  6775. }
  6776. asdl_seq_SET(finalbody, i, val);
  6777. }
  6778. Py_CLEAR(tmp);
  6779. }
  6780. *out = Try(body, handlers, orelse, finalbody, lineno, col_offset,
  6781. end_lineno, end_col_offset, arena);
  6782. if (*out == NULL) goto failed;
  6783. return 0;
  6784. }
  6785. tp = astmodulestate_global->Assert_type;
  6786. isinstance = PyObject_IsInstance(obj, tp);
  6787. if (isinstance == -1) {
  6788. return 1;
  6789. }
  6790. if (isinstance) {
  6791. expr_ty test;
  6792. expr_ty msg;
  6793. if (_PyObject_LookupAttr(obj, astmodulestate_global->test, &tmp) < 0) {
  6794. return 1;
  6795. }
  6796. if (tmp == NULL) {
  6797. PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert");
  6798. return 1;
  6799. }
  6800. else {
  6801. int res;
  6802. res = obj2ast_expr(tmp, &test, arena);
  6803. if (res != 0) goto failed;
  6804. Py_CLEAR(tmp);
  6805. }
  6806. if (_PyObject_LookupAttr(obj, astmodulestate_global->msg, &tmp) < 0) {
  6807. return 1;
  6808. }
  6809. if (tmp == NULL || tmp == Py_None) {
  6810. Py_CLEAR(tmp);
  6811. msg = NULL;
  6812. }
  6813. else {
  6814. int res;
  6815. res = obj2ast_expr(tmp, &msg, arena);
  6816. if (res != 0) goto failed;
  6817. Py_CLEAR(tmp);
  6818. }
  6819. *out = Assert(test, msg, lineno, col_offset, end_lineno,
  6820. end_col_offset, arena);
  6821. if (*out == NULL) goto failed;
  6822. return 0;
  6823. }
  6824. tp = astmodulestate_global->Import_type;
  6825. isinstance = PyObject_IsInstance(obj, tp);
  6826. if (isinstance == -1) {
  6827. return 1;
  6828. }
  6829. if (isinstance) {
  6830. asdl_seq* names;
  6831. if (_PyObject_LookupAttr(obj, astmodulestate_global->names, &tmp) < 0) {
  6832. return 1;
  6833. }
  6834. if (tmp == NULL) {
  6835. PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Import");
  6836. return 1;
  6837. }
  6838. else {
  6839. int res;
  6840. Py_ssize_t len;
  6841. Py_ssize_t i;
  6842. if (!PyList_Check(tmp)) {
  6843. PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6844. goto failed;
  6845. }
  6846. len = PyList_GET_SIZE(tmp);
  6847. names = _Py_asdl_seq_new(len, arena);
  6848. if (names == NULL) goto failed;
  6849. for (i = 0; i < len; i++) {
  6850. alias_ty val;
  6851. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6852. Py_INCREF(tmp2);
  6853. res = obj2ast_alias(tmp2, &val, arena);
  6854. Py_DECREF(tmp2);
  6855. if (res != 0) goto failed;
  6856. if (len != PyList_GET_SIZE(tmp)) {
  6857. PyErr_SetString(PyExc_RuntimeError, "Import field \"names\" changed size during iteration");
  6858. goto failed;
  6859. }
  6860. asdl_seq_SET(names, i, val);
  6861. }
  6862. Py_CLEAR(tmp);
  6863. }
  6864. *out = Import(names, lineno, col_offset, end_lineno, end_col_offset,
  6865. arena);
  6866. if (*out == NULL) goto failed;
  6867. return 0;
  6868. }
  6869. tp = astmodulestate_global->ImportFrom_type;
  6870. isinstance = PyObject_IsInstance(obj, tp);
  6871. if (isinstance == -1) {
  6872. return 1;
  6873. }
  6874. if (isinstance) {
  6875. identifier module;
  6876. asdl_seq* names;
  6877. int level;
  6878. if (_PyObject_LookupAttr(obj, astmodulestate_global->module, &tmp) < 0)
  6879. {
  6880. return 1;
  6881. }
  6882. if (tmp == NULL || tmp == Py_None) {
  6883. Py_CLEAR(tmp);
  6884. module = NULL;
  6885. }
  6886. else {
  6887. int res;
  6888. res = obj2ast_identifier(tmp, &module, arena);
  6889. if (res != 0) goto failed;
  6890. Py_CLEAR(tmp);
  6891. }
  6892. if (_PyObject_LookupAttr(obj, astmodulestate_global->names, &tmp) < 0) {
  6893. return 1;
  6894. }
  6895. if (tmp == NULL) {
  6896. PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from ImportFrom");
  6897. return 1;
  6898. }
  6899. else {
  6900. int res;
  6901. Py_ssize_t len;
  6902. Py_ssize_t i;
  6903. if (!PyList_Check(tmp)) {
  6904. PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6905. goto failed;
  6906. }
  6907. len = PyList_GET_SIZE(tmp);
  6908. names = _Py_asdl_seq_new(len, arena);
  6909. if (names == NULL) goto failed;
  6910. for (i = 0; i < len; i++) {
  6911. alias_ty val;
  6912. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6913. Py_INCREF(tmp2);
  6914. res = obj2ast_alias(tmp2, &val, arena);
  6915. Py_DECREF(tmp2);
  6916. if (res != 0) goto failed;
  6917. if (len != PyList_GET_SIZE(tmp)) {
  6918. PyErr_SetString(PyExc_RuntimeError, "ImportFrom field \"names\" changed size during iteration");
  6919. goto failed;
  6920. }
  6921. asdl_seq_SET(names, i, val);
  6922. }
  6923. Py_CLEAR(tmp);
  6924. }
  6925. if (_PyObject_LookupAttr(obj, astmodulestate_global->level, &tmp) < 0) {
  6926. return 1;
  6927. }
  6928. if (tmp == NULL || tmp == Py_None) {
  6929. Py_CLEAR(tmp);
  6930. level = 0;
  6931. }
  6932. else {
  6933. int res;
  6934. res = obj2ast_int(tmp, &level, arena);
  6935. if (res != 0) goto failed;
  6936. Py_CLEAR(tmp);
  6937. }
  6938. *out = ImportFrom(module, names, level, lineno, col_offset, end_lineno,
  6939. end_col_offset, arena);
  6940. if (*out == NULL) goto failed;
  6941. return 0;
  6942. }
  6943. tp = astmodulestate_global->Global_type;
  6944. isinstance = PyObject_IsInstance(obj, tp);
  6945. if (isinstance == -1) {
  6946. return 1;
  6947. }
  6948. if (isinstance) {
  6949. asdl_seq* names;
  6950. if (_PyObject_LookupAttr(obj, astmodulestate_global->names, &tmp) < 0) {
  6951. return 1;
  6952. }
  6953. if (tmp == NULL) {
  6954. PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Global");
  6955. return 1;
  6956. }
  6957. else {
  6958. int res;
  6959. Py_ssize_t len;
  6960. Py_ssize_t i;
  6961. if (!PyList_Check(tmp)) {
  6962. PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  6963. goto failed;
  6964. }
  6965. len = PyList_GET_SIZE(tmp);
  6966. names = _Py_asdl_seq_new(len, arena);
  6967. if (names == NULL) goto failed;
  6968. for (i = 0; i < len; i++) {
  6969. identifier val;
  6970. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  6971. Py_INCREF(tmp2);
  6972. res = obj2ast_identifier(tmp2, &val, arena);
  6973. Py_DECREF(tmp2);
  6974. if (res != 0) goto failed;
  6975. if (len != PyList_GET_SIZE(tmp)) {
  6976. PyErr_SetString(PyExc_RuntimeError, "Global field \"names\" changed size during iteration");
  6977. goto failed;
  6978. }
  6979. asdl_seq_SET(names, i, val);
  6980. }
  6981. Py_CLEAR(tmp);
  6982. }
  6983. *out = Global(names, lineno, col_offset, end_lineno, end_col_offset,
  6984. arena);
  6985. if (*out == NULL) goto failed;
  6986. return 0;
  6987. }
  6988. tp = astmodulestate_global->Nonlocal_type;
  6989. isinstance = PyObject_IsInstance(obj, tp);
  6990. if (isinstance == -1) {
  6991. return 1;
  6992. }
  6993. if (isinstance) {
  6994. asdl_seq* names;
  6995. if (_PyObject_LookupAttr(obj, astmodulestate_global->names, &tmp) < 0) {
  6996. return 1;
  6997. }
  6998. if (tmp == NULL) {
  6999. PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Nonlocal");
  7000. return 1;
  7001. }
  7002. else {
  7003. int res;
  7004. Py_ssize_t len;
  7005. Py_ssize_t i;
  7006. if (!PyList_Check(tmp)) {
  7007. PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7008. goto failed;
  7009. }
  7010. len = PyList_GET_SIZE(tmp);
  7011. names = _Py_asdl_seq_new(len, arena);
  7012. if (names == NULL) goto failed;
  7013. for (i = 0; i < len; i++) {
  7014. identifier val;
  7015. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7016. Py_INCREF(tmp2);
  7017. res = obj2ast_identifier(tmp2, &val, arena);
  7018. Py_DECREF(tmp2);
  7019. if (res != 0) goto failed;
  7020. if (len != PyList_GET_SIZE(tmp)) {
  7021. PyErr_SetString(PyExc_RuntimeError, "Nonlocal field \"names\" changed size during iteration");
  7022. goto failed;
  7023. }
  7024. asdl_seq_SET(names, i, val);
  7025. }
  7026. Py_CLEAR(tmp);
  7027. }
  7028. *out = Nonlocal(names, lineno, col_offset, end_lineno, end_col_offset,
  7029. arena);
  7030. if (*out == NULL) goto failed;
  7031. return 0;
  7032. }
  7033. tp = astmodulestate_global->Expr_type;
  7034. isinstance = PyObject_IsInstance(obj, tp);
  7035. if (isinstance == -1) {
  7036. return 1;
  7037. }
  7038. if (isinstance) {
  7039. expr_ty value;
  7040. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  7041. return 1;
  7042. }
  7043. if (tmp == NULL) {
  7044. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Expr");
  7045. return 1;
  7046. }
  7047. else {
  7048. int res;
  7049. res = obj2ast_expr(tmp, &value, arena);
  7050. if (res != 0) goto failed;
  7051. Py_CLEAR(tmp);
  7052. }
  7053. *out = Expr(value, lineno, col_offset, end_lineno, end_col_offset,
  7054. arena);
  7055. if (*out == NULL) goto failed;
  7056. return 0;
  7057. }
  7058. tp = astmodulestate_global->Pass_type;
  7059. isinstance = PyObject_IsInstance(obj, tp);
  7060. if (isinstance == -1) {
  7061. return 1;
  7062. }
  7063. if (isinstance) {
  7064. *out = Pass(lineno, col_offset, end_lineno, end_col_offset, arena);
  7065. if (*out == NULL) goto failed;
  7066. return 0;
  7067. }
  7068. tp = astmodulestate_global->Break_type;
  7069. isinstance = PyObject_IsInstance(obj, tp);
  7070. if (isinstance == -1) {
  7071. return 1;
  7072. }
  7073. if (isinstance) {
  7074. *out = Break(lineno, col_offset, end_lineno, end_col_offset, arena);
  7075. if (*out == NULL) goto failed;
  7076. return 0;
  7077. }
  7078. tp = astmodulestate_global->Continue_type;
  7079. isinstance = PyObject_IsInstance(obj, tp);
  7080. if (isinstance == -1) {
  7081. return 1;
  7082. }
  7083. if (isinstance) {
  7084. *out = Continue(lineno, col_offset, end_lineno, end_col_offset, arena);
  7085. if (*out == NULL) goto failed;
  7086. return 0;
  7087. }
  7088. PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %R", obj);
  7089. failed:
  7090. Py_XDECREF(tmp);
  7091. return 1;
  7092. }
  7093. int
  7094. obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
  7095. {
  7096. int isinstance;
  7097. PyObject *tmp = NULL;
  7098. PyObject *tp;
  7099. int lineno;
  7100. int col_offset;
  7101. int end_lineno;
  7102. int end_col_offset;
  7103. if (obj == Py_None) {
  7104. *out = NULL;
  7105. return 0;
  7106. }
  7107. if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0) {
  7108. return 1;
  7109. }
  7110. if (tmp == NULL) {
  7111. PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr");
  7112. return 1;
  7113. }
  7114. else {
  7115. int res;
  7116. res = obj2ast_int(tmp, &lineno, arena);
  7117. if (res != 0) goto failed;
  7118. Py_CLEAR(tmp);
  7119. }
  7120. if (_PyObject_LookupAttr(obj, astmodulestate_global->col_offset, &tmp) < 0)
  7121. {
  7122. return 1;
  7123. }
  7124. if (tmp == NULL) {
  7125. PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr");
  7126. return 1;
  7127. }
  7128. else {
  7129. int res;
  7130. res = obj2ast_int(tmp, &col_offset, arena);
  7131. if (res != 0) goto failed;
  7132. Py_CLEAR(tmp);
  7133. }
  7134. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_lineno, &tmp) < 0)
  7135. {
  7136. return 1;
  7137. }
  7138. if (tmp == NULL || tmp == Py_None) {
  7139. Py_CLEAR(tmp);
  7140. end_lineno = 0;
  7141. }
  7142. else {
  7143. int res;
  7144. res = obj2ast_int(tmp, &end_lineno, arena);
  7145. if (res != 0) goto failed;
  7146. Py_CLEAR(tmp);
  7147. }
  7148. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_col_offset, &tmp)
  7149. < 0) {
  7150. return 1;
  7151. }
  7152. if (tmp == NULL || tmp == Py_None) {
  7153. Py_CLEAR(tmp);
  7154. end_col_offset = 0;
  7155. }
  7156. else {
  7157. int res;
  7158. res = obj2ast_int(tmp, &end_col_offset, arena);
  7159. if (res != 0) goto failed;
  7160. Py_CLEAR(tmp);
  7161. }
  7162. tp = astmodulestate_global->BoolOp_type;
  7163. isinstance = PyObject_IsInstance(obj, tp);
  7164. if (isinstance == -1) {
  7165. return 1;
  7166. }
  7167. if (isinstance) {
  7168. boolop_ty op;
  7169. asdl_seq* values;
  7170. if (_PyObject_LookupAttr(obj, astmodulestate_global->op, &tmp) < 0) {
  7171. return 1;
  7172. }
  7173. if (tmp == NULL) {
  7174. PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp");
  7175. return 1;
  7176. }
  7177. else {
  7178. int res;
  7179. res = obj2ast_boolop(tmp, &op, arena);
  7180. if (res != 0) goto failed;
  7181. Py_CLEAR(tmp);
  7182. }
  7183. if (_PyObject_LookupAttr(obj, astmodulestate_global->values, &tmp) < 0)
  7184. {
  7185. return 1;
  7186. }
  7187. if (tmp == NULL) {
  7188. PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from BoolOp");
  7189. return 1;
  7190. }
  7191. else {
  7192. int res;
  7193. Py_ssize_t len;
  7194. Py_ssize_t i;
  7195. if (!PyList_Check(tmp)) {
  7196. PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7197. goto failed;
  7198. }
  7199. len = PyList_GET_SIZE(tmp);
  7200. values = _Py_asdl_seq_new(len, arena);
  7201. if (values == NULL) goto failed;
  7202. for (i = 0; i < len; i++) {
  7203. expr_ty val;
  7204. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7205. Py_INCREF(tmp2);
  7206. res = obj2ast_expr(tmp2, &val, arena);
  7207. Py_DECREF(tmp2);
  7208. if (res != 0) goto failed;
  7209. if (len != PyList_GET_SIZE(tmp)) {
  7210. PyErr_SetString(PyExc_RuntimeError, "BoolOp field \"values\" changed size during iteration");
  7211. goto failed;
  7212. }
  7213. asdl_seq_SET(values, i, val);
  7214. }
  7215. Py_CLEAR(tmp);
  7216. }
  7217. *out = BoolOp(op, values, lineno, col_offset, end_lineno,
  7218. end_col_offset, arena);
  7219. if (*out == NULL) goto failed;
  7220. return 0;
  7221. }
  7222. tp = astmodulestate_global->NamedExpr_type;
  7223. isinstance = PyObject_IsInstance(obj, tp);
  7224. if (isinstance == -1) {
  7225. return 1;
  7226. }
  7227. if (isinstance) {
  7228. expr_ty target;
  7229. expr_ty value;
  7230. if (_PyObject_LookupAttr(obj, astmodulestate_global->target, &tmp) < 0)
  7231. {
  7232. return 1;
  7233. }
  7234. if (tmp == NULL) {
  7235. PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr");
  7236. return 1;
  7237. }
  7238. else {
  7239. int res;
  7240. res = obj2ast_expr(tmp, &target, arena);
  7241. if (res != 0) goto failed;
  7242. Py_CLEAR(tmp);
  7243. }
  7244. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  7245. return 1;
  7246. }
  7247. if (tmp == NULL) {
  7248. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr");
  7249. return 1;
  7250. }
  7251. else {
  7252. int res;
  7253. res = obj2ast_expr(tmp, &value, arena);
  7254. if (res != 0) goto failed;
  7255. Py_CLEAR(tmp);
  7256. }
  7257. *out = NamedExpr(target, value, lineno, col_offset, end_lineno,
  7258. end_col_offset, arena);
  7259. if (*out == NULL) goto failed;
  7260. return 0;
  7261. }
  7262. tp = astmodulestate_global->BinOp_type;
  7263. isinstance = PyObject_IsInstance(obj, tp);
  7264. if (isinstance == -1) {
  7265. return 1;
  7266. }
  7267. if (isinstance) {
  7268. expr_ty left;
  7269. operator_ty op;
  7270. expr_ty right;
  7271. if (_PyObject_LookupAttr(obj, astmodulestate_global->left, &tmp) < 0) {
  7272. return 1;
  7273. }
  7274. if (tmp == NULL) {
  7275. PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp");
  7276. return 1;
  7277. }
  7278. else {
  7279. int res;
  7280. res = obj2ast_expr(tmp, &left, arena);
  7281. if (res != 0) goto failed;
  7282. Py_CLEAR(tmp);
  7283. }
  7284. if (_PyObject_LookupAttr(obj, astmodulestate_global->op, &tmp) < 0) {
  7285. return 1;
  7286. }
  7287. if (tmp == NULL) {
  7288. PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp");
  7289. return 1;
  7290. }
  7291. else {
  7292. int res;
  7293. res = obj2ast_operator(tmp, &op, arena);
  7294. if (res != 0) goto failed;
  7295. Py_CLEAR(tmp);
  7296. }
  7297. if (_PyObject_LookupAttr(obj, astmodulestate_global->right, &tmp) < 0) {
  7298. return 1;
  7299. }
  7300. if (tmp == NULL) {
  7301. PyErr_SetString(PyExc_TypeError, "required field \"right\" missing from BinOp");
  7302. return 1;
  7303. }
  7304. else {
  7305. int res;
  7306. res = obj2ast_expr(tmp, &right, arena);
  7307. if (res != 0) goto failed;
  7308. Py_CLEAR(tmp);
  7309. }
  7310. *out = BinOp(left, op, right, lineno, col_offset, end_lineno,
  7311. end_col_offset, arena);
  7312. if (*out == NULL) goto failed;
  7313. return 0;
  7314. }
  7315. tp = astmodulestate_global->UnaryOp_type;
  7316. isinstance = PyObject_IsInstance(obj, tp);
  7317. if (isinstance == -1) {
  7318. return 1;
  7319. }
  7320. if (isinstance) {
  7321. unaryop_ty op;
  7322. expr_ty operand;
  7323. if (_PyObject_LookupAttr(obj, astmodulestate_global->op, &tmp) < 0) {
  7324. return 1;
  7325. }
  7326. if (tmp == NULL) {
  7327. PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp");
  7328. return 1;
  7329. }
  7330. else {
  7331. int res;
  7332. res = obj2ast_unaryop(tmp, &op, arena);
  7333. if (res != 0) goto failed;
  7334. Py_CLEAR(tmp);
  7335. }
  7336. if (_PyObject_LookupAttr(obj, astmodulestate_global->operand, &tmp) <
  7337. 0) {
  7338. return 1;
  7339. }
  7340. if (tmp == NULL) {
  7341. PyErr_SetString(PyExc_TypeError, "required field \"operand\" missing from UnaryOp");
  7342. return 1;
  7343. }
  7344. else {
  7345. int res;
  7346. res = obj2ast_expr(tmp, &operand, arena);
  7347. if (res != 0) goto failed;
  7348. Py_CLEAR(tmp);
  7349. }
  7350. *out = UnaryOp(op, operand, lineno, col_offset, end_lineno,
  7351. end_col_offset, arena);
  7352. if (*out == NULL) goto failed;
  7353. return 0;
  7354. }
  7355. tp = astmodulestate_global->Lambda_type;
  7356. isinstance = PyObject_IsInstance(obj, tp);
  7357. if (isinstance == -1) {
  7358. return 1;
  7359. }
  7360. if (isinstance) {
  7361. arguments_ty args;
  7362. expr_ty body;
  7363. if (_PyObject_LookupAttr(obj, astmodulestate_global->args, &tmp) < 0) {
  7364. return 1;
  7365. }
  7366. if (tmp == NULL) {
  7367. PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda");
  7368. return 1;
  7369. }
  7370. else {
  7371. int res;
  7372. res = obj2ast_arguments(tmp, &args, arena);
  7373. if (res != 0) goto failed;
  7374. Py_CLEAR(tmp);
  7375. }
  7376. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  7377. return 1;
  7378. }
  7379. if (tmp == NULL) {
  7380. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Lambda");
  7381. return 1;
  7382. }
  7383. else {
  7384. int res;
  7385. res = obj2ast_expr(tmp, &body, arena);
  7386. if (res != 0) goto failed;
  7387. Py_CLEAR(tmp);
  7388. }
  7389. *out = Lambda(args, body, lineno, col_offset, end_lineno,
  7390. end_col_offset, arena);
  7391. if (*out == NULL) goto failed;
  7392. return 0;
  7393. }
  7394. tp = astmodulestate_global->IfExp_type;
  7395. isinstance = PyObject_IsInstance(obj, tp);
  7396. if (isinstance == -1) {
  7397. return 1;
  7398. }
  7399. if (isinstance) {
  7400. expr_ty test;
  7401. expr_ty body;
  7402. expr_ty orelse;
  7403. if (_PyObject_LookupAttr(obj, astmodulestate_global->test, &tmp) < 0) {
  7404. return 1;
  7405. }
  7406. if (tmp == NULL) {
  7407. PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp");
  7408. return 1;
  7409. }
  7410. else {
  7411. int res;
  7412. res = obj2ast_expr(tmp, &test, arena);
  7413. if (res != 0) goto failed;
  7414. Py_CLEAR(tmp);
  7415. }
  7416. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  7417. return 1;
  7418. }
  7419. if (tmp == NULL) {
  7420. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp");
  7421. return 1;
  7422. }
  7423. else {
  7424. int res;
  7425. res = obj2ast_expr(tmp, &body, arena);
  7426. if (res != 0) goto failed;
  7427. Py_CLEAR(tmp);
  7428. }
  7429. if (_PyObject_LookupAttr(obj, astmodulestate_global->orelse, &tmp) < 0)
  7430. {
  7431. return 1;
  7432. }
  7433. if (tmp == NULL) {
  7434. PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from IfExp");
  7435. return 1;
  7436. }
  7437. else {
  7438. int res;
  7439. res = obj2ast_expr(tmp, &orelse, arena);
  7440. if (res != 0) goto failed;
  7441. Py_CLEAR(tmp);
  7442. }
  7443. *out = IfExp(test, body, orelse, lineno, col_offset, end_lineno,
  7444. end_col_offset, arena);
  7445. if (*out == NULL) goto failed;
  7446. return 0;
  7447. }
  7448. tp = astmodulestate_global->Dict_type;
  7449. isinstance = PyObject_IsInstance(obj, tp);
  7450. if (isinstance == -1) {
  7451. return 1;
  7452. }
  7453. if (isinstance) {
  7454. asdl_seq* keys;
  7455. asdl_seq* values;
  7456. if (_PyObject_LookupAttr(obj, astmodulestate_global->keys, &tmp) < 0) {
  7457. return 1;
  7458. }
  7459. if (tmp == NULL) {
  7460. PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from Dict");
  7461. return 1;
  7462. }
  7463. else {
  7464. int res;
  7465. Py_ssize_t len;
  7466. Py_ssize_t i;
  7467. if (!PyList_Check(tmp)) {
  7468. PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7469. goto failed;
  7470. }
  7471. len = PyList_GET_SIZE(tmp);
  7472. keys = _Py_asdl_seq_new(len, arena);
  7473. if (keys == NULL) goto failed;
  7474. for (i = 0; i < len; i++) {
  7475. expr_ty val;
  7476. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7477. Py_INCREF(tmp2);
  7478. res = obj2ast_expr(tmp2, &val, arena);
  7479. Py_DECREF(tmp2);
  7480. if (res != 0) goto failed;
  7481. if (len != PyList_GET_SIZE(tmp)) {
  7482. PyErr_SetString(PyExc_RuntimeError, "Dict field \"keys\" changed size during iteration");
  7483. goto failed;
  7484. }
  7485. asdl_seq_SET(keys, i, val);
  7486. }
  7487. Py_CLEAR(tmp);
  7488. }
  7489. if (_PyObject_LookupAttr(obj, astmodulestate_global->values, &tmp) < 0)
  7490. {
  7491. return 1;
  7492. }
  7493. if (tmp == NULL) {
  7494. PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from Dict");
  7495. return 1;
  7496. }
  7497. else {
  7498. int res;
  7499. Py_ssize_t len;
  7500. Py_ssize_t i;
  7501. if (!PyList_Check(tmp)) {
  7502. PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7503. goto failed;
  7504. }
  7505. len = PyList_GET_SIZE(tmp);
  7506. values = _Py_asdl_seq_new(len, arena);
  7507. if (values == NULL) goto failed;
  7508. for (i = 0; i < len; i++) {
  7509. expr_ty val;
  7510. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7511. Py_INCREF(tmp2);
  7512. res = obj2ast_expr(tmp2, &val, arena);
  7513. Py_DECREF(tmp2);
  7514. if (res != 0) goto failed;
  7515. if (len != PyList_GET_SIZE(tmp)) {
  7516. PyErr_SetString(PyExc_RuntimeError, "Dict field \"values\" changed size during iteration");
  7517. goto failed;
  7518. }
  7519. asdl_seq_SET(values, i, val);
  7520. }
  7521. Py_CLEAR(tmp);
  7522. }
  7523. *out = Dict(keys, values, lineno, col_offset, end_lineno,
  7524. end_col_offset, arena);
  7525. if (*out == NULL) goto failed;
  7526. return 0;
  7527. }
  7528. tp = astmodulestate_global->Set_type;
  7529. isinstance = PyObject_IsInstance(obj, tp);
  7530. if (isinstance == -1) {
  7531. return 1;
  7532. }
  7533. if (isinstance) {
  7534. asdl_seq* elts;
  7535. if (_PyObject_LookupAttr(obj, astmodulestate_global->elts, &tmp) < 0) {
  7536. return 1;
  7537. }
  7538. if (tmp == NULL) {
  7539. PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Set");
  7540. return 1;
  7541. }
  7542. else {
  7543. int res;
  7544. Py_ssize_t len;
  7545. Py_ssize_t i;
  7546. if (!PyList_Check(tmp)) {
  7547. PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7548. goto failed;
  7549. }
  7550. len = PyList_GET_SIZE(tmp);
  7551. elts = _Py_asdl_seq_new(len, arena);
  7552. if (elts == NULL) goto failed;
  7553. for (i = 0; i < len; i++) {
  7554. expr_ty val;
  7555. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7556. Py_INCREF(tmp2);
  7557. res = obj2ast_expr(tmp2, &val, arena);
  7558. Py_DECREF(tmp2);
  7559. if (res != 0) goto failed;
  7560. if (len != PyList_GET_SIZE(tmp)) {
  7561. PyErr_SetString(PyExc_RuntimeError, "Set field \"elts\" changed size during iteration");
  7562. goto failed;
  7563. }
  7564. asdl_seq_SET(elts, i, val);
  7565. }
  7566. Py_CLEAR(tmp);
  7567. }
  7568. *out = Set(elts, lineno, col_offset, end_lineno, end_col_offset, arena);
  7569. if (*out == NULL) goto failed;
  7570. return 0;
  7571. }
  7572. tp = astmodulestate_global->ListComp_type;
  7573. isinstance = PyObject_IsInstance(obj, tp);
  7574. if (isinstance == -1) {
  7575. return 1;
  7576. }
  7577. if (isinstance) {
  7578. expr_ty elt;
  7579. asdl_seq* generators;
  7580. if (_PyObject_LookupAttr(obj, astmodulestate_global->elt, &tmp) < 0) {
  7581. return 1;
  7582. }
  7583. if (tmp == NULL) {
  7584. PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp");
  7585. return 1;
  7586. }
  7587. else {
  7588. int res;
  7589. res = obj2ast_expr(tmp, &elt, arena);
  7590. if (res != 0) goto failed;
  7591. Py_CLEAR(tmp);
  7592. }
  7593. if (_PyObject_LookupAttr(obj, astmodulestate_global->generators, &tmp)
  7594. < 0) {
  7595. return 1;
  7596. }
  7597. if (tmp == NULL) {
  7598. PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from ListComp");
  7599. return 1;
  7600. }
  7601. else {
  7602. int res;
  7603. Py_ssize_t len;
  7604. Py_ssize_t i;
  7605. if (!PyList_Check(tmp)) {
  7606. PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7607. goto failed;
  7608. }
  7609. len = PyList_GET_SIZE(tmp);
  7610. generators = _Py_asdl_seq_new(len, arena);
  7611. if (generators == NULL) goto failed;
  7612. for (i = 0; i < len; i++) {
  7613. comprehension_ty val;
  7614. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7615. Py_INCREF(tmp2);
  7616. res = obj2ast_comprehension(tmp2, &val, arena);
  7617. Py_DECREF(tmp2);
  7618. if (res != 0) goto failed;
  7619. if (len != PyList_GET_SIZE(tmp)) {
  7620. PyErr_SetString(PyExc_RuntimeError, "ListComp field \"generators\" changed size during iteration");
  7621. goto failed;
  7622. }
  7623. asdl_seq_SET(generators, i, val);
  7624. }
  7625. Py_CLEAR(tmp);
  7626. }
  7627. *out = ListComp(elt, generators, lineno, col_offset, end_lineno,
  7628. end_col_offset, arena);
  7629. if (*out == NULL) goto failed;
  7630. return 0;
  7631. }
  7632. tp = astmodulestate_global->SetComp_type;
  7633. isinstance = PyObject_IsInstance(obj, tp);
  7634. if (isinstance == -1) {
  7635. return 1;
  7636. }
  7637. if (isinstance) {
  7638. expr_ty elt;
  7639. asdl_seq* generators;
  7640. if (_PyObject_LookupAttr(obj, astmodulestate_global->elt, &tmp) < 0) {
  7641. return 1;
  7642. }
  7643. if (tmp == NULL) {
  7644. PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp");
  7645. return 1;
  7646. }
  7647. else {
  7648. int res;
  7649. res = obj2ast_expr(tmp, &elt, arena);
  7650. if (res != 0) goto failed;
  7651. Py_CLEAR(tmp);
  7652. }
  7653. if (_PyObject_LookupAttr(obj, astmodulestate_global->generators, &tmp)
  7654. < 0) {
  7655. return 1;
  7656. }
  7657. if (tmp == NULL) {
  7658. PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from SetComp");
  7659. return 1;
  7660. }
  7661. else {
  7662. int res;
  7663. Py_ssize_t len;
  7664. Py_ssize_t i;
  7665. if (!PyList_Check(tmp)) {
  7666. PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7667. goto failed;
  7668. }
  7669. len = PyList_GET_SIZE(tmp);
  7670. generators = _Py_asdl_seq_new(len, arena);
  7671. if (generators == NULL) goto failed;
  7672. for (i = 0; i < len; i++) {
  7673. comprehension_ty val;
  7674. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7675. Py_INCREF(tmp2);
  7676. res = obj2ast_comprehension(tmp2, &val, arena);
  7677. Py_DECREF(tmp2);
  7678. if (res != 0) goto failed;
  7679. if (len != PyList_GET_SIZE(tmp)) {
  7680. PyErr_SetString(PyExc_RuntimeError, "SetComp field \"generators\" changed size during iteration");
  7681. goto failed;
  7682. }
  7683. asdl_seq_SET(generators, i, val);
  7684. }
  7685. Py_CLEAR(tmp);
  7686. }
  7687. *out = SetComp(elt, generators, lineno, col_offset, end_lineno,
  7688. end_col_offset, arena);
  7689. if (*out == NULL) goto failed;
  7690. return 0;
  7691. }
  7692. tp = astmodulestate_global->DictComp_type;
  7693. isinstance = PyObject_IsInstance(obj, tp);
  7694. if (isinstance == -1) {
  7695. return 1;
  7696. }
  7697. if (isinstance) {
  7698. expr_ty key;
  7699. expr_ty value;
  7700. asdl_seq* generators;
  7701. if (_PyObject_LookupAttr(obj, astmodulestate_global->key, &tmp) < 0) {
  7702. return 1;
  7703. }
  7704. if (tmp == NULL) {
  7705. PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp");
  7706. return 1;
  7707. }
  7708. else {
  7709. int res;
  7710. res = obj2ast_expr(tmp, &key, arena);
  7711. if (res != 0) goto failed;
  7712. Py_CLEAR(tmp);
  7713. }
  7714. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  7715. return 1;
  7716. }
  7717. if (tmp == NULL) {
  7718. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp");
  7719. return 1;
  7720. }
  7721. else {
  7722. int res;
  7723. res = obj2ast_expr(tmp, &value, arena);
  7724. if (res != 0) goto failed;
  7725. Py_CLEAR(tmp);
  7726. }
  7727. if (_PyObject_LookupAttr(obj, astmodulestate_global->generators, &tmp)
  7728. < 0) {
  7729. return 1;
  7730. }
  7731. if (tmp == NULL) {
  7732. PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from DictComp");
  7733. return 1;
  7734. }
  7735. else {
  7736. int res;
  7737. Py_ssize_t len;
  7738. Py_ssize_t i;
  7739. if (!PyList_Check(tmp)) {
  7740. PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7741. goto failed;
  7742. }
  7743. len = PyList_GET_SIZE(tmp);
  7744. generators = _Py_asdl_seq_new(len, arena);
  7745. if (generators == NULL) goto failed;
  7746. for (i = 0; i < len; i++) {
  7747. comprehension_ty val;
  7748. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7749. Py_INCREF(tmp2);
  7750. res = obj2ast_comprehension(tmp2, &val, arena);
  7751. Py_DECREF(tmp2);
  7752. if (res != 0) goto failed;
  7753. if (len != PyList_GET_SIZE(tmp)) {
  7754. PyErr_SetString(PyExc_RuntimeError, "DictComp field \"generators\" changed size during iteration");
  7755. goto failed;
  7756. }
  7757. asdl_seq_SET(generators, i, val);
  7758. }
  7759. Py_CLEAR(tmp);
  7760. }
  7761. *out = DictComp(key, value, generators, lineno, col_offset, end_lineno,
  7762. end_col_offset, arena);
  7763. if (*out == NULL) goto failed;
  7764. return 0;
  7765. }
  7766. tp = astmodulestate_global->GeneratorExp_type;
  7767. isinstance = PyObject_IsInstance(obj, tp);
  7768. if (isinstance == -1) {
  7769. return 1;
  7770. }
  7771. if (isinstance) {
  7772. expr_ty elt;
  7773. asdl_seq* generators;
  7774. if (_PyObject_LookupAttr(obj, astmodulestate_global->elt, &tmp) < 0) {
  7775. return 1;
  7776. }
  7777. if (tmp == NULL) {
  7778. PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp");
  7779. return 1;
  7780. }
  7781. else {
  7782. int res;
  7783. res = obj2ast_expr(tmp, &elt, arena);
  7784. if (res != 0) goto failed;
  7785. Py_CLEAR(tmp);
  7786. }
  7787. if (_PyObject_LookupAttr(obj, astmodulestate_global->generators, &tmp)
  7788. < 0) {
  7789. return 1;
  7790. }
  7791. if (tmp == NULL) {
  7792. PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from GeneratorExp");
  7793. return 1;
  7794. }
  7795. else {
  7796. int res;
  7797. Py_ssize_t len;
  7798. Py_ssize_t i;
  7799. if (!PyList_Check(tmp)) {
  7800. PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7801. goto failed;
  7802. }
  7803. len = PyList_GET_SIZE(tmp);
  7804. generators = _Py_asdl_seq_new(len, arena);
  7805. if (generators == NULL) goto failed;
  7806. for (i = 0; i < len; i++) {
  7807. comprehension_ty val;
  7808. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7809. Py_INCREF(tmp2);
  7810. res = obj2ast_comprehension(tmp2, &val, arena);
  7811. Py_DECREF(tmp2);
  7812. if (res != 0) goto failed;
  7813. if (len != PyList_GET_SIZE(tmp)) {
  7814. PyErr_SetString(PyExc_RuntimeError, "GeneratorExp field \"generators\" changed size during iteration");
  7815. goto failed;
  7816. }
  7817. asdl_seq_SET(generators, i, val);
  7818. }
  7819. Py_CLEAR(tmp);
  7820. }
  7821. *out = GeneratorExp(elt, generators, lineno, col_offset, end_lineno,
  7822. end_col_offset, arena);
  7823. if (*out == NULL) goto failed;
  7824. return 0;
  7825. }
  7826. tp = astmodulestate_global->Await_type;
  7827. isinstance = PyObject_IsInstance(obj, tp);
  7828. if (isinstance == -1) {
  7829. return 1;
  7830. }
  7831. if (isinstance) {
  7832. expr_ty value;
  7833. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  7834. return 1;
  7835. }
  7836. if (tmp == NULL) {
  7837. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await");
  7838. return 1;
  7839. }
  7840. else {
  7841. int res;
  7842. res = obj2ast_expr(tmp, &value, arena);
  7843. if (res != 0) goto failed;
  7844. Py_CLEAR(tmp);
  7845. }
  7846. *out = Await(value, lineno, col_offset, end_lineno, end_col_offset,
  7847. arena);
  7848. if (*out == NULL) goto failed;
  7849. return 0;
  7850. }
  7851. tp = astmodulestate_global->Yield_type;
  7852. isinstance = PyObject_IsInstance(obj, tp);
  7853. if (isinstance == -1) {
  7854. return 1;
  7855. }
  7856. if (isinstance) {
  7857. expr_ty value;
  7858. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  7859. return 1;
  7860. }
  7861. if (tmp == NULL || tmp == Py_None) {
  7862. Py_CLEAR(tmp);
  7863. value = NULL;
  7864. }
  7865. else {
  7866. int res;
  7867. res = obj2ast_expr(tmp, &value, arena);
  7868. if (res != 0) goto failed;
  7869. Py_CLEAR(tmp);
  7870. }
  7871. *out = Yield(value, lineno, col_offset, end_lineno, end_col_offset,
  7872. arena);
  7873. if (*out == NULL) goto failed;
  7874. return 0;
  7875. }
  7876. tp = astmodulestate_global->YieldFrom_type;
  7877. isinstance = PyObject_IsInstance(obj, tp);
  7878. if (isinstance == -1) {
  7879. return 1;
  7880. }
  7881. if (isinstance) {
  7882. expr_ty value;
  7883. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  7884. return 1;
  7885. }
  7886. if (tmp == NULL) {
  7887. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom");
  7888. return 1;
  7889. }
  7890. else {
  7891. int res;
  7892. res = obj2ast_expr(tmp, &value, arena);
  7893. if (res != 0) goto failed;
  7894. Py_CLEAR(tmp);
  7895. }
  7896. *out = YieldFrom(value, lineno, col_offset, end_lineno, end_col_offset,
  7897. arena);
  7898. if (*out == NULL) goto failed;
  7899. return 0;
  7900. }
  7901. tp = astmodulestate_global->Compare_type;
  7902. isinstance = PyObject_IsInstance(obj, tp);
  7903. if (isinstance == -1) {
  7904. return 1;
  7905. }
  7906. if (isinstance) {
  7907. expr_ty left;
  7908. asdl_int_seq* ops;
  7909. asdl_seq* comparators;
  7910. if (_PyObject_LookupAttr(obj, astmodulestate_global->left, &tmp) < 0) {
  7911. return 1;
  7912. }
  7913. if (tmp == NULL) {
  7914. PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare");
  7915. return 1;
  7916. }
  7917. else {
  7918. int res;
  7919. res = obj2ast_expr(tmp, &left, arena);
  7920. if (res != 0) goto failed;
  7921. Py_CLEAR(tmp);
  7922. }
  7923. if (_PyObject_LookupAttr(obj, astmodulestate_global->ops, &tmp) < 0) {
  7924. return 1;
  7925. }
  7926. if (tmp == NULL) {
  7927. PyErr_SetString(PyExc_TypeError, "required field \"ops\" missing from Compare");
  7928. return 1;
  7929. }
  7930. else {
  7931. int res;
  7932. Py_ssize_t len;
  7933. Py_ssize_t i;
  7934. if (!PyList_Check(tmp)) {
  7935. PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7936. goto failed;
  7937. }
  7938. len = PyList_GET_SIZE(tmp);
  7939. ops = _Py_asdl_int_seq_new(len, arena);
  7940. if (ops == NULL) goto failed;
  7941. for (i = 0; i < len; i++) {
  7942. cmpop_ty val;
  7943. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7944. Py_INCREF(tmp2);
  7945. res = obj2ast_cmpop(tmp2, &val, arena);
  7946. Py_DECREF(tmp2);
  7947. if (res != 0) goto failed;
  7948. if (len != PyList_GET_SIZE(tmp)) {
  7949. PyErr_SetString(PyExc_RuntimeError, "Compare field \"ops\" changed size during iteration");
  7950. goto failed;
  7951. }
  7952. asdl_seq_SET(ops, i, val);
  7953. }
  7954. Py_CLEAR(tmp);
  7955. }
  7956. if (_PyObject_LookupAttr(obj, astmodulestate_global->comparators, &tmp)
  7957. < 0) {
  7958. return 1;
  7959. }
  7960. if (tmp == NULL) {
  7961. PyErr_SetString(PyExc_TypeError, "required field \"comparators\" missing from Compare");
  7962. return 1;
  7963. }
  7964. else {
  7965. int res;
  7966. Py_ssize_t len;
  7967. Py_ssize_t i;
  7968. if (!PyList_Check(tmp)) {
  7969. PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  7970. goto failed;
  7971. }
  7972. len = PyList_GET_SIZE(tmp);
  7973. comparators = _Py_asdl_seq_new(len, arena);
  7974. if (comparators == NULL) goto failed;
  7975. for (i = 0; i < len; i++) {
  7976. expr_ty val;
  7977. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  7978. Py_INCREF(tmp2);
  7979. res = obj2ast_expr(tmp2, &val, arena);
  7980. Py_DECREF(tmp2);
  7981. if (res != 0) goto failed;
  7982. if (len != PyList_GET_SIZE(tmp)) {
  7983. PyErr_SetString(PyExc_RuntimeError, "Compare field \"comparators\" changed size during iteration");
  7984. goto failed;
  7985. }
  7986. asdl_seq_SET(comparators, i, val);
  7987. }
  7988. Py_CLEAR(tmp);
  7989. }
  7990. *out = Compare(left, ops, comparators, lineno, col_offset, end_lineno,
  7991. end_col_offset, arena);
  7992. if (*out == NULL) goto failed;
  7993. return 0;
  7994. }
  7995. tp = astmodulestate_global->Call_type;
  7996. isinstance = PyObject_IsInstance(obj, tp);
  7997. if (isinstance == -1) {
  7998. return 1;
  7999. }
  8000. if (isinstance) {
  8001. expr_ty func;
  8002. asdl_seq* args;
  8003. asdl_seq* keywords;
  8004. if (_PyObject_LookupAttr(obj, astmodulestate_global->func, &tmp) < 0) {
  8005. return 1;
  8006. }
  8007. if (tmp == NULL) {
  8008. PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call");
  8009. return 1;
  8010. }
  8011. else {
  8012. int res;
  8013. res = obj2ast_expr(tmp, &func, arena);
  8014. if (res != 0) goto failed;
  8015. Py_CLEAR(tmp);
  8016. }
  8017. if (_PyObject_LookupAttr(obj, astmodulestate_global->args, &tmp) < 0) {
  8018. return 1;
  8019. }
  8020. if (tmp == NULL) {
  8021. PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Call");
  8022. return 1;
  8023. }
  8024. else {
  8025. int res;
  8026. Py_ssize_t len;
  8027. Py_ssize_t i;
  8028. if (!PyList_Check(tmp)) {
  8029. PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  8030. goto failed;
  8031. }
  8032. len = PyList_GET_SIZE(tmp);
  8033. args = _Py_asdl_seq_new(len, arena);
  8034. if (args == NULL) goto failed;
  8035. for (i = 0; i < len; i++) {
  8036. expr_ty val;
  8037. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  8038. Py_INCREF(tmp2);
  8039. res = obj2ast_expr(tmp2, &val, arena);
  8040. Py_DECREF(tmp2);
  8041. if (res != 0) goto failed;
  8042. if (len != PyList_GET_SIZE(tmp)) {
  8043. PyErr_SetString(PyExc_RuntimeError, "Call field \"args\" changed size during iteration");
  8044. goto failed;
  8045. }
  8046. asdl_seq_SET(args, i, val);
  8047. }
  8048. Py_CLEAR(tmp);
  8049. }
  8050. if (_PyObject_LookupAttr(obj, astmodulestate_global->keywords, &tmp) <
  8051. 0) {
  8052. return 1;
  8053. }
  8054. if (tmp == NULL) {
  8055. PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call");
  8056. return 1;
  8057. }
  8058. else {
  8059. int res;
  8060. Py_ssize_t len;
  8061. Py_ssize_t i;
  8062. if (!PyList_Check(tmp)) {
  8063. PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  8064. goto failed;
  8065. }
  8066. len = PyList_GET_SIZE(tmp);
  8067. keywords = _Py_asdl_seq_new(len, arena);
  8068. if (keywords == NULL) goto failed;
  8069. for (i = 0; i < len; i++) {
  8070. keyword_ty val;
  8071. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  8072. Py_INCREF(tmp2);
  8073. res = obj2ast_keyword(tmp2, &val, arena);
  8074. Py_DECREF(tmp2);
  8075. if (res != 0) goto failed;
  8076. if (len != PyList_GET_SIZE(tmp)) {
  8077. PyErr_SetString(PyExc_RuntimeError, "Call field \"keywords\" changed size during iteration");
  8078. goto failed;
  8079. }
  8080. asdl_seq_SET(keywords, i, val);
  8081. }
  8082. Py_CLEAR(tmp);
  8083. }
  8084. *out = Call(func, args, keywords, lineno, col_offset, end_lineno,
  8085. end_col_offset, arena);
  8086. if (*out == NULL) goto failed;
  8087. return 0;
  8088. }
  8089. tp = astmodulestate_global->FormattedValue_type;
  8090. isinstance = PyObject_IsInstance(obj, tp);
  8091. if (isinstance == -1) {
  8092. return 1;
  8093. }
  8094. if (isinstance) {
  8095. expr_ty value;
  8096. int conversion;
  8097. expr_ty format_spec;
  8098. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  8099. return 1;
  8100. }
  8101. if (tmp == NULL) {
  8102. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue");
  8103. return 1;
  8104. }
  8105. else {
  8106. int res;
  8107. res = obj2ast_expr(tmp, &value, arena);
  8108. if (res != 0) goto failed;
  8109. Py_CLEAR(tmp);
  8110. }
  8111. if (_PyObject_LookupAttr(obj, astmodulestate_global->conversion, &tmp)
  8112. < 0) {
  8113. return 1;
  8114. }
  8115. if (tmp == NULL || tmp == Py_None) {
  8116. Py_CLEAR(tmp);
  8117. conversion = 0;
  8118. }
  8119. else {
  8120. int res;
  8121. res = obj2ast_int(tmp, &conversion, arena);
  8122. if (res != 0) goto failed;
  8123. Py_CLEAR(tmp);
  8124. }
  8125. if (_PyObject_LookupAttr(obj, astmodulestate_global->format_spec, &tmp)
  8126. < 0) {
  8127. return 1;
  8128. }
  8129. if (tmp == NULL || tmp == Py_None) {
  8130. Py_CLEAR(tmp);
  8131. format_spec = NULL;
  8132. }
  8133. else {
  8134. int res;
  8135. res = obj2ast_expr(tmp, &format_spec, arena);
  8136. if (res != 0) goto failed;
  8137. Py_CLEAR(tmp);
  8138. }
  8139. *out = FormattedValue(value, conversion, format_spec, lineno,
  8140. col_offset, end_lineno, end_col_offset, arena);
  8141. if (*out == NULL) goto failed;
  8142. return 0;
  8143. }
  8144. tp = astmodulestate_global->JoinedStr_type;
  8145. isinstance = PyObject_IsInstance(obj, tp);
  8146. if (isinstance == -1) {
  8147. return 1;
  8148. }
  8149. if (isinstance) {
  8150. asdl_seq* values;
  8151. if (_PyObject_LookupAttr(obj, astmodulestate_global->values, &tmp) < 0)
  8152. {
  8153. return 1;
  8154. }
  8155. if (tmp == NULL) {
  8156. PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from JoinedStr");
  8157. return 1;
  8158. }
  8159. else {
  8160. int res;
  8161. Py_ssize_t len;
  8162. Py_ssize_t i;
  8163. if (!PyList_Check(tmp)) {
  8164. PyErr_Format(PyExc_TypeError, "JoinedStr field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  8165. goto failed;
  8166. }
  8167. len = PyList_GET_SIZE(tmp);
  8168. values = _Py_asdl_seq_new(len, arena);
  8169. if (values == NULL) goto failed;
  8170. for (i = 0; i < len; i++) {
  8171. expr_ty val;
  8172. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  8173. Py_INCREF(tmp2);
  8174. res = obj2ast_expr(tmp2, &val, arena);
  8175. Py_DECREF(tmp2);
  8176. if (res != 0) goto failed;
  8177. if (len != PyList_GET_SIZE(tmp)) {
  8178. PyErr_SetString(PyExc_RuntimeError, "JoinedStr field \"values\" changed size during iteration");
  8179. goto failed;
  8180. }
  8181. asdl_seq_SET(values, i, val);
  8182. }
  8183. Py_CLEAR(tmp);
  8184. }
  8185. *out = JoinedStr(values, lineno, col_offset, end_lineno,
  8186. end_col_offset, arena);
  8187. if (*out == NULL) goto failed;
  8188. return 0;
  8189. }
  8190. tp = astmodulestate_global->Constant_type;
  8191. isinstance = PyObject_IsInstance(obj, tp);
  8192. if (isinstance == -1) {
  8193. return 1;
  8194. }
  8195. if (isinstance) {
  8196. constant value;
  8197. string kind;
  8198. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  8199. return 1;
  8200. }
  8201. if (tmp == NULL) {
  8202. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Constant");
  8203. return 1;
  8204. }
  8205. else {
  8206. int res;
  8207. res = obj2ast_constant(tmp, &value, arena);
  8208. if (res != 0) goto failed;
  8209. Py_CLEAR(tmp);
  8210. }
  8211. if (_PyObject_LookupAttr(obj, astmodulestate_global->kind, &tmp) < 0) {
  8212. return 1;
  8213. }
  8214. if (tmp == NULL || tmp == Py_None) {
  8215. Py_CLEAR(tmp);
  8216. kind = NULL;
  8217. }
  8218. else {
  8219. int res;
  8220. res = obj2ast_string(tmp, &kind, arena);
  8221. if (res != 0) goto failed;
  8222. Py_CLEAR(tmp);
  8223. }
  8224. *out = Constant(value, kind, lineno, col_offset, end_lineno,
  8225. end_col_offset, arena);
  8226. if (*out == NULL) goto failed;
  8227. return 0;
  8228. }
  8229. tp = astmodulestate_global->Attribute_type;
  8230. isinstance = PyObject_IsInstance(obj, tp);
  8231. if (isinstance == -1) {
  8232. return 1;
  8233. }
  8234. if (isinstance) {
  8235. expr_ty value;
  8236. identifier attr;
  8237. expr_context_ty ctx;
  8238. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  8239. return 1;
  8240. }
  8241. if (tmp == NULL) {
  8242. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute");
  8243. return 1;
  8244. }
  8245. else {
  8246. int res;
  8247. res = obj2ast_expr(tmp, &value, arena);
  8248. if (res != 0) goto failed;
  8249. Py_CLEAR(tmp);
  8250. }
  8251. if (_PyObject_LookupAttr(obj, astmodulestate_global->attr, &tmp) < 0) {
  8252. return 1;
  8253. }
  8254. if (tmp == NULL) {
  8255. PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute");
  8256. return 1;
  8257. }
  8258. else {
  8259. int res;
  8260. res = obj2ast_identifier(tmp, &attr, arena);
  8261. if (res != 0) goto failed;
  8262. Py_CLEAR(tmp);
  8263. }
  8264. if (_PyObject_LookupAttr(obj, astmodulestate_global->ctx, &tmp) < 0) {
  8265. return 1;
  8266. }
  8267. if (tmp == NULL) {
  8268. PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Attribute");
  8269. return 1;
  8270. }
  8271. else {
  8272. int res;
  8273. res = obj2ast_expr_context(tmp, &ctx, arena);
  8274. if (res != 0) goto failed;
  8275. Py_CLEAR(tmp);
  8276. }
  8277. *out = Attribute(value, attr, ctx, lineno, col_offset, end_lineno,
  8278. end_col_offset, arena);
  8279. if (*out == NULL) goto failed;
  8280. return 0;
  8281. }
  8282. tp = astmodulestate_global->Subscript_type;
  8283. isinstance = PyObject_IsInstance(obj, tp);
  8284. if (isinstance == -1) {
  8285. return 1;
  8286. }
  8287. if (isinstance) {
  8288. expr_ty value;
  8289. expr_ty slice;
  8290. expr_context_ty ctx;
  8291. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  8292. return 1;
  8293. }
  8294. if (tmp == NULL) {
  8295. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript");
  8296. return 1;
  8297. }
  8298. else {
  8299. int res;
  8300. res = obj2ast_expr(tmp, &value, arena);
  8301. if (res != 0) goto failed;
  8302. Py_CLEAR(tmp);
  8303. }
  8304. if (_PyObject_LookupAttr(obj, astmodulestate_global->slice, &tmp) < 0) {
  8305. return 1;
  8306. }
  8307. if (tmp == NULL) {
  8308. PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript");
  8309. return 1;
  8310. }
  8311. else {
  8312. int res;
  8313. res = obj2ast_expr(tmp, &slice, arena);
  8314. if (res != 0) goto failed;
  8315. Py_CLEAR(tmp);
  8316. }
  8317. if (_PyObject_LookupAttr(obj, astmodulestate_global->ctx, &tmp) < 0) {
  8318. return 1;
  8319. }
  8320. if (tmp == NULL) {
  8321. PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Subscript");
  8322. return 1;
  8323. }
  8324. else {
  8325. int res;
  8326. res = obj2ast_expr_context(tmp, &ctx, arena);
  8327. if (res != 0) goto failed;
  8328. Py_CLEAR(tmp);
  8329. }
  8330. *out = Subscript(value, slice, ctx, lineno, col_offset, end_lineno,
  8331. end_col_offset, arena);
  8332. if (*out == NULL) goto failed;
  8333. return 0;
  8334. }
  8335. tp = astmodulestate_global->Starred_type;
  8336. isinstance = PyObject_IsInstance(obj, tp);
  8337. if (isinstance == -1) {
  8338. return 1;
  8339. }
  8340. if (isinstance) {
  8341. expr_ty value;
  8342. expr_context_ty ctx;
  8343. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  8344. return 1;
  8345. }
  8346. if (tmp == NULL) {
  8347. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred");
  8348. return 1;
  8349. }
  8350. else {
  8351. int res;
  8352. res = obj2ast_expr(tmp, &value, arena);
  8353. if (res != 0) goto failed;
  8354. Py_CLEAR(tmp);
  8355. }
  8356. if (_PyObject_LookupAttr(obj, astmodulestate_global->ctx, &tmp) < 0) {
  8357. return 1;
  8358. }
  8359. if (tmp == NULL) {
  8360. PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred");
  8361. return 1;
  8362. }
  8363. else {
  8364. int res;
  8365. res = obj2ast_expr_context(tmp, &ctx, arena);
  8366. if (res != 0) goto failed;
  8367. Py_CLEAR(tmp);
  8368. }
  8369. *out = Starred(value, ctx, lineno, col_offset, end_lineno,
  8370. end_col_offset, arena);
  8371. if (*out == NULL) goto failed;
  8372. return 0;
  8373. }
  8374. tp = astmodulestate_global->Name_type;
  8375. isinstance = PyObject_IsInstance(obj, tp);
  8376. if (isinstance == -1) {
  8377. return 1;
  8378. }
  8379. if (isinstance) {
  8380. identifier id;
  8381. expr_context_ty ctx;
  8382. if (_PyObject_LookupAttr(obj, astmodulestate_global->id, &tmp) < 0) {
  8383. return 1;
  8384. }
  8385. if (tmp == NULL) {
  8386. PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name");
  8387. return 1;
  8388. }
  8389. else {
  8390. int res;
  8391. res = obj2ast_identifier(tmp, &id, arena);
  8392. if (res != 0) goto failed;
  8393. Py_CLEAR(tmp);
  8394. }
  8395. if (_PyObject_LookupAttr(obj, astmodulestate_global->ctx, &tmp) < 0) {
  8396. return 1;
  8397. }
  8398. if (tmp == NULL) {
  8399. PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Name");
  8400. return 1;
  8401. }
  8402. else {
  8403. int res;
  8404. res = obj2ast_expr_context(tmp, &ctx, arena);
  8405. if (res != 0) goto failed;
  8406. Py_CLEAR(tmp);
  8407. }
  8408. *out = Name(id, ctx, lineno, col_offset, end_lineno, end_col_offset,
  8409. arena);
  8410. if (*out == NULL) goto failed;
  8411. return 0;
  8412. }
  8413. tp = astmodulestate_global->List_type;
  8414. isinstance = PyObject_IsInstance(obj, tp);
  8415. if (isinstance == -1) {
  8416. return 1;
  8417. }
  8418. if (isinstance) {
  8419. asdl_seq* elts;
  8420. expr_context_ty ctx;
  8421. if (_PyObject_LookupAttr(obj, astmodulestate_global->elts, &tmp) < 0) {
  8422. return 1;
  8423. }
  8424. if (tmp == NULL) {
  8425. PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from List");
  8426. return 1;
  8427. }
  8428. else {
  8429. int res;
  8430. Py_ssize_t len;
  8431. Py_ssize_t i;
  8432. if (!PyList_Check(tmp)) {
  8433. PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  8434. goto failed;
  8435. }
  8436. len = PyList_GET_SIZE(tmp);
  8437. elts = _Py_asdl_seq_new(len, arena);
  8438. if (elts == NULL) goto failed;
  8439. for (i = 0; i < len; i++) {
  8440. expr_ty val;
  8441. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  8442. Py_INCREF(tmp2);
  8443. res = obj2ast_expr(tmp2, &val, arena);
  8444. Py_DECREF(tmp2);
  8445. if (res != 0) goto failed;
  8446. if (len != PyList_GET_SIZE(tmp)) {
  8447. PyErr_SetString(PyExc_RuntimeError, "List field \"elts\" changed size during iteration");
  8448. goto failed;
  8449. }
  8450. asdl_seq_SET(elts, i, val);
  8451. }
  8452. Py_CLEAR(tmp);
  8453. }
  8454. if (_PyObject_LookupAttr(obj, astmodulestate_global->ctx, &tmp) < 0) {
  8455. return 1;
  8456. }
  8457. if (tmp == NULL) {
  8458. PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from List");
  8459. return 1;
  8460. }
  8461. else {
  8462. int res;
  8463. res = obj2ast_expr_context(tmp, &ctx, arena);
  8464. if (res != 0) goto failed;
  8465. Py_CLEAR(tmp);
  8466. }
  8467. *out = List(elts, ctx, lineno, col_offset, end_lineno, end_col_offset,
  8468. arena);
  8469. if (*out == NULL) goto failed;
  8470. return 0;
  8471. }
  8472. tp = astmodulestate_global->Tuple_type;
  8473. isinstance = PyObject_IsInstance(obj, tp);
  8474. if (isinstance == -1) {
  8475. return 1;
  8476. }
  8477. if (isinstance) {
  8478. asdl_seq* elts;
  8479. expr_context_ty ctx;
  8480. if (_PyObject_LookupAttr(obj, astmodulestate_global->elts, &tmp) < 0) {
  8481. return 1;
  8482. }
  8483. if (tmp == NULL) {
  8484. PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Tuple");
  8485. return 1;
  8486. }
  8487. else {
  8488. int res;
  8489. Py_ssize_t len;
  8490. Py_ssize_t i;
  8491. if (!PyList_Check(tmp)) {
  8492. PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  8493. goto failed;
  8494. }
  8495. len = PyList_GET_SIZE(tmp);
  8496. elts = _Py_asdl_seq_new(len, arena);
  8497. if (elts == NULL) goto failed;
  8498. for (i = 0; i < len; i++) {
  8499. expr_ty val;
  8500. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  8501. Py_INCREF(tmp2);
  8502. res = obj2ast_expr(tmp2, &val, arena);
  8503. Py_DECREF(tmp2);
  8504. if (res != 0) goto failed;
  8505. if (len != PyList_GET_SIZE(tmp)) {
  8506. PyErr_SetString(PyExc_RuntimeError, "Tuple field \"elts\" changed size during iteration");
  8507. goto failed;
  8508. }
  8509. asdl_seq_SET(elts, i, val);
  8510. }
  8511. Py_CLEAR(tmp);
  8512. }
  8513. if (_PyObject_LookupAttr(obj, astmodulestate_global->ctx, &tmp) < 0) {
  8514. return 1;
  8515. }
  8516. if (tmp == NULL) {
  8517. PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Tuple");
  8518. return 1;
  8519. }
  8520. else {
  8521. int res;
  8522. res = obj2ast_expr_context(tmp, &ctx, arena);
  8523. if (res != 0) goto failed;
  8524. Py_CLEAR(tmp);
  8525. }
  8526. *out = Tuple(elts, ctx, lineno, col_offset, end_lineno, end_col_offset,
  8527. arena);
  8528. if (*out == NULL) goto failed;
  8529. return 0;
  8530. }
  8531. tp = astmodulestate_global->Slice_type;
  8532. isinstance = PyObject_IsInstance(obj, tp);
  8533. if (isinstance == -1) {
  8534. return 1;
  8535. }
  8536. if (isinstance) {
  8537. expr_ty lower;
  8538. expr_ty upper;
  8539. expr_ty step;
  8540. if (_PyObject_LookupAttr(obj, astmodulestate_global->lower, &tmp) < 0) {
  8541. return 1;
  8542. }
  8543. if (tmp == NULL || tmp == Py_None) {
  8544. Py_CLEAR(tmp);
  8545. lower = NULL;
  8546. }
  8547. else {
  8548. int res;
  8549. res = obj2ast_expr(tmp, &lower, arena);
  8550. if (res != 0) goto failed;
  8551. Py_CLEAR(tmp);
  8552. }
  8553. if (_PyObject_LookupAttr(obj, astmodulestate_global->upper, &tmp) < 0) {
  8554. return 1;
  8555. }
  8556. if (tmp == NULL || tmp == Py_None) {
  8557. Py_CLEAR(tmp);
  8558. upper = NULL;
  8559. }
  8560. else {
  8561. int res;
  8562. res = obj2ast_expr(tmp, &upper, arena);
  8563. if (res != 0) goto failed;
  8564. Py_CLEAR(tmp);
  8565. }
  8566. if (_PyObject_LookupAttr(obj, astmodulestate_global->step, &tmp) < 0) {
  8567. return 1;
  8568. }
  8569. if (tmp == NULL || tmp == Py_None) {
  8570. Py_CLEAR(tmp);
  8571. step = NULL;
  8572. }
  8573. else {
  8574. int res;
  8575. res = obj2ast_expr(tmp, &step, arena);
  8576. if (res != 0) goto failed;
  8577. Py_CLEAR(tmp);
  8578. }
  8579. *out = Slice(lower, upper, step, lineno, col_offset, end_lineno,
  8580. end_col_offset, arena);
  8581. if (*out == NULL) goto failed;
  8582. return 0;
  8583. }
  8584. PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj);
  8585. failed:
  8586. Py_XDECREF(tmp);
  8587. return 1;
  8588. }
  8589. int
  8590. obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena)
  8591. {
  8592. int isinstance;
  8593. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Load_type);
  8594. if (isinstance == -1) {
  8595. return 1;
  8596. }
  8597. if (isinstance) {
  8598. *out = Load;
  8599. return 0;
  8600. }
  8601. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Store_type);
  8602. if (isinstance == -1) {
  8603. return 1;
  8604. }
  8605. if (isinstance) {
  8606. *out = Store;
  8607. return 0;
  8608. }
  8609. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Del_type);
  8610. if (isinstance == -1) {
  8611. return 1;
  8612. }
  8613. if (isinstance) {
  8614. *out = Del;
  8615. return 0;
  8616. }
  8617. PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
  8618. return 1;
  8619. }
  8620. int
  8621. obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena)
  8622. {
  8623. int isinstance;
  8624. isinstance = PyObject_IsInstance(obj, astmodulestate_global->And_type);
  8625. if (isinstance == -1) {
  8626. return 1;
  8627. }
  8628. if (isinstance) {
  8629. *out = And;
  8630. return 0;
  8631. }
  8632. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Or_type);
  8633. if (isinstance == -1) {
  8634. return 1;
  8635. }
  8636. if (isinstance) {
  8637. *out = Or;
  8638. return 0;
  8639. }
  8640. PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %R", obj);
  8641. return 1;
  8642. }
  8643. int
  8644. obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena)
  8645. {
  8646. int isinstance;
  8647. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Add_type);
  8648. if (isinstance == -1) {
  8649. return 1;
  8650. }
  8651. if (isinstance) {
  8652. *out = Add;
  8653. return 0;
  8654. }
  8655. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Sub_type);
  8656. if (isinstance == -1) {
  8657. return 1;
  8658. }
  8659. if (isinstance) {
  8660. *out = Sub;
  8661. return 0;
  8662. }
  8663. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Mult_type);
  8664. if (isinstance == -1) {
  8665. return 1;
  8666. }
  8667. if (isinstance) {
  8668. *out = Mult;
  8669. return 0;
  8670. }
  8671. isinstance = PyObject_IsInstance(obj, astmodulestate_global->MatMult_type);
  8672. if (isinstance == -1) {
  8673. return 1;
  8674. }
  8675. if (isinstance) {
  8676. *out = MatMult;
  8677. return 0;
  8678. }
  8679. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Div_type);
  8680. if (isinstance == -1) {
  8681. return 1;
  8682. }
  8683. if (isinstance) {
  8684. *out = Div;
  8685. return 0;
  8686. }
  8687. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Mod_type);
  8688. if (isinstance == -1) {
  8689. return 1;
  8690. }
  8691. if (isinstance) {
  8692. *out = Mod;
  8693. return 0;
  8694. }
  8695. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Pow_type);
  8696. if (isinstance == -1) {
  8697. return 1;
  8698. }
  8699. if (isinstance) {
  8700. *out = Pow;
  8701. return 0;
  8702. }
  8703. isinstance = PyObject_IsInstance(obj, astmodulestate_global->LShift_type);
  8704. if (isinstance == -1) {
  8705. return 1;
  8706. }
  8707. if (isinstance) {
  8708. *out = LShift;
  8709. return 0;
  8710. }
  8711. isinstance = PyObject_IsInstance(obj, astmodulestate_global->RShift_type);
  8712. if (isinstance == -1) {
  8713. return 1;
  8714. }
  8715. if (isinstance) {
  8716. *out = RShift;
  8717. return 0;
  8718. }
  8719. isinstance = PyObject_IsInstance(obj, astmodulestate_global->BitOr_type);
  8720. if (isinstance == -1) {
  8721. return 1;
  8722. }
  8723. if (isinstance) {
  8724. *out = BitOr;
  8725. return 0;
  8726. }
  8727. isinstance = PyObject_IsInstance(obj, astmodulestate_global->BitXor_type);
  8728. if (isinstance == -1) {
  8729. return 1;
  8730. }
  8731. if (isinstance) {
  8732. *out = BitXor;
  8733. return 0;
  8734. }
  8735. isinstance = PyObject_IsInstance(obj, astmodulestate_global->BitAnd_type);
  8736. if (isinstance == -1) {
  8737. return 1;
  8738. }
  8739. if (isinstance) {
  8740. *out = BitAnd;
  8741. return 0;
  8742. }
  8743. isinstance = PyObject_IsInstance(obj, astmodulestate_global->FloorDiv_type);
  8744. if (isinstance == -1) {
  8745. return 1;
  8746. }
  8747. if (isinstance) {
  8748. *out = FloorDiv;
  8749. return 0;
  8750. }
  8751. PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %R", obj);
  8752. return 1;
  8753. }
  8754. int
  8755. obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena)
  8756. {
  8757. int isinstance;
  8758. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Invert_type);
  8759. if (isinstance == -1) {
  8760. return 1;
  8761. }
  8762. if (isinstance) {
  8763. *out = Invert;
  8764. return 0;
  8765. }
  8766. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Not_type);
  8767. if (isinstance == -1) {
  8768. return 1;
  8769. }
  8770. if (isinstance) {
  8771. *out = Not;
  8772. return 0;
  8773. }
  8774. isinstance = PyObject_IsInstance(obj, astmodulestate_global->UAdd_type);
  8775. if (isinstance == -1) {
  8776. return 1;
  8777. }
  8778. if (isinstance) {
  8779. *out = UAdd;
  8780. return 0;
  8781. }
  8782. isinstance = PyObject_IsInstance(obj, astmodulestate_global->USub_type);
  8783. if (isinstance == -1) {
  8784. return 1;
  8785. }
  8786. if (isinstance) {
  8787. *out = USub;
  8788. return 0;
  8789. }
  8790. PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %R", obj);
  8791. return 1;
  8792. }
  8793. int
  8794. obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena)
  8795. {
  8796. int isinstance;
  8797. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Eq_type);
  8798. if (isinstance == -1) {
  8799. return 1;
  8800. }
  8801. if (isinstance) {
  8802. *out = Eq;
  8803. return 0;
  8804. }
  8805. isinstance = PyObject_IsInstance(obj, astmodulestate_global->NotEq_type);
  8806. if (isinstance == -1) {
  8807. return 1;
  8808. }
  8809. if (isinstance) {
  8810. *out = NotEq;
  8811. return 0;
  8812. }
  8813. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Lt_type);
  8814. if (isinstance == -1) {
  8815. return 1;
  8816. }
  8817. if (isinstance) {
  8818. *out = Lt;
  8819. return 0;
  8820. }
  8821. isinstance = PyObject_IsInstance(obj, astmodulestate_global->LtE_type);
  8822. if (isinstance == -1) {
  8823. return 1;
  8824. }
  8825. if (isinstance) {
  8826. *out = LtE;
  8827. return 0;
  8828. }
  8829. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Gt_type);
  8830. if (isinstance == -1) {
  8831. return 1;
  8832. }
  8833. if (isinstance) {
  8834. *out = Gt;
  8835. return 0;
  8836. }
  8837. isinstance = PyObject_IsInstance(obj, astmodulestate_global->GtE_type);
  8838. if (isinstance == -1) {
  8839. return 1;
  8840. }
  8841. if (isinstance) {
  8842. *out = GtE;
  8843. return 0;
  8844. }
  8845. isinstance = PyObject_IsInstance(obj, astmodulestate_global->Is_type);
  8846. if (isinstance == -1) {
  8847. return 1;
  8848. }
  8849. if (isinstance) {
  8850. *out = Is;
  8851. return 0;
  8852. }
  8853. isinstance = PyObject_IsInstance(obj, astmodulestate_global->IsNot_type);
  8854. if (isinstance == -1) {
  8855. return 1;
  8856. }
  8857. if (isinstance) {
  8858. *out = IsNot;
  8859. return 0;
  8860. }
  8861. isinstance = PyObject_IsInstance(obj, astmodulestate_global->In_type);
  8862. if (isinstance == -1) {
  8863. return 1;
  8864. }
  8865. if (isinstance) {
  8866. *out = In;
  8867. return 0;
  8868. }
  8869. isinstance = PyObject_IsInstance(obj, astmodulestate_global->NotIn_type);
  8870. if (isinstance == -1) {
  8871. return 1;
  8872. }
  8873. if (isinstance) {
  8874. *out = NotIn;
  8875. return 0;
  8876. }
  8877. PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %R", obj);
  8878. return 1;
  8879. }
  8880. int
  8881. obj2ast_comprehension(PyObject* obj, comprehension_ty* out, PyArena* arena)
  8882. {
  8883. PyObject* tmp = NULL;
  8884. expr_ty target;
  8885. expr_ty iter;
  8886. asdl_seq* ifs;
  8887. int is_async;
  8888. if (_PyObject_LookupAttr(obj, astmodulestate_global->target, &tmp) < 0) {
  8889. return 1;
  8890. }
  8891. if (tmp == NULL) {
  8892. PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension");
  8893. return 1;
  8894. }
  8895. else {
  8896. int res;
  8897. res = obj2ast_expr(tmp, &target, arena);
  8898. if (res != 0) goto failed;
  8899. Py_CLEAR(tmp);
  8900. }
  8901. if (_PyObject_LookupAttr(obj, astmodulestate_global->iter, &tmp) < 0) {
  8902. return 1;
  8903. }
  8904. if (tmp == NULL) {
  8905. PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension");
  8906. return 1;
  8907. }
  8908. else {
  8909. int res;
  8910. res = obj2ast_expr(tmp, &iter, arena);
  8911. if (res != 0) goto failed;
  8912. Py_CLEAR(tmp);
  8913. }
  8914. if (_PyObject_LookupAttr(obj, astmodulestate_global->ifs, &tmp) < 0) {
  8915. return 1;
  8916. }
  8917. if (tmp == NULL) {
  8918. PyErr_SetString(PyExc_TypeError, "required field \"ifs\" missing from comprehension");
  8919. return 1;
  8920. }
  8921. else {
  8922. int res;
  8923. Py_ssize_t len;
  8924. Py_ssize_t i;
  8925. if (!PyList_Check(tmp)) {
  8926. PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  8927. goto failed;
  8928. }
  8929. len = PyList_GET_SIZE(tmp);
  8930. ifs = _Py_asdl_seq_new(len, arena);
  8931. if (ifs == NULL) goto failed;
  8932. for (i = 0; i < len; i++) {
  8933. expr_ty val;
  8934. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  8935. Py_INCREF(tmp2);
  8936. res = obj2ast_expr(tmp2, &val, arena);
  8937. Py_DECREF(tmp2);
  8938. if (res != 0) goto failed;
  8939. if (len != PyList_GET_SIZE(tmp)) {
  8940. PyErr_SetString(PyExc_RuntimeError, "comprehension field \"ifs\" changed size during iteration");
  8941. goto failed;
  8942. }
  8943. asdl_seq_SET(ifs, i, val);
  8944. }
  8945. Py_CLEAR(tmp);
  8946. }
  8947. if (_PyObject_LookupAttr(obj, astmodulestate_global->is_async, &tmp) < 0) {
  8948. return 1;
  8949. }
  8950. if (tmp == NULL) {
  8951. PyErr_SetString(PyExc_TypeError, "required field \"is_async\" missing from comprehension");
  8952. return 1;
  8953. }
  8954. else {
  8955. int res;
  8956. res = obj2ast_int(tmp, &is_async, arena);
  8957. if (res != 0) goto failed;
  8958. Py_CLEAR(tmp);
  8959. }
  8960. *out = comprehension(target, iter, ifs, is_async, arena);
  8961. return 0;
  8962. failed:
  8963. Py_XDECREF(tmp);
  8964. return 1;
  8965. }
  8966. int
  8967. obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena)
  8968. {
  8969. int isinstance;
  8970. PyObject *tmp = NULL;
  8971. PyObject *tp;
  8972. int lineno;
  8973. int col_offset;
  8974. int end_lineno;
  8975. int end_col_offset;
  8976. if (obj == Py_None) {
  8977. *out = NULL;
  8978. return 0;
  8979. }
  8980. if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0) {
  8981. return 1;
  8982. }
  8983. if (tmp == NULL) {
  8984. PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler");
  8985. return 1;
  8986. }
  8987. else {
  8988. int res;
  8989. res = obj2ast_int(tmp, &lineno, arena);
  8990. if (res != 0) goto failed;
  8991. Py_CLEAR(tmp);
  8992. }
  8993. if (_PyObject_LookupAttr(obj, astmodulestate_global->col_offset, &tmp) < 0)
  8994. {
  8995. return 1;
  8996. }
  8997. if (tmp == NULL) {
  8998. PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler");
  8999. return 1;
  9000. }
  9001. else {
  9002. int res;
  9003. res = obj2ast_int(tmp, &col_offset, arena);
  9004. if (res != 0) goto failed;
  9005. Py_CLEAR(tmp);
  9006. }
  9007. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_lineno, &tmp) < 0)
  9008. {
  9009. return 1;
  9010. }
  9011. if (tmp == NULL || tmp == Py_None) {
  9012. Py_CLEAR(tmp);
  9013. end_lineno = 0;
  9014. }
  9015. else {
  9016. int res;
  9017. res = obj2ast_int(tmp, &end_lineno, arena);
  9018. if (res != 0) goto failed;
  9019. Py_CLEAR(tmp);
  9020. }
  9021. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_col_offset, &tmp)
  9022. < 0) {
  9023. return 1;
  9024. }
  9025. if (tmp == NULL || tmp == Py_None) {
  9026. Py_CLEAR(tmp);
  9027. end_col_offset = 0;
  9028. }
  9029. else {
  9030. int res;
  9031. res = obj2ast_int(tmp, &end_col_offset, arena);
  9032. if (res != 0) goto failed;
  9033. Py_CLEAR(tmp);
  9034. }
  9035. tp = astmodulestate_global->ExceptHandler_type;
  9036. isinstance = PyObject_IsInstance(obj, tp);
  9037. if (isinstance == -1) {
  9038. return 1;
  9039. }
  9040. if (isinstance) {
  9041. expr_ty type;
  9042. identifier name;
  9043. asdl_seq* body;
  9044. if (_PyObject_LookupAttr(obj, astmodulestate_global->type, &tmp) < 0) {
  9045. return 1;
  9046. }
  9047. if (tmp == NULL || tmp == Py_None) {
  9048. Py_CLEAR(tmp);
  9049. type = NULL;
  9050. }
  9051. else {
  9052. int res;
  9053. res = obj2ast_expr(tmp, &type, arena);
  9054. if (res != 0) goto failed;
  9055. Py_CLEAR(tmp);
  9056. }
  9057. if (_PyObject_LookupAttr(obj, astmodulestate_global->name, &tmp) < 0) {
  9058. return 1;
  9059. }
  9060. if (tmp == NULL || tmp == Py_None) {
  9061. Py_CLEAR(tmp);
  9062. name = NULL;
  9063. }
  9064. else {
  9065. int res;
  9066. res = obj2ast_identifier(tmp, &name, arena);
  9067. if (res != 0) goto failed;
  9068. Py_CLEAR(tmp);
  9069. }
  9070. if (_PyObject_LookupAttr(obj, astmodulestate_global->body, &tmp) < 0) {
  9071. return 1;
  9072. }
  9073. if (tmp == NULL) {
  9074. PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ExceptHandler");
  9075. return 1;
  9076. }
  9077. else {
  9078. int res;
  9079. Py_ssize_t len;
  9080. Py_ssize_t i;
  9081. if (!PyList_Check(tmp)) {
  9082. PyErr_Format(PyExc_TypeError, "ExceptHandler field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  9083. goto failed;
  9084. }
  9085. len = PyList_GET_SIZE(tmp);
  9086. body = _Py_asdl_seq_new(len, arena);
  9087. if (body == NULL) goto failed;
  9088. for (i = 0; i < len; i++) {
  9089. stmt_ty val;
  9090. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  9091. Py_INCREF(tmp2);
  9092. res = obj2ast_stmt(tmp2, &val, arena);
  9093. Py_DECREF(tmp2);
  9094. if (res != 0) goto failed;
  9095. if (len != PyList_GET_SIZE(tmp)) {
  9096. PyErr_SetString(PyExc_RuntimeError, "ExceptHandler field \"body\" changed size during iteration");
  9097. goto failed;
  9098. }
  9099. asdl_seq_SET(body, i, val);
  9100. }
  9101. Py_CLEAR(tmp);
  9102. }
  9103. *out = ExceptHandler(type, name, body, lineno, col_offset, end_lineno,
  9104. end_col_offset, arena);
  9105. if (*out == NULL) goto failed;
  9106. return 0;
  9107. }
  9108. PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %R", obj);
  9109. failed:
  9110. Py_XDECREF(tmp);
  9111. return 1;
  9112. }
  9113. int
  9114. obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena)
  9115. {
  9116. PyObject* tmp = NULL;
  9117. asdl_seq* posonlyargs;
  9118. asdl_seq* args;
  9119. arg_ty vararg;
  9120. asdl_seq* kwonlyargs;
  9121. asdl_seq* kw_defaults;
  9122. arg_ty kwarg;
  9123. asdl_seq* defaults;
  9124. if (_PyObject_LookupAttr(obj, astmodulestate_global->posonlyargs, &tmp) <
  9125. 0) {
  9126. return 1;
  9127. }
  9128. if (tmp == NULL) {
  9129. PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments");
  9130. return 1;
  9131. }
  9132. else {
  9133. int res;
  9134. Py_ssize_t len;
  9135. Py_ssize_t i;
  9136. if (!PyList_Check(tmp)) {
  9137. PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  9138. goto failed;
  9139. }
  9140. len = PyList_GET_SIZE(tmp);
  9141. posonlyargs = _Py_asdl_seq_new(len, arena);
  9142. if (posonlyargs == NULL) goto failed;
  9143. for (i = 0; i < len; i++) {
  9144. arg_ty val;
  9145. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  9146. Py_INCREF(tmp2);
  9147. res = obj2ast_arg(tmp2, &val, arena);
  9148. Py_DECREF(tmp2);
  9149. if (res != 0) goto failed;
  9150. if (len != PyList_GET_SIZE(tmp)) {
  9151. PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration");
  9152. goto failed;
  9153. }
  9154. asdl_seq_SET(posonlyargs, i, val);
  9155. }
  9156. Py_CLEAR(tmp);
  9157. }
  9158. if (_PyObject_LookupAttr(obj, astmodulestate_global->args, &tmp) < 0) {
  9159. return 1;
  9160. }
  9161. if (tmp == NULL) {
  9162. PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments");
  9163. return 1;
  9164. }
  9165. else {
  9166. int res;
  9167. Py_ssize_t len;
  9168. Py_ssize_t i;
  9169. if (!PyList_Check(tmp)) {
  9170. PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  9171. goto failed;
  9172. }
  9173. len = PyList_GET_SIZE(tmp);
  9174. args = _Py_asdl_seq_new(len, arena);
  9175. if (args == NULL) goto failed;
  9176. for (i = 0; i < len; i++) {
  9177. arg_ty val;
  9178. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  9179. Py_INCREF(tmp2);
  9180. res = obj2ast_arg(tmp2, &val, arena);
  9181. Py_DECREF(tmp2);
  9182. if (res != 0) goto failed;
  9183. if (len != PyList_GET_SIZE(tmp)) {
  9184. PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration");
  9185. goto failed;
  9186. }
  9187. asdl_seq_SET(args, i, val);
  9188. }
  9189. Py_CLEAR(tmp);
  9190. }
  9191. if (_PyObject_LookupAttr(obj, astmodulestate_global->vararg, &tmp) < 0) {
  9192. return 1;
  9193. }
  9194. if (tmp == NULL || tmp == Py_None) {
  9195. Py_CLEAR(tmp);
  9196. vararg = NULL;
  9197. }
  9198. else {
  9199. int res;
  9200. res = obj2ast_arg(tmp, &vararg, arena);
  9201. if (res != 0) goto failed;
  9202. Py_CLEAR(tmp);
  9203. }
  9204. if (_PyObject_LookupAttr(obj, astmodulestate_global->kwonlyargs, &tmp) < 0)
  9205. {
  9206. return 1;
  9207. }
  9208. if (tmp == NULL) {
  9209. PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments");
  9210. return 1;
  9211. }
  9212. else {
  9213. int res;
  9214. Py_ssize_t len;
  9215. Py_ssize_t i;
  9216. if (!PyList_Check(tmp)) {
  9217. PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  9218. goto failed;
  9219. }
  9220. len = PyList_GET_SIZE(tmp);
  9221. kwonlyargs = _Py_asdl_seq_new(len, arena);
  9222. if (kwonlyargs == NULL) goto failed;
  9223. for (i = 0; i < len; i++) {
  9224. arg_ty val;
  9225. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  9226. Py_INCREF(tmp2);
  9227. res = obj2ast_arg(tmp2, &val, arena);
  9228. Py_DECREF(tmp2);
  9229. if (res != 0) goto failed;
  9230. if (len != PyList_GET_SIZE(tmp)) {
  9231. PyErr_SetString(PyExc_RuntimeError, "arguments field \"kwonlyargs\" changed size during iteration");
  9232. goto failed;
  9233. }
  9234. asdl_seq_SET(kwonlyargs, i, val);
  9235. }
  9236. Py_CLEAR(tmp);
  9237. }
  9238. if (_PyObject_LookupAttr(obj, astmodulestate_global->kw_defaults, &tmp) <
  9239. 0) {
  9240. return 1;
  9241. }
  9242. if (tmp == NULL) {
  9243. PyErr_SetString(PyExc_TypeError, "required field \"kw_defaults\" missing from arguments");
  9244. return 1;
  9245. }
  9246. else {
  9247. int res;
  9248. Py_ssize_t len;
  9249. Py_ssize_t i;
  9250. if (!PyList_Check(tmp)) {
  9251. PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  9252. goto failed;
  9253. }
  9254. len = PyList_GET_SIZE(tmp);
  9255. kw_defaults = _Py_asdl_seq_new(len, arena);
  9256. if (kw_defaults == NULL) goto failed;
  9257. for (i = 0; i < len; i++) {
  9258. expr_ty val;
  9259. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  9260. Py_INCREF(tmp2);
  9261. res = obj2ast_expr(tmp2, &val, arena);
  9262. Py_DECREF(tmp2);
  9263. if (res != 0) goto failed;
  9264. if (len != PyList_GET_SIZE(tmp)) {
  9265. PyErr_SetString(PyExc_RuntimeError, "arguments field \"kw_defaults\" changed size during iteration");
  9266. goto failed;
  9267. }
  9268. asdl_seq_SET(kw_defaults, i, val);
  9269. }
  9270. Py_CLEAR(tmp);
  9271. }
  9272. if (_PyObject_LookupAttr(obj, astmodulestate_global->kwarg, &tmp) < 0) {
  9273. return 1;
  9274. }
  9275. if (tmp == NULL || tmp == Py_None) {
  9276. Py_CLEAR(tmp);
  9277. kwarg = NULL;
  9278. }
  9279. else {
  9280. int res;
  9281. res = obj2ast_arg(tmp, &kwarg, arena);
  9282. if (res != 0) goto failed;
  9283. Py_CLEAR(tmp);
  9284. }
  9285. if (_PyObject_LookupAttr(obj, astmodulestate_global->defaults, &tmp) < 0) {
  9286. return 1;
  9287. }
  9288. if (tmp == NULL) {
  9289. PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments");
  9290. return 1;
  9291. }
  9292. else {
  9293. int res;
  9294. Py_ssize_t len;
  9295. Py_ssize_t i;
  9296. if (!PyList_Check(tmp)) {
  9297. PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
  9298. goto failed;
  9299. }
  9300. len = PyList_GET_SIZE(tmp);
  9301. defaults = _Py_asdl_seq_new(len, arena);
  9302. if (defaults == NULL) goto failed;
  9303. for (i = 0; i < len; i++) {
  9304. expr_ty val;
  9305. PyObject *tmp2 = PyList_GET_ITEM(tmp, i);
  9306. Py_INCREF(tmp2);
  9307. res = obj2ast_expr(tmp2, &val, arena);
  9308. Py_DECREF(tmp2);
  9309. if (res != 0) goto failed;
  9310. if (len != PyList_GET_SIZE(tmp)) {
  9311. PyErr_SetString(PyExc_RuntimeError, "arguments field \"defaults\" changed size during iteration");
  9312. goto failed;
  9313. }
  9314. asdl_seq_SET(defaults, i, val);
  9315. }
  9316. Py_CLEAR(tmp);
  9317. }
  9318. *out = arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg,
  9319. defaults, arena);
  9320. return 0;
  9321. failed:
  9322. Py_XDECREF(tmp);
  9323. return 1;
  9324. }
  9325. int
  9326. obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
  9327. {
  9328. PyObject* tmp = NULL;
  9329. identifier arg;
  9330. expr_ty annotation;
  9331. string type_comment;
  9332. int lineno;
  9333. int col_offset;
  9334. int end_lineno;
  9335. int end_col_offset;
  9336. if (_PyObject_LookupAttr(obj, astmodulestate_global->arg, &tmp) < 0) {
  9337. return 1;
  9338. }
  9339. if (tmp == NULL) {
  9340. PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg");
  9341. return 1;
  9342. }
  9343. else {
  9344. int res;
  9345. res = obj2ast_identifier(tmp, &arg, arena);
  9346. if (res != 0) goto failed;
  9347. Py_CLEAR(tmp);
  9348. }
  9349. if (_PyObject_LookupAttr(obj, astmodulestate_global->annotation, &tmp) < 0)
  9350. {
  9351. return 1;
  9352. }
  9353. if (tmp == NULL || tmp == Py_None) {
  9354. Py_CLEAR(tmp);
  9355. annotation = NULL;
  9356. }
  9357. else {
  9358. int res;
  9359. res = obj2ast_expr(tmp, &annotation, arena);
  9360. if (res != 0) goto failed;
  9361. Py_CLEAR(tmp);
  9362. }
  9363. if (_PyObject_LookupAttr(obj, astmodulestate_global->type_comment, &tmp) <
  9364. 0) {
  9365. return 1;
  9366. }
  9367. if (tmp == NULL || tmp == Py_None) {
  9368. Py_CLEAR(tmp);
  9369. type_comment = NULL;
  9370. }
  9371. else {
  9372. int res;
  9373. res = obj2ast_string(tmp, &type_comment, arena);
  9374. if (res != 0) goto failed;
  9375. Py_CLEAR(tmp);
  9376. }
  9377. if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0) {
  9378. return 1;
  9379. }
  9380. if (tmp == NULL) {
  9381. PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg");
  9382. return 1;
  9383. }
  9384. else {
  9385. int res;
  9386. res = obj2ast_int(tmp, &lineno, arena);
  9387. if (res != 0) goto failed;
  9388. Py_CLEAR(tmp);
  9389. }
  9390. if (_PyObject_LookupAttr(obj, astmodulestate_global->col_offset, &tmp) < 0)
  9391. {
  9392. return 1;
  9393. }
  9394. if (tmp == NULL) {
  9395. PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg");
  9396. return 1;
  9397. }
  9398. else {
  9399. int res;
  9400. res = obj2ast_int(tmp, &col_offset, arena);
  9401. if (res != 0) goto failed;
  9402. Py_CLEAR(tmp);
  9403. }
  9404. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_lineno, &tmp) < 0)
  9405. {
  9406. return 1;
  9407. }
  9408. if (tmp == NULL || tmp == Py_None) {
  9409. Py_CLEAR(tmp);
  9410. end_lineno = 0;
  9411. }
  9412. else {
  9413. int res;
  9414. res = obj2ast_int(tmp, &end_lineno, arena);
  9415. if (res != 0) goto failed;
  9416. Py_CLEAR(tmp);
  9417. }
  9418. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_col_offset, &tmp)
  9419. < 0) {
  9420. return 1;
  9421. }
  9422. if (tmp == NULL || tmp == Py_None) {
  9423. Py_CLEAR(tmp);
  9424. end_col_offset = 0;
  9425. }
  9426. else {
  9427. int res;
  9428. res = obj2ast_int(tmp, &end_col_offset, arena);
  9429. if (res != 0) goto failed;
  9430. Py_CLEAR(tmp);
  9431. }
  9432. *out = arg(arg, annotation, type_comment, lineno, col_offset, end_lineno,
  9433. end_col_offset, arena);
  9434. return 0;
  9435. failed:
  9436. Py_XDECREF(tmp);
  9437. return 1;
  9438. }
  9439. int
  9440. obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena)
  9441. {
  9442. PyObject* tmp = NULL;
  9443. identifier arg;
  9444. expr_ty value;
  9445. int lineno;
  9446. int col_offset;
  9447. int end_lineno;
  9448. int end_col_offset;
  9449. if (_PyObject_LookupAttr(obj, astmodulestate_global->arg, &tmp) < 0) {
  9450. return 1;
  9451. }
  9452. if (tmp == NULL || tmp == Py_None) {
  9453. Py_CLEAR(tmp);
  9454. arg = NULL;
  9455. }
  9456. else {
  9457. int res;
  9458. res = obj2ast_identifier(tmp, &arg, arena);
  9459. if (res != 0) goto failed;
  9460. Py_CLEAR(tmp);
  9461. }
  9462. if (_PyObject_LookupAttr(obj, astmodulestate_global->value, &tmp) < 0) {
  9463. return 1;
  9464. }
  9465. if (tmp == NULL) {
  9466. PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from keyword");
  9467. return 1;
  9468. }
  9469. else {
  9470. int res;
  9471. res = obj2ast_expr(tmp, &value, arena);
  9472. if (res != 0) goto failed;
  9473. Py_CLEAR(tmp);
  9474. }
  9475. if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0) {
  9476. return 1;
  9477. }
  9478. if (tmp == NULL) {
  9479. PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from keyword");
  9480. return 1;
  9481. }
  9482. else {
  9483. int res;
  9484. res = obj2ast_int(tmp, &lineno, arena);
  9485. if (res != 0) goto failed;
  9486. Py_CLEAR(tmp);
  9487. }
  9488. if (_PyObject_LookupAttr(obj, astmodulestate_global->col_offset, &tmp) < 0)
  9489. {
  9490. return 1;
  9491. }
  9492. if (tmp == NULL) {
  9493. PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from keyword");
  9494. return 1;
  9495. }
  9496. else {
  9497. int res;
  9498. res = obj2ast_int(tmp, &col_offset, arena);
  9499. if (res != 0) goto failed;
  9500. Py_CLEAR(tmp);
  9501. }
  9502. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_lineno, &tmp) < 0)
  9503. {
  9504. return 1;
  9505. }
  9506. if (tmp == NULL || tmp == Py_None) {
  9507. Py_CLEAR(tmp);
  9508. end_lineno = 0;
  9509. }
  9510. else {
  9511. int res;
  9512. res = obj2ast_int(tmp, &end_lineno, arena);
  9513. if (res != 0) goto failed;
  9514. Py_CLEAR(tmp);
  9515. }
  9516. if (_PyObject_LookupAttr(obj, astmodulestate_global->end_col_offset, &tmp)
  9517. < 0) {
  9518. return 1;
  9519. }
  9520. if (tmp == NULL || tmp == Py_None) {
  9521. Py_CLEAR(tmp);
  9522. end_col_offset = 0;
  9523. }
  9524. else {
  9525. int res;
  9526. res = obj2ast_int(tmp, &end_col_offset, arena);
  9527. if (res != 0) goto failed;
  9528. Py_CLEAR(tmp);
  9529. }
  9530. *out = keyword(arg, value, lineno, col_offset, end_lineno, end_col_offset,
  9531. arena);
  9532. return 0;
  9533. failed:
  9534. Py_XDECREF(tmp);
  9535. return 1;
  9536. }
  9537. int
  9538. obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena)
  9539. {
  9540. PyObject* tmp = NULL;
  9541. identifier name;
  9542. identifier asname;
  9543. if (_PyObject_LookupAttr(obj, astmodulestate_global->name, &tmp) < 0) {
  9544. return 1;
  9545. }
  9546. if (tmp == NULL) {
  9547. PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias");
  9548. return 1;
  9549. }
  9550. else {
  9551. int res;
  9552. res = obj2ast_identifier(tmp, &name, arena);
  9553. if (res != 0) goto failed;
  9554. Py_CLEAR(tmp);
  9555. }
  9556. if (_PyObject_LookupAttr(obj, astmodulestate_global->asname, &tmp) < 0) {
  9557. return 1;
  9558. }
  9559. if (tmp == NULL || tmp == Py_None) {
  9560. Py_CLEAR(tmp);
  9561. asname = NULL;
  9562. }
  9563. else {
  9564. int res;
  9565. res = obj2ast_identifier(tmp, &asname, arena);
  9566. if (res != 0) goto failed;
  9567. Py_CLEAR(tmp);
  9568. }
  9569. *out = alias(name, asname, arena);
  9570. return 0;
  9571. failed:
  9572. Py_XDECREF(tmp);
  9573. return 1;
  9574. }
  9575. int
  9576. obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena)
  9577. {
  9578. PyObject* tmp = NULL;
  9579. expr_ty context_expr;
  9580. expr_ty optional_vars;
  9581. if (_PyObject_LookupAttr(obj, astmodulestate_global->context_expr, &tmp) <
  9582. 0) {
  9583. return 1;
  9584. }
  9585. if (tmp == NULL) {
  9586. PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem");
  9587. return 1;
  9588. }
  9589. else {
  9590. int res;
  9591. res = obj2ast_expr(tmp, &context_expr, arena);
  9592. if (res != 0) goto failed;
  9593. Py_CLEAR(tmp);
  9594. }
  9595. if (_PyObject_LookupAttr(obj, astmodulestate_global->optional_vars, &tmp) <
  9596. 0) {
  9597. return 1;
  9598. }
  9599. if (tmp == NULL || tmp == Py_None) {
  9600. Py_CLEAR(tmp);
  9601. optional_vars = NULL;
  9602. }
  9603. else {
  9604. int res;
  9605. res = obj2ast_expr(tmp, &optional_vars, arena);
  9606. if (res != 0) goto failed;
  9607. Py_CLEAR(tmp);
  9608. }
  9609. *out = withitem(context_expr, optional_vars, arena);
  9610. return 0;
  9611. failed:
  9612. Py_XDECREF(tmp);
  9613. return 1;
  9614. }
  9615. int
  9616. obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena)
  9617. {
  9618. int isinstance;
  9619. PyObject *tmp = NULL;
  9620. PyObject *tp;
  9621. if (obj == Py_None) {
  9622. *out = NULL;
  9623. return 0;
  9624. }
  9625. tp = astmodulestate_global->TypeIgnore_type;
  9626. isinstance = PyObject_IsInstance(obj, tp);
  9627. if (isinstance == -1) {
  9628. return 1;
  9629. }
  9630. if (isinstance) {
  9631. int lineno;
  9632. string tag;
  9633. if (_PyObject_LookupAttr(obj, astmodulestate_global->lineno, &tmp) < 0)
  9634. {
  9635. return 1;
  9636. }
  9637. if (tmp == NULL) {
  9638. PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore");
  9639. return 1;
  9640. }
  9641. else {
  9642. int res;
  9643. res = obj2ast_int(tmp, &lineno, arena);
  9644. if (res != 0) goto failed;
  9645. Py_CLEAR(tmp);
  9646. }
  9647. if (_PyObject_LookupAttr(obj, astmodulestate_global->tag, &tmp) < 0) {
  9648. return 1;
  9649. }
  9650. if (tmp == NULL) {
  9651. PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore");
  9652. return 1;
  9653. }
  9654. else {
  9655. int res;
  9656. res = obj2ast_string(tmp, &tag, arena);
  9657. if (res != 0) goto failed;
  9658. Py_CLEAR(tmp);
  9659. }
  9660. *out = TypeIgnore(lineno, tag, arena);
  9661. if (*out == NULL) goto failed;
  9662. return 0;
  9663. }
  9664. PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj);
  9665. failed:
  9666. Py_XDECREF(tmp);
  9667. return 1;
  9668. }
  9669. PyMODINIT_FUNC
  9670. PyInit__ast(void)
  9671. {
  9672. PyObject *m;
  9673. if (!init_types()) return NULL;
  9674. m = PyState_FindModule(&_astmodule);
  9675. if (!m) return NULL;
  9676. if (PyModule_AddObject(m, "AST", astmodulestate_global->AST_type) < 0) {
  9677. goto error;
  9678. }
  9679. Py_INCREF(astmodulestate(m)->AST_type);
  9680. if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) {
  9681. goto error;
  9682. }
  9683. if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) {
  9684. goto error;
  9685. }
  9686. if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) {
  9687. goto error;
  9688. }
  9689. if (PyModule_AddObject(m, "mod", astmodulestate_global->mod_type) < 0) {
  9690. goto error;
  9691. }
  9692. Py_INCREF(astmodulestate(m)->mod_type);
  9693. if (PyModule_AddObject(m, "Module", astmodulestate_global->Module_type) <
  9694. 0) {
  9695. goto error;
  9696. }
  9697. Py_INCREF(astmodulestate(m)->Module_type);
  9698. if (PyModule_AddObject(m, "Interactive",
  9699. astmodulestate_global->Interactive_type) < 0) {
  9700. goto error;
  9701. }
  9702. Py_INCREF(astmodulestate(m)->Interactive_type);
  9703. if (PyModule_AddObject(m, "Expression",
  9704. astmodulestate_global->Expression_type) < 0) {
  9705. goto error;
  9706. }
  9707. Py_INCREF(astmodulestate(m)->Expression_type);
  9708. if (PyModule_AddObject(m, "FunctionType",
  9709. astmodulestate_global->FunctionType_type) < 0) {
  9710. goto error;
  9711. }
  9712. Py_INCREF(astmodulestate(m)->FunctionType_type);
  9713. if (PyModule_AddObject(m, "stmt", astmodulestate_global->stmt_type) < 0) {
  9714. goto error;
  9715. }
  9716. Py_INCREF(astmodulestate(m)->stmt_type);
  9717. if (PyModule_AddObject(m, "FunctionDef",
  9718. astmodulestate_global->FunctionDef_type) < 0) {
  9719. goto error;
  9720. }
  9721. Py_INCREF(astmodulestate(m)->FunctionDef_type);
  9722. if (PyModule_AddObject(m, "AsyncFunctionDef",
  9723. astmodulestate_global->AsyncFunctionDef_type) < 0) {
  9724. goto error;
  9725. }
  9726. Py_INCREF(astmodulestate(m)->AsyncFunctionDef_type);
  9727. if (PyModule_AddObject(m, "ClassDef", astmodulestate_global->ClassDef_type)
  9728. < 0) {
  9729. goto error;
  9730. }
  9731. Py_INCREF(astmodulestate(m)->ClassDef_type);
  9732. if (PyModule_AddObject(m, "Return", astmodulestate_global->Return_type) <
  9733. 0) {
  9734. goto error;
  9735. }
  9736. Py_INCREF(astmodulestate(m)->Return_type);
  9737. if (PyModule_AddObject(m, "Delete", astmodulestate_global->Delete_type) <
  9738. 0) {
  9739. goto error;
  9740. }
  9741. Py_INCREF(astmodulestate(m)->Delete_type);
  9742. if (PyModule_AddObject(m, "Assign", astmodulestate_global->Assign_type) <
  9743. 0) {
  9744. goto error;
  9745. }
  9746. Py_INCREF(astmodulestate(m)->Assign_type);
  9747. if (PyModule_AddObject(m, "AugAssign",
  9748. astmodulestate_global->AugAssign_type) < 0) {
  9749. goto error;
  9750. }
  9751. Py_INCREF(astmodulestate(m)->AugAssign_type);
  9752. if (PyModule_AddObject(m, "AnnAssign",
  9753. astmodulestate_global->AnnAssign_type) < 0) {
  9754. goto error;
  9755. }
  9756. Py_INCREF(astmodulestate(m)->AnnAssign_type);
  9757. if (PyModule_AddObject(m, "For", astmodulestate_global->For_type) < 0) {
  9758. goto error;
  9759. }
  9760. Py_INCREF(astmodulestate(m)->For_type);
  9761. if (PyModule_AddObject(m, "AsyncFor", astmodulestate_global->AsyncFor_type)
  9762. < 0) {
  9763. goto error;
  9764. }
  9765. Py_INCREF(astmodulestate(m)->AsyncFor_type);
  9766. if (PyModule_AddObject(m, "While", astmodulestate_global->While_type) < 0) {
  9767. goto error;
  9768. }
  9769. Py_INCREF(astmodulestate(m)->While_type);
  9770. if (PyModule_AddObject(m, "If", astmodulestate_global->If_type) < 0) {
  9771. goto error;
  9772. }
  9773. Py_INCREF(astmodulestate(m)->If_type);
  9774. if (PyModule_AddObject(m, "With", astmodulestate_global->With_type) < 0) {
  9775. goto error;
  9776. }
  9777. Py_INCREF(astmodulestate(m)->With_type);
  9778. if (PyModule_AddObject(m, "AsyncWith",
  9779. astmodulestate_global->AsyncWith_type) < 0) {
  9780. goto error;
  9781. }
  9782. Py_INCREF(astmodulestate(m)->AsyncWith_type);
  9783. if (PyModule_AddObject(m, "Raise", astmodulestate_global->Raise_type) < 0) {
  9784. goto error;
  9785. }
  9786. Py_INCREF(astmodulestate(m)->Raise_type);
  9787. if (PyModule_AddObject(m, "Try", astmodulestate_global->Try_type) < 0) {
  9788. goto error;
  9789. }
  9790. Py_INCREF(astmodulestate(m)->Try_type);
  9791. if (PyModule_AddObject(m, "Assert", astmodulestate_global->Assert_type) <
  9792. 0) {
  9793. goto error;
  9794. }
  9795. Py_INCREF(astmodulestate(m)->Assert_type);
  9796. if (PyModule_AddObject(m, "Import", astmodulestate_global->Import_type) <
  9797. 0) {
  9798. goto error;
  9799. }
  9800. Py_INCREF(astmodulestate(m)->Import_type);
  9801. if (PyModule_AddObject(m, "ImportFrom",
  9802. astmodulestate_global->ImportFrom_type) < 0) {
  9803. goto error;
  9804. }
  9805. Py_INCREF(astmodulestate(m)->ImportFrom_type);
  9806. if (PyModule_AddObject(m, "Global", astmodulestate_global->Global_type) <
  9807. 0) {
  9808. goto error;
  9809. }
  9810. Py_INCREF(astmodulestate(m)->Global_type);
  9811. if (PyModule_AddObject(m, "Nonlocal", astmodulestate_global->Nonlocal_type)
  9812. < 0) {
  9813. goto error;
  9814. }
  9815. Py_INCREF(astmodulestate(m)->Nonlocal_type);
  9816. if (PyModule_AddObject(m, "Expr", astmodulestate_global->Expr_type) < 0) {
  9817. goto error;
  9818. }
  9819. Py_INCREF(astmodulestate(m)->Expr_type);
  9820. if (PyModule_AddObject(m, "Pass", astmodulestate_global->Pass_type) < 0) {
  9821. goto error;
  9822. }
  9823. Py_INCREF(astmodulestate(m)->Pass_type);
  9824. if (PyModule_AddObject(m, "Break", astmodulestate_global->Break_type) < 0) {
  9825. goto error;
  9826. }
  9827. Py_INCREF(astmodulestate(m)->Break_type);
  9828. if (PyModule_AddObject(m, "Continue", astmodulestate_global->Continue_type)
  9829. < 0) {
  9830. goto error;
  9831. }
  9832. Py_INCREF(astmodulestate(m)->Continue_type);
  9833. if (PyModule_AddObject(m, "expr", astmodulestate_global->expr_type) < 0) {
  9834. goto error;
  9835. }
  9836. Py_INCREF(astmodulestate(m)->expr_type);
  9837. if (PyModule_AddObject(m, "BoolOp", astmodulestate_global->BoolOp_type) <
  9838. 0) {
  9839. goto error;
  9840. }
  9841. Py_INCREF(astmodulestate(m)->BoolOp_type);
  9842. if (PyModule_AddObject(m, "NamedExpr",
  9843. astmodulestate_global->NamedExpr_type) < 0) {
  9844. goto error;
  9845. }
  9846. Py_INCREF(astmodulestate(m)->NamedExpr_type);
  9847. if (PyModule_AddObject(m, "BinOp", astmodulestate_global->BinOp_type) < 0) {
  9848. goto error;
  9849. }
  9850. Py_INCREF(astmodulestate(m)->BinOp_type);
  9851. if (PyModule_AddObject(m, "UnaryOp", astmodulestate_global->UnaryOp_type) <
  9852. 0) {
  9853. goto error;
  9854. }
  9855. Py_INCREF(astmodulestate(m)->UnaryOp_type);
  9856. if (PyModule_AddObject(m, "Lambda", astmodulestate_global->Lambda_type) <
  9857. 0) {
  9858. goto error;
  9859. }
  9860. Py_INCREF(astmodulestate(m)->Lambda_type);
  9861. if (PyModule_AddObject(m, "IfExp", astmodulestate_global->IfExp_type) < 0) {
  9862. goto error;
  9863. }
  9864. Py_INCREF(astmodulestate(m)->IfExp_type);
  9865. if (PyModule_AddObject(m, "Dict", astmodulestate_global->Dict_type) < 0) {
  9866. goto error;
  9867. }
  9868. Py_INCREF(astmodulestate(m)->Dict_type);
  9869. if (PyModule_AddObject(m, "Set", astmodulestate_global->Set_type) < 0) {
  9870. goto error;
  9871. }
  9872. Py_INCREF(astmodulestate(m)->Set_type);
  9873. if (PyModule_AddObject(m, "ListComp", astmodulestate_global->ListComp_type)
  9874. < 0) {
  9875. goto error;
  9876. }
  9877. Py_INCREF(astmodulestate(m)->ListComp_type);
  9878. if (PyModule_AddObject(m, "SetComp", astmodulestate_global->SetComp_type) <
  9879. 0) {
  9880. goto error;
  9881. }
  9882. Py_INCREF(astmodulestate(m)->SetComp_type);
  9883. if (PyModule_AddObject(m, "DictComp", astmodulestate_global->DictComp_type)
  9884. < 0) {
  9885. goto error;
  9886. }
  9887. Py_INCREF(astmodulestate(m)->DictComp_type);
  9888. if (PyModule_AddObject(m, "GeneratorExp",
  9889. astmodulestate_global->GeneratorExp_type) < 0) {
  9890. goto error;
  9891. }
  9892. Py_INCREF(astmodulestate(m)->GeneratorExp_type);
  9893. if (PyModule_AddObject(m, "Await", astmodulestate_global->Await_type) < 0) {
  9894. goto error;
  9895. }
  9896. Py_INCREF(astmodulestate(m)->Await_type);
  9897. if (PyModule_AddObject(m, "Yield", astmodulestate_global->Yield_type) < 0) {
  9898. goto error;
  9899. }
  9900. Py_INCREF(astmodulestate(m)->Yield_type);
  9901. if (PyModule_AddObject(m, "YieldFrom",
  9902. astmodulestate_global->YieldFrom_type) < 0) {
  9903. goto error;
  9904. }
  9905. Py_INCREF(astmodulestate(m)->YieldFrom_type);
  9906. if (PyModule_AddObject(m, "Compare", astmodulestate_global->Compare_type) <
  9907. 0) {
  9908. goto error;
  9909. }
  9910. Py_INCREF(astmodulestate(m)->Compare_type);
  9911. if (PyModule_AddObject(m, "Call", astmodulestate_global->Call_type) < 0) {
  9912. goto error;
  9913. }
  9914. Py_INCREF(astmodulestate(m)->Call_type);
  9915. if (PyModule_AddObject(m, "FormattedValue",
  9916. astmodulestate_global->FormattedValue_type) < 0) {
  9917. goto error;
  9918. }
  9919. Py_INCREF(astmodulestate(m)->FormattedValue_type);
  9920. if (PyModule_AddObject(m, "JoinedStr",
  9921. astmodulestate_global->JoinedStr_type) < 0) {
  9922. goto error;
  9923. }
  9924. Py_INCREF(astmodulestate(m)->JoinedStr_type);
  9925. if (PyModule_AddObject(m, "Constant", astmodulestate_global->Constant_type)
  9926. < 0) {
  9927. goto error;
  9928. }
  9929. Py_INCREF(astmodulestate(m)->Constant_type);
  9930. if (PyModule_AddObject(m, "Attribute",
  9931. astmodulestate_global->Attribute_type) < 0) {
  9932. goto error;
  9933. }
  9934. Py_INCREF(astmodulestate(m)->Attribute_type);
  9935. if (PyModule_AddObject(m, "Subscript",
  9936. astmodulestate_global->Subscript_type) < 0) {
  9937. goto error;
  9938. }
  9939. Py_INCREF(astmodulestate(m)->Subscript_type);
  9940. if (PyModule_AddObject(m, "Starred", astmodulestate_global->Starred_type) <
  9941. 0) {
  9942. goto error;
  9943. }
  9944. Py_INCREF(astmodulestate(m)->Starred_type);
  9945. if (PyModule_AddObject(m, "Name", astmodulestate_global->Name_type) < 0) {
  9946. goto error;
  9947. }
  9948. Py_INCREF(astmodulestate(m)->Name_type);
  9949. if (PyModule_AddObject(m, "List", astmodulestate_global->List_type) < 0) {
  9950. goto error;
  9951. }
  9952. Py_INCREF(astmodulestate(m)->List_type);
  9953. if (PyModule_AddObject(m, "Tuple", astmodulestate_global->Tuple_type) < 0) {
  9954. goto error;
  9955. }
  9956. Py_INCREF(astmodulestate(m)->Tuple_type);
  9957. if (PyModule_AddObject(m, "Slice", astmodulestate_global->Slice_type) < 0) {
  9958. goto error;
  9959. }
  9960. Py_INCREF(astmodulestate(m)->Slice_type);
  9961. if (PyModule_AddObject(m, "expr_context",
  9962. astmodulestate_global->expr_context_type) < 0) {
  9963. goto error;
  9964. }
  9965. Py_INCREF(astmodulestate(m)->expr_context_type);
  9966. if (PyModule_AddObject(m, "Load", astmodulestate_global->Load_type) < 0) {
  9967. goto error;
  9968. }
  9969. Py_INCREF(astmodulestate(m)->Load_type);
  9970. if (PyModule_AddObject(m, "Store", astmodulestate_global->Store_type) < 0) {
  9971. goto error;
  9972. }
  9973. Py_INCREF(astmodulestate(m)->Store_type);
  9974. if (PyModule_AddObject(m, "Del", astmodulestate_global->Del_type) < 0) {
  9975. goto error;
  9976. }
  9977. Py_INCREF(astmodulestate(m)->Del_type);
  9978. if (PyModule_AddObject(m, "boolop", astmodulestate_global->boolop_type) <
  9979. 0) {
  9980. goto error;
  9981. }
  9982. Py_INCREF(astmodulestate(m)->boolop_type);
  9983. if (PyModule_AddObject(m, "And", astmodulestate_global->And_type) < 0) {
  9984. goto error;
  9985. }
  9986. Py_INCREF(astmodulestate(m)->And_type);
  9987. if (PyModule_AddObject(m, "Or", astmodulestate_global->Or_type) < 0) {
  9988. goto error;
  9989. }
  9990. Py_INCREF(astmodulestate(m)->Or_type);
  9991. if (PyModule_AddObject(m, "operator", astmodulestate_global->operator_type)
  9992. < 0) {
  9993. goto error;
  9994. }
  9995. Py_INCREF(astmodulestate(m)->operator_type);
  9996. if (PyModule_AddObject(m, "Add", astmodulestate_global->Add_type) < 0) {
  9997. goto error;
  9998. }
  9999. Py_INCREF(astmodulestate(m)->Add_type);
  10000. if (PyModule_AddObject(m, "Sub", astmodulestate_global->Sub_type) < 0) {
  10001. goto error;
  10002. }
  10003. Py_INCREF(astmodulestate(m)->Sub_type);
  10004. if (PyModule_AddObject(m, "Mult", astmodulestate_global->Mult_type) < 0) {
  10005. goto error;
  10006. }
  10007. Py_INCREF(astmodulestate(m)->Mult_type);
  10008. if (PyModule_AddObject(m, "MatMult", astmodulestate_global->MatMult_type) <
  10009. 0) {
  10010. goto error;
  10011. }
  10012. Py_INCREF(astmodulestate(m)->MatMult_type);
  10013. if (PyModule_AddObject(m, "Div", astmodulestate_global->Div_type) < 0) {
  10014. goto error;
  10015. }
  10016. Py_INCREF(astmodulestate(m)->Div_type);
  10017. if (PyModule_AddObject(m, "Mod", astmodulestate_global->Mod_type) < 0) {
  10018. goto error;
  10019. }
  10020. Py_INCREF(astmodulestate(m)->Mod_type);
  10021. if (PyModule_AddObject(m, "Pow", astmodulestate_global->Pow_type) < 0) {
  10022. goto error;
  10023. }
  10024. Py_INCREF(astmodulestate(m)->Pow_type);
  10025. if (PyModule_AddObject(m, "LShift", astmodulestate_global->LShift_type) <
  10026. 0) {
  10027. goto error;
  10028. }
  10029. Py_INCREF(astmodulestate(m)->LShift_type);
  10030. if (PyModule_AddObject(m, "RShift", astmodulestate_global->RShift_type) <
  10031. 0) {
  10032. goto error;
  10033. }
  10034. Py_INCREF(astmodulestate(m)->RShift_type);
  10035. if (PyModule_AddObject(m, "BitOr", astmodulestate_global->BitOr_type) < 0) {
  10036. goto error;
  10037. }
  10038. Py_INCREF(astmodulestate(m)->BitOr_type);
  10039. if (PyModule_AddObject(m, "BitXor", astmodulestate_global->BitXor_type) <
  10040. 0) {
  10041. goto error;
  10042. }
  10043. Py_INCREF(astmodulestate(m)->BitXor_type);
  10044. if (PyModule_AddObject(m, "BitAnd", astmodulestate_global->BitAnd_type) <
  10045. 0) {
  10046. goto error;
  10047. }
  10048. Py_INCREF(astmodulestate(m)->BitAnd_type);
  10049. if (PyModule_AddObject(m, "FloorDiv", astmodulestate_global->FloorDiv_type)
  10050. < 0) {
  10051. goto error;
  10052. }
  10053. Py_INCREF(astmodulestate(m)->FloorDiv_type);
  10054. if (PyModule_AddObject(m, "unaryop", astmodulestate_global->unaryop_type) <
  10055. 0) {
  10056. goto error;
  10057. }
  10058. Py_INCREF(astmodulestate(m)->unaryop_type);
  10059. if (PyModule_AddObject(m, "Invert", astmodulestate_global->Invert_type) <
  10060. 0) {
  10061. goto error;
  10062. }
  10063. Py_INCREF(astmodulestate(m)->Invert_type);
  10064. if (PyModule_AddObject(m, "Not", astmodulestate_global->Not_type) < 0) {
  10065. goto error;
  10066. }
  10067. Py_INCREF(astmodulestate(m)->Not_type);
  10068. if (PyModule_AddObject(m, "UAdd", astmodulestate_global->UAdd_type) < 0) {
  10069. goto error;
  10070. }
  10071. Py_INCREF(astmodulestate(m)->UAdd_type);
  10072. if (PyModule_AddObject(m, "USub", astmodulestate_global->USub_type) < 0) {
  10073. goto error;
  10074. }
  10075. Py_INCREF(astmodulestate(m)->USub_type);
  10076. if (PyModule_AddObject(m, "cmpop", astmodulestate_global->cmpop_type) < 0) {
  10077. goto error;
  10078. }
  10079. Py_INCREF(astmodulestate(m)->cmpop_type);
  10080. if (PyModule_AddObject(m, "Eq", astmodulestate_global->Eq_type) < 0) {
  10081. goto error;
  10082. }
  10083. Py_INCREF(astmodulestate(m)->Eq_type);
  10084. if (PyModule_AddObject(m, "NotEq", astmodulestate_global->NotEq_type) < 0) {
  10085. goto error;
  10086. }
  10087. Py_INCREF(astmodulestate(m)->NotEq_type);
  10088. if (PyModule_AddObject(m, "Lt", astmodulestate_global->Lt_type) < 0) {
  10089. goto error;
  10090. }
  10091. Py_INCREF(astmodulestate(m)->Lt_type);
  10092. if (PyModule_AddObject(m, "LtE", astmodulestate_global->LtE_type) < 0) {
  10093. goto error;
  10094. }
  10095. Py_INCREF(astmodulestate(m)->LtE_type);
  10096. if (PyModule_AddObject(m, "Gt", astmodulestate_global->Gt_type) < 0) {
  10097. goto error;
  10098. }
  10099. Py_INCREF(astmodulestate(m)->Gt_type);
  10100. if (PyModule_AddObject(m, "GtE", astmodulestate_global->GtE_type) < 0) {
  10101. goto error;
  10102. }
  10103. Py_INCREF(astmodulestate(m)->GtE_type);
  10104. if (PyModule_AddObject(m, "Is", astmodulestate_global->Is_type) < 0) {
  10105. goto error;
  10106. }
  10107. Py_INCREF(astmodulestate(m)->Is_type);
  10108. if (PyModule_AddObject(m, "IsNot", astmodulestate_global->IsNot_type) < 0) {
  10109. goto error;
  10110. }
  10111. Py_INCREF(astmodulestate(m)->IsNot_type);
  10112. if (PyModule_AddObject(m, "In", astmodulestate_global->In_type) < 0) {
  10113. goto error;
  10114. }
  10115. Py_INCREF(astmodulestate(m)->In_type);
  10116. if (PyModule_AddObject(m, "NotIn", astmodulestate_global->NotIn_type) < 0) {
  10117. goto error;
  10118. }
  10119. Py_INCREF(astmodulestate(m)->NotIn_type);
  10120. if (PyModule_AddObject(m, "comprehension",
  10121. astmodulestate_global->comprehension_type) < 0) {
  10122. goto error;
  10123. }
  10124. Py_INCREF(astmodulestate(m)->comprehension_type);
  10125. if (PyModule_AddObject(m, "excepthandler",
  10126. astmodulestate_global->excepthandler_type) < 0) {
  10127. goto error;
  10128. }
  10129. Py_INCREF(astmodulestate(m)->excepthandler_type);
  10130. if (PyModule_AddObject(m, "ExceptHandler",
  10131. astmodulestate_global->ExceptHandler_type) < 0) {
  10132. goto error;
  10133. }
  10134. Py_INCREF(astmodulestate(m)->ExceptHandler_type);
  10135. if (PyModule_AddObject(m, "arguments",
  10136. astmodulestate_global->arguments_type) < 0) {
  10137. goto error;
  10138. }
  10139. Py_INCREF(astmodulestate(m)->arguments_type);
  10140. if (PyModule_AddObject(m, "arg", astmodulestate_global->arg_type) < 0) {
  10141. goto error;
  10142. }
  10143. Py_INCREF(astmodulestate(m)->arg_type);
  10144. if (PyModule_AddObject(m, "keyword", astmodulestate_global->keyword_type) <
  10145. 0) {
  10146. goto error;
  10147. }
  10148. Py_INCREF(astmodulestate(m)->keyword_type);
  10149. if (PyModule_AddObject(m, "alias", astmodulestate_global->alias_type) < 0) {
  10150. goto error;
  10151. }
  10152. Py_INCREF(astmodulestate(m)->alias_type);
  10153. if (PyModule_AddObject(m, "withitem", astmodulestate_global->withitem_type)
  10154. < 0) {
  10155. goto error;
  10156. }
  10157. Py_INCREF(astmodulestate(m)->withitem_type);
  10158. if (PyModule_AddObject(m, "type_ignore",
  10159. astmodulestate_global->type_ignore_type) < 0) {
  10160. goto error;
  10161. }
  10162. Py_INCREF(astmodulestate(m)->type_ignore_type);
  10163. if (PyModule_AddObject(m, "TypeIgnore",
  10164. astmodulestate_global->TypeIgnore_type) < 0) {
  10165. goto error;
  10166. }
  10167. Py_INCREF(astmodulestate(m)->TypeIgnore_type);
  10168. return m;
  10169. error:
  10170. Py_DECREF(m);
  10171. return NULL;
  10172. }
  10173. PyObject* PyAST_mod2obj(mod_ty t)
  10174. {
  10175. if (!init_types())
  10176. return NULL;
  10177. return ast2obj_mod(t);
  10178. }
  10179. /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
  10180. mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
  10181. {
  10182. PyObject *req_type[3];
  10183. const char * const req_name[] = {"Module", "Expression", "Interactive"};
  10184. int isinstance;
  10185. if (PySys_Audit("compile", "OO", ast, Py_None) < 0) {
  10186. return NULL;
  10187. }
  10188. req_type[0] = astmodulestate_global->Module_type;
  10189. req_type[1] = astmodulestate_global->Expression_type;
  10190. req_type[2] = astmodulestate_global->Interactive_type;
  10191. assert(0 <= mode && mode <= 2);
  10192. if (!init_types())
  10193. return NULL;
  10194. isinstance = PyObject_IsInstance(ast, req_type[mode]);
  10195. if (isinstance == -1)
  10196. return NULL;
  10197. if (!isinstance) {
  10198. PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s",
  10199. req_name[mode], _PyType_Name(Py_TYPE(ast)));
  10200. return NULL;
  10201. }
  10202. mod_ty res = NULL;
  10203. if (obj2ast_mod(ast, &res, arena) != 0)
  10204. return NULL;
  10205. else
  10206. return res;
  10207. }
  10208. int PyAST_Check(PyObject* obj)
  10209. {
  10210. if (!init_types())
  10211. return -1;
  10212. return PyObject_IsInstance(obj, astmodulestate_global->AST_type);
  10213. }