mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #4042 from youknowone/ast
Update ast and dict changes including unpack & kw_defaults
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1723,6 +1723,7 @@ name = "rustpython-ast"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"rustpython-bytecode",
|
||||
"rustpython-common",
|
||||
]
|
||||
|
||||
|
||||
109
Lib/ast.py
vendored
109
Lib/ast.py
vendored
@@ -47,8 +47,8 @@ def parse(source, filename='<unknown>', mode='exec', *,
|
||||
elif feature_version is None:
|
||||
feature_version = -1
|
||||
# Else it should be an int giving the minor version for 3.x.
|
||||
return compile(source, filename, mode, flags)
|
||||
# _feature_version=feature_version)
|
||||
return compile(source, filename, mode, flags,
|
||||
_feature_version=feature_version)
|
||||
|
||||
|
||||
def literal_eval(node_or_string):
|
||||
@@ -59,11 +59,14 @@ def literal_eval(node_or_string):
|
||||
sets, booleans, and None.
|
||||
"""
|
||||
if isinstance(node_or_string, str):
|
||||
node_or_string = parse(node_or_string, mode='eval')
|
||||
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
|
||||
if isinstance(node_or_string, Expression):
|
||||
node_or_string = node_or_string.body
|
||||
def _raise_malformed_node(node):
|
||||
raise ValueError(f'malformed node or string: {node!r}')
|
||||
msg = "malformed node or string"
|
||||
if lno := getattr(node, 'lineno', None):
|
||||
msg += f' on line {lno}'
|
||||
raise ValueError(msg + f': {node!r}')
|
||||
def _convert_num(node):
|
||||
if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
|
||||
_raise_malformed_node(node)
|
||||
@@ -794,6 +797,9 @@ class _Unparser(NodeVisitor):
|
||||
else:
|
||||
super().visit(node)
|
||||
|
||||
# Note: as visit() resets the output text, do NOT rely on
|
||||
# NodeVisitor.generic_visit to handle any nodes (as it calls back in to
|
||||
# the subclass visit() method, which resets self._source to an empty list)
|
||||
def visit(self, node):
|
||||
"""Outputs a source code string that, if converted back to an ast
|
||||
(using ast.parse) will generate an AST equivalent to *node*"""
|
||||
@@ -1483,6 +1489,13 @@ class _Unparser(NodeVisitor):
|
||||
self.write(":")
|
||||
self.traverse(node.step)
|
||||
|
||||
def visit_Match(self, node):
|
||||
self.fill("match ")
|
||||
self.traverse(node.subject)
|
||||
with self.block():
|
||||
for case in node.cases:
|
||||
self.traverse(case)
|
||||
|
||||
def visit_arg(self, node):
|
||||
self.write(node.arg)
|
||||
if node.annotation:
|
||||
@@ -1567,6 +1580,94 @@ class _Unparser(NodeVisitor):
|
||||
self.write(" as ")
|
||||
self.traverse(node.optional_vars)
|
||||
|
||||
def visit_match_case(self, node):
|
||||
self.fill("case ")
|
||||
self.traverse(node.pattern)
|
||||
if node.guard:
|
||||
self.write(" if ")
|
||||
self.traverse(node.guard)
|
||||
with self.block():
|
||||
self.traverse(node.body)
|
||||
|
||||
def visit_MatchValue(self, node):
|
||||
self.traverse(node.value)
|
||||
|
||||
def visit_MatchSingleton(self, node):
|
||||
self._write_constant(node.value)
|
||||
|
||||
def visit_MatchSequence(self, node):
|
||||
with self.delimit("[", "]"):
|
||||
self.interleave(
|
||||
lambda: self.write(", "), self.traverse, node.patterns
|
||||
)
|
||||
|
||||
def visit_MatchStar(self, node):
|
||||
name = node.name
|
||||
if name is None:
|
||||
name = "_"
|
||||
self.write(f"*{name}")
|
||||
|
||||
def visit_MatchMapping(self, node):
|
||||
def write_key_pattern_pair(pair):
|
||||
k, p = pair
|
||||
self.traverse(k)
|
||||
self.write(": ")
|
||||
self.traverse(p)
|
||||
|
||||
with self.delimit("{", "}"):
|
||||
keys = node.keys
|
||||
self.interleave(
|
||||
lambda: self.write(", "),
|
||||
write_key_pattern_pair,
|
||||
zip(keys, node.patterns, strict=True),
|
||||
)
|
||||
rest = node.rest
|
||||
if rest is not None:
|
||||
if keys:
|
||||
self.write(", ")
|
||||
self.write(f"**{rest}")
|
||||
|
||||
def visit_MatchClass(self, node):
|
||||
self.set_precedence(_Precedence.ATOM, node.cls)
|
||||
self.traverse(node.cls)
|
||||
with self.delimit("(", ")"):
|
||||
patterns = node.patterns
|
||||
self.interleave(
|
||||
lambda: self.write(", "), self.traverse, patterns
|
||||
)
|
||||
attrs = node.kwd_attrs
|
||||
if attrs:
|
||||
def write_attr_pattern(pair):
|
||||
attr, pattern = pair
|
||||
self.write(f"{attr}=")
|
||||
self.traverse(pattern)
|
||||
|
||||
if patterns:
|
||||
self.write(", ")
|
||||
self.interleave(
|
||||
lambda: self.write(", "),
|
||||
write_attr_pattern,
|
||||
zip(attrs, node.kwd_patterns, strict=True),
|
||||
)
|
||||
|
||||
def visit_MatchAs(self, node):
|
||||
name = node.name
|
||||
pattern = node.pattern
|
||||
if name is None:
|
||||
self.write("_")
|
||||
elif pattern is None:
|
||||
self.write(node.name)
|
||||
else:
|
||||
with self.require_parens(_Precedence.TEST, node):
|
||||
self.set_precedence(_Precedence.BOR, node.pattern)
|
||||
self.traverse(node.pattern)
|
||||
self.write(f" as {node.name}")
|
||||
|
||||
def visit_MatchOr(self, node):
|
||||
with self.require_parens(_Precedence.BOR, node):
|
||||
self.set_precedence(_Precedence.BOR.next(), *node.patterns)
|
||||
self.interleave(lambda: self.write(" | "), self.traverse, node.patterns)
|
||||
|
||||
def unparse(ast_obj):
|
||||
unparser = _Unparser()
|
||||
return unparser.visit(ast_obj)
|
||||
|
||||
700
Lib/test/test_ast.py
vendored
700
Lib/test/test_ast.py
vendored
@@ -1,7 +1,9 @@
|
||||
import ast
|
||||
import builtins
|
||||
import dis
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
import weakref
|
||||
@@ -17,6 +19,8 @@ def to_tuple(t):
|
||||
result = [t.__class__.__name__]
|
||||
if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
|
||||
result.append((t.lineno, t.col_offset))
|
||||
if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
|
||||
result[-1] += (t.end_lineno, t.end_col_offset)
|
||||
if t._fields is None:
|
||||
return tuple(result)
|
||||
for f in t._fields:
|
||||
@@ -245,6 +249,13 @@ eval_tests = [
|
||||
|
||||
class AST_Tests(unittest.TestCase):
|
||||
|
||||
def _is_ast_node(self, name, node):
|
||||
if not isinstance(node, type):
|
||||
return False
|
||||
if "ast" not in node.__module__:
|
||||
return False
|
||||
return name != 'AST' and name[0].isupper()
|
||||
|
||||
def _assertTrueorder(self, ast_node, parent_pos):
|
||||
if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
|
||||
return
|
||||
@@ -262,6 +273,7 @@ class AST_Tests(unittest.TestCase):
|
||||
self._assertTrueorder(child, first_pos)
|
||||
elif value is not None:
|
||||
self._assertTrueorder(value, parent_pos)
|
||||
self.assertEqual(ast_node._fields, ast_node.__match_args__)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@@ -276,7 +288,7 @@ class AST_Tests(unittest.TestCase):
|
||||
x.vararg
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
# "_ast.AST constructor takes 0 positional arguments"
|
||||
# "ast.AST constructor takes 0 positional arguments"
|
||||
ast.AST(2)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@@ -329,6 +341,28 @@ class AST_Tests(unittest.TestCase):
|
||||
mod.body[0].module = " __future__ ".strip()
|
||||
compile(mod, "<test>", "exec")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_alias(self):
|
||||
im = ast.parse("from bar import y").body[0]
|
||||
self.assertEqual(len(im.names), 1)
|
||||
alias = im.names[0]
|
||||
self.assertEqual(alias.name, 'y')
|
||||
self.assertIsNone(alias.asname)
|
||||
self.assertEqual(alias.lineno, 1)
|
||||
self.assertEqual(alias.end_lineno, 1)
|
||||
self.assertEqual(alias.col_offset, 16)
|
||||
self.assertEqual(alias.end_col_offset, 17)
|
||||
|
||||
im = ast.parse("from bar import *").body[0]
|
||||
alias = im.names[0]
|
||||
self.assertEqual(alias.name, '*')
|
||||
self.assertIsNone(alias.asname)
|
||||
self.assertEqual(alias.lineno, 1)
|
||||
self.assertEqual(alias.end_lineno, 1)
|
||||
self.assertEqual(alias.col_offset, 16)
|
||||
self.assertEqual(alias.end_col_offset, 17)
|
||||
|
||||
def test_base_classes(self):
|
||||
self.assertTrue(issubclass(ast.For, ast.stmt))
|
||||
self.assertTrue(issubclass(ast.Name, ast.expr))
|
||||
@@ -341,7 +375,11 @@ class AST_Tests(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
def test_field_attr_existence(self):
|
||||
for name, item in ast.__dict__.items():
|
||||
if isinstance(item, type) and name != 'AST' and name[0].isupper():
|
||||
if self._is_ast_node(name, item):
|
||||
if name == 'Index':
|
||||
# Index(value) just returns value now.
|
||||
# The argument is required.
|
||||
continue
|
||||
x = item()
|
||||
if isinstance(x, ast.AST):
|
||||
self.assertEqual(type(x._fields), tuple)
|
||||
@@ -354,9 +392,11 @@ class AST_Tests(unittest.TestCase):
|
||||
'kw_defaults', 'kwarg', 'defaults'))
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
x.vararg
|
||||
x.args
|
||||
self.assertIsNone(x.vararg)
|
||||
|
||||
x = ast.arguments(*range(1, 8))
|
||||
self.assertEqual(x.args, 2)
|
||||
self.assertEqual(x.vararg, 3)
|
||||
|
||||
def test_field_attr_writable(self):
|
||||
@@ -587,17 +627,26 @@ class AST_Tests(unittest.TestCase):
|
||||
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
compile(m, "<test>", "exec")
|
||||
self.assertIn("but got <_ast.expr", str(cm.exception))
|
||||
self.assertIn("but got <ast.expr", str(cm.exception))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_invalid_identitifer(self):
|
||||
def test_invalid_identifier(self):
|
||||
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
|
||||
ast.fix_missing_locations(m)
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
compile(m, "<test>", "exec")
|
||||
self.assertIn("identifier must be of type str", str(cm.exception))
|
||||
|
||||
def test_invalid_constant(self):
|
||||
for invalid_constant in int, (1, 2, int), frozenset((1, 2, int)):
|
||||
e = ast.Expression(body=ast.Constant(invalid_constant))
|
||||
ast.fix_missing_locations(e)
|
||||
with self.assertRaisesRegex(
|
||||
TypeError, "invalid type in Constant: type"
|
||||
):
|
||||
compile(e, "<test>", "eval")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_empty_yield_from(self):
|
||||
@@ -606,7 +655,7 @@ class AST_Tests(unittest.TestCase):
|
||||
empty_yield_from.body[0].body[0].value.value = None
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
compile(empty_yield_from, "<test>", "exec")
|
||||
self.assertIn("field value is required", str(cm.exception))
|
||||
self.assertIn("field 'value' is required", str(cm.exception))
|
||||
|
||||
@support.cpython_only
|
||||
def test_issue31592(self):
|
||||
@@ -658,6 +707,27 @@ class AST_Tests(unittest.TestCase):
|
||||
attr_b = tree.body[0].decorator_list[0].value
|
||||
self.assertEqual(attr_b.end_col_offset, 4)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_ast_asdl_signature(self):
|
||||
self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
|
||||
self.assertEqual(ast.GtE.__doc__, "GtE")
|
||||
self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
|
||||
self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
|
||||
expressions = [f" | {node.__doc__}" for node in ast.expr.__subclasses__()]
|
||||
expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
|
||||
self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_parenthesized_with_feature_version(self):
|
||||
ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10))
|
||||
# While advertised as a feature in Python 3.10, this was allowed starting 3.9
|
||||
ast.parse('with (CtxManager() as example): ...', feature_version=(3, 9))
|
||||
with self.assertRaises(SyntaxError):
|
||||
ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8))
|
||||
ast.parse('with CtxManager() as example: ...', feature_version=(3, 8))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_issue40614_feature_version(self):
|
||||
@@ -665,13 +735,20 @@ class AST_Tests(unittest.TestCase):
|
||||
with self.assertRaises(SyntaxError):
|
||||
ast.parse('f"{x=}"', feature_version=(3, 7))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_assignment_expression_feature_version(self):
|
||||
ast.parse('(x := 0)', feature_version=(3, 8))
|
||||
with self.assertRaises(SyntaxError):
|
||||
ast.parse('(x := 0)', feature_version=(3, 7))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_constant_as_name(self):
|
||||
for constant in "True", "False", "None":
|
||||
expr = ast.Expression(ast.Name(constant, ast.Load()))
|
||||
ast.fix_missing_locations(expr)
|
||||
with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"):
|
||||
with self.assertRaisesRegex(ValueError, f"identifier field can't represent '{constant}' constant"):
|
||||
compile(expr, "<test>", "eval")
|
||||
|
||||
|
||||
@@ -699,23 +776,86 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
node = ast.parse('spam(eggs, "and cheese")')
|
||||
self.assertEqual(ast.dump(node),
|
||||
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
|
||||
"args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], "
|
||||
"args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
|
||||
"keywords=[]))], type_ignores=[])"
|
||||
)
|
||||
self.assertEqual(ast.dump(node, annotate_fields=False),
|
||||
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
|
||||
"Constant('and cheese', None)], []))], [])"
|
||||
"Constant('and cheese')], []))], [])"
|
||||
)
|
||||
self.assertEqual(ast.dump(node, include_attributes=True),
|
||||
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
|
||||
"args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
|
||||
"end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, "
|
||||
"end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
|
||||
"lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON; redundant kind for Contant node
|
||||
@unittest.expectedFailure
|
||||
def test_dump_indent(self):
|
||||
node = ast.parse('spam(eggs, "and cheese")')
|
||||
self.assertEqual(ast.dump(node, indent=3), """\
|
||||
Module(
|
||||
body=[
|
||||
Expr(
|
||||
value=Call(
|
||||
func=Name(id='spam', ctx=Load()),
|
||||
args=[
|
||||
Name(id='eggs', ctx=Load()),
|
||||
Constant(value='and cheese')],
|
||||
keywords=[]))],
|
||||
type_ignores=[])""")
|
||||
self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
|
||||
Module(
|
||||
\t[
|
||||
\t\tExpr(
|
||||
\t\t\tCall(
|
||||
\t\t\t\tName('spam', Load()),
|
||||
\t\t\t\t[
|
||||
\t\t\t\t\tName('eggs', Load()),
|
||||
\t\t\t\t\tConstant('and cheese')],
|
||||
\t\t\t\t[]))],
|
||||
\t[])""")
|
||||
self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
|
||||
Module(
|
||||
body=[
|
||||
Expr(
|
||||
value=Call(
|
||||
func=Name(
|
||||
id='spam',
|
||||
ctx=Load(),
|
||||
lineno=1,
|
||||
col_offset=0,
|
||||
end_lineno=1,
|
||||
end_col_offset=4),
|
||||
args=[
|
||||
Name(
|
||||
id='eggs',
|
||||
ctx=Load(),
|
||||
lineno=1,
|
||||
col_offset=5,
|
||||
end_lineno=1,
|
||||
end_col_offset=9),
|
||||
Constant(
|
||||
value='and cheese',
|
||||
lineno=1,
|
||||
col_offset=11,
|
||||
end_lineno=1,
|
||||
end_col_offset=23)],
|
||||
keywords=[],
|
||||
lineno=1,
|
||||
col_offset=0,
|
||||
end_lineno=1,
|
||||
end_col_offset=24),
|
||||
lineno=1,
|
||||
col_offset=0,
|
||||
end_lineno=1,
|
||||
end_col_offset=24)],
|
||||
type_ignores=[])""")
|
||||
|
||||
def test_dump_incomplete(self):
|
||||
node = ast.Raise(lineno=3, col_offset=4)
|
||||
self.assertEqual(ast.dump(node),
|
||||
@@ -751,16 +891,13 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
src = ast.parse('1 + 1', mode='eval')
|
||||
src.body.right = ast.copy_location(ast.Num(2), src.body.right)
|
||||
self.assertEqual(ast.dump(src, include_attributes=True),
|
||||
'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
|
||||
'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
|
||||
'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
|
||||
'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
|
||||
'col_offset=0, end_lineno=1, end_col_offset=5))'
|
||||
)
|
||||
src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1)
|
||||
new = ast.copy_location(src, ast.Call(
|
||||
col_offset=None, lineno=None,
|
||||
end_lineno=None, end_col_offset=None
|
||||
))
|
||||
new = ast.copy_location(src, ast.Call(col_offset=None, lineno=None))
|
||||
self.assertIsNone(new.end_lineno)
|
||||
self.assertIsNone(new.end_col_offset)
|
||||
self.assertEqual(new.lineno, 1)
|
||||
@@ -777,7 +914,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
self.assertEqual(ast.dump(src, include_attributes=True),
|
||||
"Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
|
||||
"args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
|
||||
"args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
|
||||
"end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
|
||||
"end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
|
||||
"end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
|
||||
@@ -794,8 +931,8 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
src = ast.parse('1 + 1', mode='eval')
|
||||
self.assertEqual(ast.increment_lineno(src, n=3), src)
|
||||
self.assertEqual(ast.dump(src, include_attributes=True),
|
||||
'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
|
||||
'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
|
||||
'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
|
||||
'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
|
||||
'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
|
||||
'col_offset=0, end_lineno=4, end_col_offset=5))'
|
||||
)
|
||||
@@ -803,14 +940,13 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
src = ast.parse('1 + 1', mode='eval')
|
||||
self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
|
||||
self.assertEqual(ast.dump(src, include_attributes=True),
|
||||
'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
|
||||
'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
|
||||
'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
|
||||
'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
|
||||
'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
|
||||
'col_offset=0, end_lineno=4, end_col_offset=5))'
|
||||
)
|
||||
src = ast.Call(
|
||||
func=ast.Name("test", ast.Load()), args=[], keywords=[],
|
||||
lineno=1, end_lineno=None
|
||||
func=ast.Name("test", ast.Load()), args=[], keywords=[], lineno=1
|
||||
)
|
||||
self.assertEqual(ast.increment_lineno(src).lineno, 2)
|
||||
self.assertIsNone(ast.increment_lineno(src).end_lineno)
|
||||
@@ -821,6 +957,8 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
self.assertEqual(d.pop('func').id, 'foo')
|
||||
self.assertEqual(d, {'keywords': [], 'args': []})
|
||||
|
||||
# TODO: RUSTPYTHON; redundant kind for Contant node
|
||||
@unittest.expectedFailure
|
||||
def test_iter_child_nodes(self):
|
||||
node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
|
||||
self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
|
||||
@@ -829,7 +967,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
self.assertEqual(next(iterator).value, 23)
|
||||
self.assertEqual(next(iterator).value, 42)
|
||||
self.assertEqual(ast.dump(next(iterator)),
|
||||
"keyword(arg='eggs', value=Constant(value='leek', kind=None))"
|
||||
"keyword(arg='eggs', value=Constant(value='leek'))"
|
||||
)
|
||||
|
||||
def test_get_docstring(self):
|
||||
@@ -923,6 +1061,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
|
||||
self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
|
||||
self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
|
||||
self.assertEqual(ast.literal_eval('set()'), set())
|
||||
self.assertRaises(ValueError, ast.literal_eval, 'foo()')
|
||||
self.assertEqual(ast.literal_eval('6'), 6)
|
||||
self.assertEqual(ast.literal_eval('+6'), 6)
|
||||
@@ -962,6 +1101,35 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
|
||||
self.assertRaises(ValueError, ast.literal_eval, malformed)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_literal_eval_trailing_ws(self):
|
||||
self.assertEqual(ast.literal_eval(" -1"), -1)
|
||||
self.assertEqual(ast.literal_eval("\t\t-1"), -1)
|
||||
self.assertEqual(ast.literal_eval(" \t -1"), -1)
|
||||
self.assertRaises(IndentationError, ast.literal_eval, "\n -1")
|
||||
|
||||
def test_literal_eval_malformed_lineno(self):
|
||||
msg = r'malformed node or string on line 3:'
|
||||
with self.assertRaisesRegex(ValueError, msg):
|
||||
ast.literal_eval("{'a': 1,\n'b':2,\n'c':++3,\n'd':4}")
|
||||
|
||||
node = ast.UnaryOp(
|
||||
ast.UAdd(), ast.UnaryOp(ast.UAdd(), ast.Constant(6)))
|
||||
self.assertIsNone(getattr(node, 'lineno', None))
|
||||
msg = r'malformed node or string:'
|
||||
with self.assertRaisesRegex(ValueError, msg):
|
||||
ast.literal_eval(node)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_literal_eval_syntax_errors(self):
|
||||
with self.assertRaisesRegex(SyntaxError, "unexpected indent"):
|
||||
ast.literal_eval(r'''
|
||||
\
|
||||
(\
|
||||
\ ''')
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_bad_integer(self):
|
||||
@@ -975,11 +1143,10 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
compile(mod, 'test', 'exec')
|
||||
self.assertIn("invalid integer value: None", str(cm.exception))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_level_as_none(self):
|
||||
body = [ast.ImportFrom(module='time',
|
||||
names=[ast.alias(name='sleep')],
|
||||
names=[ast.alias(name='sleep',
|
||||
lineno=0, col_offset=0)],
|
||||
level=None,
|
||||
lineno=0, col_offset=0)]
|
||||
mod = ast.Module(body, [])
|
||||
@@ -988,6 +1155,24 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||
exec(code, ns)
|
||||
self.assertIn('sleep', ns)
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON; crash")
|
||||
def test_recursion_direct(self):
|
||||
e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
|
||||
e.operand = e
|
||||
with self.assertRaises(RecursionError):
|
||||
with support.infinite_recursion():
|
||||
compile(ast.Expression(e), "<test>", "eval")
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON; crash")
|
||||
def test_recursion_indirect(self):
|
||||
e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
|
||||
f = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
|
||||
e.operand = f
|
||||
f.operand = e
|
||||
with self.assertRaises(RecursionError):
|
||||
with support.infinite_recursion():
|
||||
compile(ast.Expression(e), "<test>", "eval")
|
||||
|
||||
|
||||
class ASTValidatorTests(unittest.TestCase):
|
||||
|
||||
@@ -1398,11 +1583,11 @@ class ASTValidatorTests(unittest.TestCase):
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_subscript(self):
|
||||
sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
|
||||
sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
|
||||
ast.Load())
|
||||
self.expr(sub, "must have Load context")
|
||||
x = ast.Name("x", ast.Load())
|
||||
sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
|
||||
sub = ast.Subscript(x, ast.Name("y", ast.Store()),
|
||||
ast.Load())
|
||||
self.expr(sub, "must have Load context")
|
||||
s = ast.Name("x", ast.Store())
|
||||
@@ -1410,9 +1595,9 @@ class ASTValidatorTests(unittest.TestCase):
|
||||
sl = ast.Slice(*args)
|
||||
self.expr(ast.Subscript(x, sl, ast.Load()),
|
||||
"must have Load context")
|
||||
sl = ast.ExtSlice([])
|
||||
self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
|
||||
sl = ast.ExtSlice([ast.Index(s)])
|
||||
sl = ast.Tuple([], ast.Load())
|
||||
self.expr(ast.Subscript(x, sl, ast.Load()))
|
||||
sl = ast.Tuple([s], ast.Load())
|
||||
self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@@ -1455,6 +1640,151 @@ class ASTValidatorTests(unittest.TestCase):
|
||||
mod = ast.parse(source, fn)
|
||||
compile(mod, fn, "exec")
|
||||
|
||||
constant_1 = ast.Constant(1)
|
||||
pattern_1 = ast.MatchValue(constant_1)
|
||||
|
||||
constant_x = ast.Constant('x')
|
||||
pattern_x = ast.MatchValue(constant_x)
|
||||
|
||||
constant_true = ast.Constant(True)
|
||||
pattern_true = ast.MatchSingleton(True)
|
||||
|
||||
name_carter = ast.Name('carter', ast.Load())
|
||||
|
||||
_MATCH_PATTERNS = [
|
||||
ast.MatchValue(
|
||||
ast.Attribute(
|
||||
ast.Attribute(
|
||||
ast.Name('x', ast.Store()),
|
||||
'y', ast.Load()
|
||||
),
|
||||
'z', ast.Load()
|
||||
)
|
||||
),
|
||||
ast.MatchValue(
|
||||
ast.Attribute(
|
||||
ast.Attribute(
|
||||
ast.Name('x', ast.Load()),
|
||||
'y', ast.Store()
|
||||
),
|
||||
'z', ast.Load()
|
||||
)
|
||||
),
|
||||
ast.MatchValue(
|
||||
ast.Constant(...)
|
||||
),
|
||||
ast.MatchValue(
|
||||
ast.Constant(True)
|
||||
),
|
||||
ast.MatchValue(
|
||||
ast.Constant((1,2,3))
|
||||
),
|
||||
ast.MatchSingleton('string'),
|
||||
ast.MatchSequence([
|
||||
ast.MatchSingleton('string')
|
||||
]),
|
||||
ast.MatchSequence(
|
||||
[
|
||||
ast.MatchSequence(
|
||||
[
|
||||
ast.MatchSingleton('string')
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
ast.MatchMapping(
|
||||
[constant_1, constant_true],
|
||||
[pattern_x]
|
||||
),
|
||||
ast.MatchMapping(
|
||||
[constant_true, constant_1],
|
||||
[pattern_x, pattern_1],
|
||||
rest='True'
|
||||
),
|
||||
ast.MatchMapping(
|
||||
[constant_true, ast.Starred(ast.Name('lol', ast.Load()), ast.Load())],
|
||||
[pattern_x, pattern_1],
|
||||
rest='legit'
|
||||
),
|
||||
ast.MatchClass(
|
||||
ast.Attribute(
|
||||
ast.Attribute(
|
||||
constant_x,
|
||||
'y', ast.Load()),
|
||||
'z', ast.Load()),
|
||||
patterns=[], kwd_attrs=[], kwd_patterns=[]
|
||||
),
|
||||
ast.MatchClass(
|
||||
name_carter,
|
||||
patterns=[],
|
||||
kwd_attrs=['True'],
|
||||
kwd_patterns=[pattern_1]
|
||||
),
|
||||
ast.MatchClass(
|
||||
name_carter,
|
||||
patterns=[],
|
||||
kwd_attrs=[],
|
||||
kwd_patterns=[pattern_1]
|
||||
),
|
||||
ast.MatchClass(
|
||||
name_carter,
|
||||
patterns=[ast.MatchSingleton('string')],
|
||||
kwd_attrs=[],
|
||||
kwd_patterns=[]
|
||||
),
|
||||
ast.MatchClass(
|
||||
name_carter,
|
||||
patterns=[ast.MatchStar()],
|
||||
kwd_attrs=[],
|
||||
kwd_patterns=[]
|
||||
),
|
||||
ast.MatchClass(
|
||||
name_carter,
|
||||
patterns=[],
|
||||
kwd_attrs=[],
|
||||
kwd_patterns=[ast.MatchStar()]
|
||||
),
|
||||
ast.MatchSequence(
|
||||
[
|
||||
ast.MatchStar("True")
|
||||
]
|
||||
),
|
||||
ast.MatchAs(
|
||||
name='False'
|
||||
),
|
||||
ast.MatchOr(
|
||||
[]
|
||||
),
|
||||
ast.MatchOr(
|
||||
[pattern_1]
|
||||
),
|
||||
ast.MatchOr(
|
||||
[pattern_1, pattern_x, ast.MatchSingleton('xxx')]
|
||||
),
|
||||
ast.MatchAs(name="_"),
|
||||
ast.MatchStar(name="x"),
|
||||
ast.MatchSequence([ast.MatchStar("_")]),
|
||||
ast.MatchMapping([], [], rest="_"),
|
||||
]
|
||||
|
||||
def test_match_validation_pattern(self):
|
||||
name_x = ast.Name('x', ast.Load())
|
||||
for pattern in self._MATCH_PATTERNS:
|
||||
with self.subTest(ast.dump(pattern, indent=4)):
|
||||
node = ast.Match(
|
||||
subject=name_x,
|
||||
cases = [
|
||||
ast.match_case(
|
||||
pattern=pattern,
|
||||
body = [ast.Pass()]
|
||||
)
|
||||
]
|
||||
)
|
||||
node = ast.fix_missing_locations(node)
|
||||
module = ast.Module([node], [])
|
||||
with self.assertRaises(ValueError):
|
||||
compile(module, "<test>", "exec")
|
||||
|
||||
|
||||
class ConstantTests(unittest.TestCase):
|
||||
"""Tests on the ast.Constant node type."""
|
||||
@@ -1783,6 +2113,7 @@ class EndPositionTests(unittest.TestCase):
|
||||
''').strip()
|
||||
imp = ast.parse(s).body[0]
|
||||
self._check_end_pos(imp, 3, 1)
|
||||
self._check_end_pos(imp.names[2], 2, 16)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@@ -1796,11 +2127,11 @@ class EndPositionTests(unittest.TestCase):
|
||||
''').strip()
|
||||
i1, i2, im = map(self._parse_value, (s1, s2, sm))
|
||||
self._check_content(s1, i1.value, 'f()[1, 2]')
|
||||
self._check_content(s1, i1.value.slice.value, '1, 2')
|
||||
self._check_content(s1, i1.value.slice, '1, 2')
|
||||
self._check_content(s2, i2.slice.lower, 'a.b')
|
||||
self._check_content(s2, i2.slice.upper, 'c.d')
|
||||
self._check_content(sm, im.slice.dims[0].upper, 'f ()')
|
||||
self._check_content(sm, im.slice.dims[1].lower, 'g ()')
|
||||
self._check_content(sm, im.slice.elts[0].upper, 'f ()')
|
||||
self._check_content(sm, im.slice.elts[1].lower, 'g ()')
|
||||
self._check_end_pos(im, 3, 3)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@@ -1980,6 +2311,19 @@ class EndPositionTests(unittest.TestCase):
|
||||
cdef = ast.parse(s).body[0]
|
||||
self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_source_segment_missing_info(self):
|
||||
s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
|
||||
v, w, x, y = ast.parse(s).body
|
||||
del v.lineno
|
||||
del w.end_lineno
|
||||
del x.col_offset
|
||||
del y.end_col_offset
|
||||
self.assertIsNone(ast.get_source_segment(s, v))
|
||||
self.assertIsNone(ast.get_source_segment(s, w))
|
||||
self.assertIsNone(ast.get_source_segment(s, x))
|
||||
self.assertIsNone(ast.get_source_segment(s, y))
|
||||
|
||||
class NodeVisitorTests(unittest.TestCase):
|
||||
def test_old_constant_nodes(self):
|
||||
@@ -2031,6 +2375,88 @@ class NodeVisitorTests(unittest.TestCase):
|
||||
])
|
||||
|
||||
|
||||
@support.cpython_only
|
||||
class ModuleStateTests(unittest.TestCase):
|
||||
# bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state.
|
||||
|
||||
def check_ast_module(self):
|
||||
# Check that the _ast module still works as expected
|
||||
code = 'x + 1'
|
||||
filename = '<string>'
|
||||
mode = 'eval'
|
||||
|
||||
# Create _ast.AST subclasses instances
|
||||
ast_tree = compile(code, filename, mode, flags=ast.PyCF_ONLY_AST)
|
||||
|
||||
# Call PyAST_Check()
|
||||
code = compile(ast_tree, filename, mode)
|
||||
self.assertIsInstance(code, types.CodeType)
|
||||
|
||||
def test_reload_module(self):
|
||||
# bpo-41194: Importing the _ast module twice must not crash.
|
||||
with support.swap_item(sys.modules, '_ast', None):
|
||||
del sys.modules['_ast']
|
||||
import _ast as ast1
|
||||
|
||||
del sys.modules['_ast']
|
||||
import _ast as ast2
|
||||
|
||||
self.check_ast_module()
|
||||
|
||||
# Unloading the two _ast module instances must not crash.
|
||||
del ast1
|
||||
del ast2
|
||||
support.gc_collect()
|
||||
|
||||
self.check_ast_module()
|
||||
|
||||
def test_sys_modules(self):
|
||||
# bpo-41631: Test reproducing a Mercurial crash when PyAST_Check()
|
||||
# imported the _ast module internally.
|
||||
lazy_mod = object()
|
||||
|
||||
def my_import(name, *args, **kw):
|
||||
sys.modules[name] = lazy_mod
|
||||
return lazy_mod
|
||||
|
||||
with support.swap_item(sys.modules, '_ast', None):
|
||||
del sys.modules['_ast']
|
||||
|
||||
with support.swap_attr(builtins, '__import__', my_import):
|
||||
# Test that compile() does not import the _ast module
|
||||
self.check_ast_module()
|
||||
self.assertNotIn('_ast', sys.modules)
|
||||
|
||||
# Sanity check of the test itself
|
||||
import _ast
|
||||
self.assertIs(_ast, lazy_mod)
|
||||
|
||||
def test_subinterpreter(self):
|
||||
# bpo-41631: Importing and using the _ast module in a subinterpreter
|
||||
# must not crash.
|
||||
code = dedent('''
|
||||
import _ast
|
||||
import ast
|
||||
import gc
|
||||
import sys
|
||||
import types
|
||||
|
||||
# Create _ast.AST subclasses instances and call PyAST_Check()
|
||||
ast_tree = compile('x+1', '<string>', 'eval',
|
||||
flags=ast.PyCF_ONLY_AST)
|
||||
code = compile(ast_tree, 'string', 'eval')
|
||||
if not isinstance(code, types.CodeType):
|
||||
raise AssertionError
|
||||
|
||||
# Unloading the _ast module must not crash.
|
||||
del ast, _ast
|
||||
del sys.modules['ast'], sys.modules['_ast']
|
||||
gc.collect()
|
||||
''')
|
||||
res = support.run_in_subinterp(code)
|
||||
self.assertEqual(res, 0)
|
||||
|
||||
|
||||
def main():
|
||||
if __name__ != '__main__':
|
||||
return
|
||||
@@ -2048,112 +2474,112 @@ def main():
|
||||
|
||||
#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
|
||||
exec_results = [
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 0, None)]), [('Pass', (1, 12))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42, None)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1, None), ('Constant', (1, 16), None, None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()', None))], [], None, None)], []),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1, None))], [], None, None)], []),
|
||||
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []),
|
||||
('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []),
|
||||
('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []),
|
||||
('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
|
||||
('Module', [('Assign', (1, 0), [('List', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
|
||||
('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1, None))], []),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
|
||||
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
|
||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
|
||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])], []),
|
||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [('Pass', (6, 2))])])], []),
|
||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
|
||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))], None)], []),
|
||||
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string', None)], []), None)], []),
|
||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []),
|
||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []),
|
||||
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []),
|
||||
('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []),
|
||||
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []),
|
||||
('Module', [('Global', (1, 0), ['v'])], []),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1, None))], []),
|
||||
('Module', [('Pass', (1, 0))], []),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('List', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
|
||||
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0), ('Tuple', (2, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function', None)), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1, None))], [('Expr', (3, 7), ('Constant', (3, 7), 2, None))], None)], [], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1, None))], None)], [], None, None)], []),
|
||||
('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2, None)], [('Dict', (1, 3), [('Constant', (1, 4), 1, None)], [('Constant', (1, 6), 2, None)]), ('Constant', (1, 12), 3, None)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1, None), ('Constant', (1, 6), 2, None)]), ('Load',)), ('Constant', (1, 10), 3, None)]))], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []),
|
||||
('Module', [('ClassDef', (4, 0), 'C', [], [], [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])])], []),
|
||||
('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
|
||||
('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Attribute', (1, 1), ('Attribute', (1, 1), ('Name', (1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
|
||||
('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None), ('arg', (1, 15), 'd', None, None), ('arg', (1, 18), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], ('arg', (1, 26), 'kwargs', None, None), []), [('Pass', (1, 35))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None), ('arg', (1, 19), 'c', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None), ('Constant', (1, 21), 4, None)]), [('Pass', (1, 25))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 28))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 26))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], ('arg', (1, 29), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 38))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], ('arg', (1, 27), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 36))], [], None, None)], []),
|
||||
('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
|
||||
('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
|
||||
('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
|
||||
('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
|
||||
('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
|
||||
('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
|
||||
('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
|
||||
('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []),
|
||||
('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
|
||||
('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
|
||||
('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
|
||||
('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []),
|
||||
('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
|
||||
('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
|
||||
('Module', [('If', (1, 0, 4, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 4, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [])])], []),
|
||||
('Module', [('If', (1, 0, 6, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 6, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [('Pass', (6, 2, 6, 6))])])], []),
|
||||
('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',)))], [('Pass', (1, 13, 1, 17))], None)], []),
|
||||
('Module', [('With', (1, 0, 1, 25), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',))), ('withitem', ('Name', (1, 13, 1, 14), 'z', ('Load',)), ('Name', (1, 18, 1, 19), 'q', ('Store',)))], [('Pass', (1, 21, 1, 25))], None)], []),
|
||||
('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []),
|
||||
('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []),
|
||||
('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
|
||||
('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
|
||||
('Module', [('Import', (1, 0, 1, 10), [('alias', (1, 7, 1, 10), 'sys', None)])], []),
|
||||
('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', (1, 16, 1, 17), 'v', None)], 0)], []),
|
||||
('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
|
||||
('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
|
||||
('Module', [('Pass', (1, 0, 1, 4))], []),
|
||||
('Module', [('For', (1, 0, 1, 16), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Break', (1, 11, 1, 16))], [], None)], []),
|
||||
('Module', [('For', (1, 0, 1, 19), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Continue', (1, 11, 1, 19))], [], None)], []),
|
||||
('Module', [('For', (1, 0, 1, 18), ('Tuple', (1, 4, 1, 7), [('Name', (1, 4, 1, 5), 'a', ('Store',)), ('Name', (1, 6, 1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 11, 1, 12), 'c', ('Load',)), [('Pass', (1, 14, 1, 18))], [], None)], []),
|
||||
('Module', [('For', (1, 0, 1, 20), ('Tuple', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
|
||||
('Module', [('For', (1, 0, 1, 20), ('List', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
|
||||
('Module', [('Expr', (1, 0, 11, 5), ('GeneratorExp', (1, 0, 11, 5), ('Tuple', (2, 4, 6, 5), [('Name', (3, 4, 3, 6), 'Aa', ('Load',)), ('Name', (5, 7, 5, 9), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4, 10, 6), [('Name', (8, 4, 8, 6), 'Aa', ('Store',)), ('Name', (10, 4, 10, 6), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10, 10, 12), 'Cc', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0, 1, 34), ('DictComp', (1, 0, 1, 34), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Name', (1, 11, 1, 12), 'w', ('Store',)), ('Name', (1, 16, 1, 17), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22, 1, 23), 'm', ('Store',)), ('Name', (1, 27, 1, 28), 'p', ('Load',)), [('Name', (1, 32, 1, 33), 'g', ('Load',))], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0, 1, 20), ('DictComp', (1, 0, 1, 20), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'v', ('Store',)), ('Name', (1, 13, 1, 14), 'w', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'x', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0, 1, 19), ('SetComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 12, 1, 13), 'x', ('Load',)), [('Name', (1, 17, 1, 18), 'g', ('Load',))], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0, 1, 16), ('SetComp', (1, 0, 1, 16), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7, 1, 10), [('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 9, 1, 10), 'm', ('Store',))], ('Store',)), ('Name', (1, 14, 1, 15), 'x', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []),
|
||||
('Module', [('Expr', (1, 0, 1, 14), ('Dict', (1, 0, 1, 14), [None, ('Constant', (1, 10, 1, 11), 2, None)], [('Dict', (1, 3, 1, 8), [('Constant', (1, 4, 1, 5), 1, None)], [('Constant', (1, 6, 1, 7), 2, None)]), ('Constant', (1, 12, 1, 13), 3, None)]))], []),
|
||||
('Module', [('Expr', (1, 0, 1, 12), ('Set', (1, 0, 1, 12), [('Starred', (1, 1, 1, 8), ('Set', (1, 2, 1, 8), [('Constant', (1, 3, 1, 4), 1, None), ('Constant', (1, 6, 1, 7), 2, None)]), ('Load',)), ('Constant', (1, 10, 1, 11), 3, None)]))], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
|
||||
('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []),
|
||||
('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
|
||||
('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
|
||||
('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []),
|
||||
]
|
||||
single_results = [
|
||||
('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1, None), ('Add',), ('Constant', (1, 2), 2, None)))]),
|
||||
('Interactive', [('Expr', (1, 0, 1, 3), ('BinOp', (1, 0, 1, 3), ('Constant', (1, 0, 1, 1), 1, None), ('Add',), ('Constant', (1, 2, 1, 3), 2, None)))]),
|
||||
]
|
||||
eval_results = [
|
||||
('Expression', ('Constant', (1, 0), None, None)),
|
||||
('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
|
||||
('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
|
||||
('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
|
||||
('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))),
|
||||
('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])),
|
||||
('Expression', ('Dict', (1, 0), [], [])),
|
||||
('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])),
|
||||
('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1, None)], [('Constant', (4, 10), 2, None)])),
|
||||
('Expression', ('ListComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
|
||||
('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2, None), ('Constant', (1, 8), 3, None)])),
|
||||
('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Constant', (1, 2), 1, None), ('Constant', (1, 4), 2, None), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8), 3, None)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
|
||||
('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Starred', (1, 2), ('List', (1, 3), [('Constant', (1, 4), 0, None), ('Constant', (1, 7), 1, None)], ('Load',)), ('Load',))], [])),
|
||||
('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('GeneratorExp', (1, 1), ('Name', (1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 8), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Load',)), [], 0)])], [])),
|
||||
('Expression', ('Constant', (1, 0), 10, None)),
|
||||
('Expression', ('Constant', (1, 0), 'string', None)),
|
||||
('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
|
||||
('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
|
||||
('Expression', ('Name', (1, 0), 'v', ('Load',))),
|
||||
('Expression', ('List', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))),
|
||||
('Expression', ('List', (1, 0), [], ('Load',))),
|
||||
('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1, None), ('Constant', (1, 2), 2, None), ('Constant', (1, 4), 3, None)], ('Load',))),
|
||||
('Expression', ('Tuple', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))),
|
||||
('Expression', ('Tuple', (1, 0), [], ('Load',))),
|
||||
('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12), 1, None), ('Constant', (1, 14), 2, None), None), ('Load',))], [])),
|
||||
('Expression', ('Constant', (1, 0, 1, 4), None, None)),
|
||||
('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
|
||||
('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
|
||||
('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
|
||||
('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
|
||||
('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
|
||||
('Expression', ('Dict', (1, 0, 1, 2), [], [])),
|
||||
('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
|
||||
('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
|
||||
('Expression', ('ListComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
|
||||
('Expression', ('ListComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('SetComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
|
||||
('Expression', ('Compare', (1, 0, 1, 9), ('Constant', (1, 0, 1, 1), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4, 1, 5), 2, None), ('Constant', (1, 8, 1, 9), 3, None)])),
|
||||
('Expression', ('Call', (1, 0, 1, 17), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Constant', (1, 2, 1, 3), 1, None), ('Constant', (1, 4, 1, 5), 2, None), ('Starred', (1, 10, 1, 12), ('Name', (1, 11, 1, 12), 'd', ('Load',)), ('Load',))], [('keyword', (1, 6, 1, 9), 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', (1, 13, 1, 16), None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
|
||||
('Expression', ('Call', (1, 0, 1, 10), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Starred', (1, 2, 1, 9), ('List', (1, 3, 1, 9), [('Constant', (1, 4, 1, 5), 0, None), ('Constant', (1, 7, 1, 8), 1, None)], ('Load',)), ('Load',))], [])),
|
||||
('Expression', ('Call', (1, 0, 1, 15), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('GeneratorExp', (1, 1, 1, 15), ('Name', (1, 2, 1, 3), 'a', ('Load',)), [('comprehension', ('Name', (1, 8, 1, 9), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Load',)), [], 0)])], [])),
|
||||
('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
|
||||
('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
|
||||
('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
|
||||
('Expression', ('Subscript', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Slice', (1, 2, 1, 5), ('Name', (1, 2, 1, 3), 'b', ('Load',)), ('Name', (1, 4, 1, 5), 'c', ('Load',)), None), ('Load',))),
|
||||
('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
|
||||
('Expression', ('List', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
|
||||
('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
|
||||
('Expression', ('Tuple', (1, 0, 1, 5), [('Constant', (1, 0, 1, 1), 1, None), ('Constant', (1, 2, 1, 3), 2, None), ('Constant', (1, 4, 1, 5), 3, None)], ('Load',))),
|
||||
('Expression', ('Tuple', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
|
||||
('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
|
||||
('Expression', ('Call', (1, 0, 1, 17), ('Attribute', (1, 0, 1, 7), ('Attribute', (1, 0, 1, 5), ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8, 1, 16), ('Attribute', (1, 8, 1, 11), ('Name', (1, 8, 1, 9), 'a', ('Load',)), 'b', ('Load',)), ('Slice', (1, 12, 1, 15), ('Constant', (1, 12, 1, 13), 1, None), ('Constant', (1, 14, 1, 15), 2, None), None), ('Load',))], [])),
|
||||
]
|
||||
main()
|
||||
|
||||
103
Lib/test/test_future.py
vendored
103
Lib/test/test_future.py
vendored
@@ -38,53 +38,62 @@ class FutureTest(unittest.TestCase):
|
||||
with import_helper.CleanImport('test_future3'):
|
||||
from test import test_future3
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture3(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future3
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future3", 3)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture4(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future4
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future4", 3)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture5(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future5
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future5", 4)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture6(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future6
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future6", 3)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture7(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future7
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture8(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future8
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future8", 3)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture9(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future9
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future9", 3)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_badfuture10(self):
|
||||
with self.assertRaises(SyntaxError) as cm:
|
||||
from test import badsyntax_future10
|
||||
self.check_syntax_error(cm.exception, "badsyntax_future10", 3)
|
||||
|
||||
k, v = None, None # 'dictionary changed size during iteration'
|
||||
for k, v in locals().items():
|
||||
if k.startswith("test_badfuture"):
|
||||
# XXX RUSTPYTHON TODO: fix SyntaxError
|
||||
locals()[k] = unittest.expectedFailure(v)
|
||||
del k, v
|
||||
|
||||
def test_ensure_flags_dont_clash(self):
|
||||
# bpo-39562: test that future flags and compiler flags doesn't clash
|
||||
|
||||
@@ -141,8 +150,12 @@ class AnnotationsFutureTestCase(unittest.TestCase):
|
||||
...
|
||||
async def g2(arg: {ann}) -> None:
|
||||
...
|
||||
class H:
|
||||
var: {ann}
|
||||
object.attr: {ann}
|
||||
var: {ann}
|
||||
var2: {ann} = None
|
||||
object.attr: {ann}
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -174,6 +187,14 @@ class AnnotationsFutureTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def _exec_future(self, code):
|
||||
scope = {}
|
||||
exec(
|
||||
"from __future__ import annotations\n"
|
||||
+ code, {}, scope
|
||||
)
|
||||
return scope
|
||||
|
||||
def test_annotations(self):
|
||||
eq = self.assertAnnotationEqual
|
||||
eq('...')
|
||||
@@ -313,10 +334,6 @@ class AnnotationsFutureTestCase(unittest.TestCase):
|
||||
eq("f'{x}'")
|
||||
eq("f'{x!r}'")
|
||||
eq("f'{x!a}'")
|
||||
eq('(yield from outside_of_generator)')
|
||||
eq('(yield)')
|
||||
eq('(yield a + b)')
|
||||
eq('await some.complicated[0].call(with_args=True or 1 is not 1)')
|
||||
eq('[x for x in (a if b else c)]')
|
||||
eq('[x for x in a if (b if c else d)]')
|
||||
eq('f(x for x in a)')
|
||||
@@ -324,13 +341,11 @@ class AnnotationsFutureTestCase(unittest.TestCase):
|
||||
eq('f((x for x in a), 2)')
|
||||
eq('(((a)))', 'a')
|
||||
eq('(((a, b)))', '(a, b)')
|
||||
eq("(x := 10)")
|
||||
eq("f'{(x := 10):=10}'")
|
||||
eq("1 + 2 + 3")
|
||||
|
||||
def test_fstring_debug_annotations(self):
|
||||
# f-strings with '=' don't round trip very well, so set the expected
|
||||
# result explicitely.
|
||||
# result explicitly.
|
||||
self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'")
|
||||
self.assertAnnotationEqual("f'{x=:}'", expected="f'x={x:}'")
|
||||
self.assertAnnotationEqual("f'{x=:.2f}'", expected="f'x={x:.2f}'")
|
||||
@@ -350,6 +365,66 @@ class AnnotationsFutureTestCase(unittest.TestCase):
|
||||
self.assertAnnotationEqual("('inf', 1e1000, 'infxxx', 1e1000j)", expected=f"('inf', {inf}, 'infxxx', {infj})")
|
||||
self.assertAnnotationEqual("(1e1000, (1e1000j,))", expected=f"({inf}, ({infj},))")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_annotation_with_complex_target(self):
|
||||
with self.assertRaises(SyntaxError):
|
||||
exec(
|
||||
"from __future__ import annotations\n"
|
||||
"object.__debug__: int"
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_annotations_symbol_table_pass(self):
|
||||
namespace = self._exec_future(dedent("""
|
||||
from __future__ import annotations
|
||||
|
||||
def foo():
|
||||
outer = 1
|
||||
def bar():
|
||||
inner: outer = 1
|
||||
return bar
|
||||
"""))
|
||||
|
||||
foo = namespace.pop("foo")
|
||||
self.assertIsNone(foo().__closure__)
|
||||
self.assertEqual(foo.__code__.co_cellvars, ())
|
||||
self.assertEqual(foo().__code__.co_freevars, ())
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_annotations_forbidden(self):
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("test: (yield)")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("test.test: (yield a + b)")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("test[something]: (yield from x)")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("def func(test: (yield from outside_of_generator)): pass")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("def test() -> (await y): pass")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("async def test() -> something((a := b)): pass")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("test: await some.complicated[0].call(with_args=True or 1 is not 1)")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future("test: f'{(x := 10):=10}'")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
self._exec_future(dedent("""\
|
||||
def foo():
|
||||
def bar(arg: (yield)): pass
|
||||
"""))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -13,3 +13,4 @@ unparse = ["rustpython-common"]
|
||||
[dependencies]
|
||||
num-bigint = "0.4.3"
|
||||
rustpython-common = { path = "../common", optional = true }
|
||||
rustpython-bytecode = { path = "../bytecode"}
|
||||
|
||||
@@ -26,7 +26,7 @@ module Python
|
||||
| Assign(expr* targets, expr value, string? type_comment)
|
||||
| AugAssign(expr target, operator op, expr value)
|
||||
-- 'simple' indicates that we annotate simple name without parens
|
||||
| AnnAssign(expr target, expr annotation, expr? value, bool simple)
|
||||
| AnnAssign(expr target, expr annotation, expr? value, int simple)
|
||||
|
||||
-- use 'orelse' because else is a keyword in target languages
|
||||
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
|
||||
@@ -36,12 +36,14 @@ module Python
|
||||
| With(withitem* items, stmt* body, string? type_comment)
|
||||
| AsyncWith(withitem* items, stmt* body, string? type_comment)
|
||||
|
||||
| Match(expr subject, match_case* cases)
|
||||
|
||||
| Raise(expr? exc, expr? cause)
|
||||
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
|
||||
| Assert(expr test, expr? msg)
|
||||
|
||||
| Import(alias* names)
|
||||
| ImportFrom(identifier? module, alias* names, int level)
|
||||
| ImportFrom(identifier? module, alias* names, int? level)
|
||||
|
||||
| Global(identifier* names)
|
||||
| Nonlocal(identifier* names)
|
||||
@@ -58,7 +60,7 @@ module Python
|
||||
| UnaryOp(unaryop op, expr operand)
|
||||
| Lambda(arguments args, expr body)
|
||||
| IfExp(expr test, expr body, expr orelse)
|
||||
| Dict(expr?* keys, expr* values)
|
||||
| Dict(expr* keys, expr* values)
|
||||
| Set(expr* elts)
|
||||
| ListComp(expr elt, comprehension* generators)
|
||||
| SetComp(expr elt, comprehension* generators)
|
||||
@@ -72,7 +74,7 @@ module Python
|
||||
-- x < 4 < 3 and (x < 4) < 3
|
||||
| Compare(expr left, cmpop* ops, expr* comparators)
|
||||
| Call(expr func, expr* args, keyword* keywords)
|
||||
| FormattedValue(expr value, conversion_flag? conversion, expr? format_spec)
|
||||
| FormattedValue(expr value, int conversion, expr? format_spec)
|
||||
| JoinedStr(expr* values)
|
||||
| Constant(constant value, string? kind)
|
||||
|
||||
@@ -101,13 +103,13 @@ module Python
|
||||
|
||||
cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn
|
||||
|
||||
comprehension = (expr target, expr iter, expr* ifs, bool is_async)
|
||||
comprehension = (expr target, expr iter, expr* ifs, int is_async)
|
||||
|
||||
excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
|
||||
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
|
||||
|
||||
arguments = (arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs,
|
||||
expr?* kw_defaults, arg? kwarg, expr* defaults)
|
||||
expr* kw_defaults, arg? kwarg, expr* defaults)
|
||||
|
||||
arg = (identifier arg, expr? annotation, string? type_comment)
|
||||
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
|
||||
@@ -118,8 +120,25 @@ module Python
|
||||
|
||||
-- import name with optional 'as' alias.
|
||||
alias = (identifier name, identifier? asname)
|
||||
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
|
||||
|
||||
withitem = (expr context_expr, expr? optional_vars)
|
||||
|
||||
match_case = (pattern pattern, expr? guard, stmt* body)
|
||||
|
||||
pattern = MatchValue(expr value)
|
||||
| MatchSingleton(constant value)
|
||||
| MatchSequence(pattern* patterns)
|
||||
| MatchMapping(expr* keys, pattern* patterns, identifier? rest)
|
||||
| MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)
|
||||
|
||||
| MatchStar(identifier? name)
|
||||
-- The optional "rest" MatchMapping parameter handles capturing extra mapping keys
|
||||
|
||||
| MatchAs(pattern? pattern, identifier? name)
|
||||
| MatchOr(pattern* patterns)
|
||||
|
||||
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
|
||||
|
||||
type_ignore = TypeIgnore(int lineno, string tag)
|
||||
}
|
||||
|
||||
10
ast/asdl.py
10
ast/asdl.py
@@ -33,7 +33,7 @@ __all__ = [
|
||||
# See the EBNF at the top of the file to understand the logical connection
|
||||
# between the various node types.
|
||||
|
||||
builtin_types = {'identifier', 'string', 'int', 'constant', 'bool', 'conversion_flag'}
|
||||
builtin_types = {'identifier', 'string', 'int', 'constant'}
|
||||
|
||||
class AST:
|
||||
def __repr__(self):
|
||||
@@ -204,7 +204,7 @@ def check(mod):
|
||||
|
||||
def parse(filename):
|
||||
"""Parse ASDL from the given file and return a Module node describing it."""
|
||||
with open(filename) as f:
|
||||
with open(filename, encoding="utf-8") as f:
|
||||
parser = ASDLParser()
|
||||
return parser.parse(f.read())
|
||||
|
||||
@@ -340,12 +340,12 @@ class ASDLParser:
|
||||
|
||||
def _parse_optional_field_quantifier(self):
|
||||
is_seq, is_opt = False, False
|
||||
if self.cur_token.kind == TokenKind.Question:
|
||||
is_opt = True
|
||||
self._advance()
|
||||
if self.cur_token.kind == TokenKind.Asterisk:
|
||||
is_seq = True
|
||||
self._advance()
|
||||
elif self.cur_token.kind == TokenKind.Question:
|
||||
is_opt = True
|
||||
self._advance()
|
||||
return is_seq, is_opt
|
||||
|
||||
def _advance(self):
|
||||
|
||||
@@ -14,12 +14,10 @@ TABSIZE = 4
|
||||
AUTOGEN_MESSAGE = "// File automatically generated by {}.\n"
|
||||
|
||||
builtin_type_mapping = {
|
||||
'identifier': 'Ident',
|
||||
'string': 'String',
|
||||
'int': 'usize',
|
||||
'constant': 'Constant',
|
||||
'bool': 'bool',
|
||||
'conversion_flag': 'ConversionFlag',
|
||||
"identifier": "Ident",
|
||||
"string": "String",
|
||||
"int": "usize",
|
||||
"constant": "Constant",
|
||||
}
|
||||
assert builtin_type_mapping.keys() == asdl.builtin_types
|
||||
|
||||
@@ -31,8 +29,10 @@ def get_rust_type(name):
|
||||
"""
|
||||
if name in asdl.builtin_types:
|
||||
return builtin_type_mapping[name]
|
||||
else:
|
||||
elif name.islower():
|
||||
return "".join(part.capitalize() for part in name.split("_"))
|
||||
else:
|
||||
return name
|
||||
|
||||
|
||||
def is_simple(sum):
|
||||
@@ -252,13 +252,23 @@ class StructVisitor(TypeInfoEmitVisitor):
|
||||
if product.attributes:
|
||||
dataname = rustname + "Data"
|
||||
self.emit_attrs(depth)
|
||||
self.emit(f"pub struct {dataname}{generics} {{", depth)
|
||||
has_expr = any(f.type != "identifier" for f in product.fields)
|
||||
if has_expr:
|
||||
datadef = f"{dataname}{generics}"
|
||||
else:
|
||||
datadef = dataname
|
||||
self.emit(f"pub struct {datadef} {{", depth)
|
||||
for f in product.fields:
|
||||
self.visit(f, typeinfo, "pub ", depth + 1)
|
||||
self.emit("}", depth)
|
||||
if product.attributes:
|
||||
# attributes should just be location info
|
||||
self.emit(f"pub type {rustname}<U = ()> = Located<{dataname}{generics_applied}, U>;", depth);
|
||||
if not has_expr:
|
||||
generics_applied = ""
|
||||
self.emit(
|
||||
f"pub type {rustname}<U = ()> = Located<{dataname}{generics_applied}, U>;",
|
||||
depth,
|
||||
)
|
||||
self.emit("", depth)
|
||||
|
||||
|
||||
@@ -422,8 +432,11 @@ class ClassDefVisitor(EmitVisitor):
|
||||
self.gen_classdef(name, product.fields, product.attributes, depth)
|
||||
|
||||
def gen_classdef(self, name, fields, attrs, depth, base="AstNode"):
|
||||
structname = "Node" + name
|
||||
self.emit(f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = {json.dumps(base)})]', depth)
|
||||
structname = "Node" + get_rust_type(name)
|
||||
self.emit(
|
||||
f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = {json.dumps(base)})]',
|
||||
depth,
|
||||
)
|
||||
self.emit(f"struct {structname};", depth)
|
||||
self.emit("#[pyclass(flags(HAS_DICT, BASETYPE))]", depth)
|
||||
self.emit(f"impl {structname} {{", depth)
|
||||
@@ -467,7 +480,10 @@ class ExtendModuleVisitor(EmitVisitor):
|
||||
self.visit(type.value, type.name, depth)
|
||||
|
||||
def visitSum(self, sum, name, depth):
|
||||
self.emit(f"{json.dumps(name)} => NodeKind{get_rust_type(name)}::make_class(&vm.ctx),", depth)
|
||||
rust_name = get_rust_type(name)
|
||||
self.emit(
|
||||
f"{json.dumps(name)} => NodeKind{rust_name}::make_class(&vm.ctx),", depth
|
||||
)
|
||||
for cons in sum.types:
|
||||
self.visit(cons, depth)
|
||||
|
||||
@@ -478,7 +494,8 @@ class ExtendModuleVisitor(EmitVisitor):
|
||||
self.gen_extension(name, depth)
|
||||
|
||||
def gen_extension(self, name, depth):
|
||||
self.emit(f"{json.dumps(name)} => Node{name}::make_class(&vm.ctx),", depth)
|
||||
rust_name = get_rust_type(name)
|
||||
self.emit(f"{json.dumps(name)} => Node{rust_name}::make_class(&vm.ctx),", depth)
|
||||
|
||||
|
||||
class TraitImplVisitor(EmitVisitor):
|
||||
@@ -494,7 +511,6 @@ class TraitImplVisitor(EmitVisitor):
|
||||
if sum.attributes:
|
||||
enumname += "Kind"
|
||||
|
||||
|
||||
self.emit(f"impl NamedNode for ast::{enumname} {{", depth)
|
||||
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
|
||||
self.emit("}", depth)
|
||||
@@ -546,8 +562,11 @@ class TraitImplVisitor(EmitVisitor):
|
||||
self.emit("}", depth)
|
||||
|
||||
def make_node(self, variant, fields, depth):
|
||||
lines = []
|
||||
self.emit(f"let _node = AstNode.into_ref_with_type(_vm, Node{variant}::static_type().to_owned()).unwrap();", depth)
|
||||
rust_variant = get_rust_type(variant)
|
||||
self.emit(
|
||||
f"let _node = AstNode.into_ref_with_type(_vm, Node{rust_variant}::static_type().to_owned()).unwrap();",
|
||||
depth,
|
||||
)
|
||||
if fields:
|
||||
self.emit("let _dict = _node.as_object().dict().unwrap();", depth)
|
||||
for f in fields:
|
||||
|
||||
180
ast/src/ast_gen.rs
generated
180
ast/src/ast_gen.rs
generated
@@ -87,7 +87,7 @@ pub enum StmtKind<U = ()> {
|
||||
target: Box<Expr<U>>,
|
||||
annotation: Box<Expr<U>>,
|
||||
value: Option<Box<Expr<U>>>,
|
||||
simple: bool,
|
||||
simple: usize,
|
||||
},
|
||||
For {
|
||||
target: Box<Expr<U>>,
|
||||
@@ -123,6 +123,10 @@ pub enum StmtKind<U = ()> {
|
||||
body: Vec<Stmt<U>>,
|
||||
type_comment: Option<String>,
|
||||
},
|
||||
Match {
|
||||
subject: Box<Expr<U>>,
|
||||
cases: Vec<MatchCase<U>>,
|
||||
},
|
||||
Raise {
|
||||
exc: Option<Box<Expr<U>>>,
|
||||
cause: Option<Box<Expr<U>>>,
|
||||
@@ -138,12 +142,12 @@ pub enum StmtKind<U = ()> {
|
||||
msg: Option<Box<Expr<U>>>,
|
||||
},
|
||||
Import {
|
||||
names: Vec<Alias>,
|
||||
names: Vec<Alias<U>>,
|
||||
},
|
||||
ImportFrom {
|
||||
module: Option<Ident>,
|
||||
names: Vec<Alias>,
|
||||
level: usize,
|
||||
names: Vec<Alias<U>>,
|
||||
level: Option<usize>,
|
||||
},
|
||||
Global {
|
||||
names: Vec<Ident>,
|
||||
@@ -189,7 +193,7 @@ pub enum ExprKind<U = ()> {
|
||||
orelse: Box<Expr<U>>,
|
||||
},
|
||||
Dict {
|
||||
keys: Vec<Option<Box<Expr<U>>>>,
|
||||
keys: Vec<Expr<U>>,
|
||||
values: Vec<Expr<U>>,
|
||||
},
|
||||
Set {
|
||||
@@ -233,7 +237,7 @@ pub enum ExprKind<U = ()> {
|
||||
},
|
||||
FormattedValue {
|
||||
value: Box<Expr<U>>,
|
||||
conversion: Option<ConversionFlag>,
|
||||
conversion: usize,
|
||||
format_spec: Option<Box<Expr<U>>>,
|
||||
},
|
||||
JoinedStr {
|
||||
@@ -334,7 +338,7 @@ pub struct Comprehension<U = ()> {
|
||||
pub target: Box<Expr<U>>,
|
||||
pub iter: Box<Expr<U>>,
|
||||
pub ifs: Vec<Expr<U>>,
|
||||
pub is_async: bool,
|
||||
pub is_async: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -353,7 +357,7 @@ pub struct Arguments<U = ()> {
|
||||
pub args: Vec<Arg<U>>,
|
||||
pub vararg: Option<Box<Arg<U>>>,
|
||||
pub kwonlyargs: Vec<Arg<U>>,
|
||||
pub kw_defaults: Vec<Option<Box<Expr<U>>>>,
|
||||
pub kw_defaults: Vec<Expr<U>>,
|
||||
pub kwarg: Option<Box<Arg<U>>>,
|
||||
pub defaults: Vec<Expr<U>>,
|
||||
}
|
||||
@@ -374,10 +378,11 @@ pub struct KeywordData<U = ()> {
|
||||
pub type Keyword<U = ()> = Located<KeywordData<U>, U>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Alias {
|
||||
pub struct AliasData {
|
||||
pub name: Ident,
|
||||
pub asname: Option<Ident>,
|
||||
}
|
||||
pub type Alias<U = ()> = Located<AliasData, U>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Withitem<U = ()> {
|
||||
@@ -385,6 +390,48 @@ pub struct Withitem<U = ()> {
|
||||
pub optional_vars: Option<Box<Expr<U>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct MatchCase<U = ()> {
|
||||
pub pattern: Box<Pattern<U>>,
|
||||
pub guard: Option<Box<Expr<U>>>,
|
||||
pub body: Vec<Stmt<U>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum PatternKind<U = ()> {
|
||||
MatchValue {
|
||||
value: Box<Expr<U>>,
|
||||
},
|
||||
MatchSingleton {
|
||||
value: Constant,
|
||||
},
|
||||
MatchSequence {
|
||||
patterns: Vec<Pattern<U>>,
|
||||
},
|
||||
MatchMapping {
|
||||
keys: Vec<Expr<U>>,
|
||||
patterns: Vec<Pattern<U>>,
|
||||
rest: Option<Ident>,
|
||||
},
|
||||
MatchClass {
|
||||
cls: Box<Expr<U>>,
|
||||
patterns: Vec<Pattern<U>>,
|
||||
kwd_attrs: Vec<Ident>,
|
||||
kwd_patterns: Vec<Pattern<U>>,
|
||||
},
|
||||
MatchStar {
|
||||
name: Option<Ident>,
|
||||
},
|
||||
MatchAs {
|
||||
pattern: Option<Box<Pattern<U>>>,
|
||||
name: Option<Ident>,
|
||||
},
|
||||
MatchOr {
|
||||
patterns: Vec<Pattern<U>>,
|
||||
},
|
||||
}
|
||||
pub type Pattern<U = ()> = Located<PatternKind<U>, U>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TypeIgnore {
|
||||
TypeIgnore { lineno: usize, tag: String },
|
||||
@@ -449,7 +496,7 @@ pub mod fold {
|
||||
) -> Result<Keyword<Self::TargetU>, Self::Error> {
|
||||
fold_keyword(self, node)
|
||||
}
|
||||
fn fold_alias(&mut self, node: Alias) -> Result<Alias, Self::Error> {
|
||||
fn fold_alias(&mut self, node: Alias<U>) -> Result<Alias<Self::TargetU>, Self::Error> {
|
||||
fold_alias(self, node)
|
||||
}
|
||||
fn fold_withitem(
|
||||
@@ -458,6 +505,18 @@ pub mod fold {
|
||||
) -> Result<Withitem<Self::TargetU>, Self::Error> {
|
||||
fold_withitem(self, node)
|
||||
}
|
||||
fn fold_match_case(
|
||||
&mut self,
|
||||
node: MatchCase<U>,
|
||||
) -> Result<MatchCase<Self::TargetU>, Self::Error> {
|
||||
fold_match_case(self, node)
|
||||
}
|
||||
fn fold_pattern(
|
||||
&mut self,
|
||||
node: Pattern<U>,
|
||||
) -> Result<Pattern<Self::TargetU>, Self::Error> {
|
||||
fold_pattern(self, node)
|
||||
}
|
||||
fn fold_type_ignore(&mut self, node: TypeIgnore) -> Result<TypeIgnore, Self::Error> {
|
||||
fold_type_ignore(self, node)
|
||||
}
|
||||
@@ -645,6 +704,10 @@ pub mod fold {
|
||||
body: Foldable::fold(body, folder)?,
|
||||
type_comment: Foldable::fold(type_comment, folder)?,
|
||||
}),
|
||||
StmtKind::Match { subject, cases } => Ok(StmtKind::Match {
|
||||
subject: Foldable::fold(subject, folder)?,
|
||||
cases: Foldable::fold(cases, folder)?,
|
||||
}),
|
||||
StmtKind::Raise { exc, cause } => Ok(StmtKind::Raise {
|
||||
exc: Foldable::fold(exc, folder)?,
|
||||
cause: Foldable::fold(cause, folder)?,
|
||||
@@ -1074,8 +1137,8 @@ pub mod fold {
|
||||
})
|
||||
})
|
||||
}
|
||||
impl<T, U> Foldable<T, U> for Alias {
|
||||
type Mapped = Alias;
|
||||
impl<T, U> Foldable<T, U> for Alias<T> {
|
||||
type Mapped = Alias<U>;
|
||||
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
||||
self,
|
||||
folder: &mut F,
|
||||
@@ -1085,12 +1148,14 @@ pub mod fold {
|
||||
}
|
||||
pub fn fold_alias<U, F: Fold<U> + ?Sized>(
|
||||
#[allow(unused)] folder: &mut F,
|
||||
node: Alias,
|
||||
) -> Result<Alias, F::Error> {
|
||||
let Alias { name, asname } = node;
|
||||
Ok(Alias {
|
||||
name: Foldable::fold(name, folder)?,
|
||||
asname: Foldable::fold(asname, folder)?,
|
||||
node: Alias<U>,
|
||||
) -> Result<Alias<F::TargetU>, F::Error> {
|
||||
fold_located(folder, node, |folder, node| {
|
||||
let AliasData { name, asname } = node;
|
||||
Ok(AliasData {
|
||||
name: Foldable::fold(name, folder)?,
|
||||
asname: Foldable::fold(asname, folder)?,
|
||||
})
|
||||
})
|
||||
}
|
||||
impl<T, U> Foldable<T, U> for Withitem<T> {
|
||||
@@ -1115,6 +1180,85 @@ pub mod fold {
|
||||
optional_vars: Foldable::fold(optional_vars, folder)?,
|
||||
})
|
||||
}
|
||||
impl<T, U> Foldable<T, U> for MatchCase<T> {
|
||||
type Mapped = MatchCase<U>;
|
||||
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
||||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self::Mapped, F::Error> {
|
||||
folder.fold_match_case(self)
|
||||
}
|
||||
}
|
||||
pub fn fold_match_case<U, F: Fold<U> + ?Sized>(
|
||||
#[allow(unused)] folder: &mut F,
|
||||
node: MatchCase<U>,
|
||||
) -> Result<MatchCase<F::TargetU>, F::Error> {
|
||||
let MatchCase {
|
||||
pattern,
|
||||
guard,
|
||||
body,
|
||||
} = node;
|
||||
Ok(MatchCase {
|
||||
pattern: Foldable::fold(pattern, folder)?,
|
||||
guard: Foldable::fold(guard, folder)?,
|
||||
body: Foldable::fold(body, folder)?,
|
||||
})
|
||||
}
|
||||
impl<T, U> Foldable<T, U> for Pattern<T> {
|
||||
type Mapped = Pattern<U>;
|
||||
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
||||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self::Mapped, F::Error> {
|
||||
folder.fold_pattern(self)
|
||||
}
|
||||
}
|
||||
pub fn fold_pattern<U, F: Fold<U> + ?Sized>(
|
||||
#[allow(unused)] folder: &mut F,
|
||||
node: Pattern<U>,
|
||||
) -> Result<Pattern<F::TargetU>, F::Error> {
|
||||
fold_located(folder, node, |folder, node| match node {
|
||||
PatternKind::MatchValue { value } => Ok(PatternKind::MatchValue {
|
||||
value: Foldable::fold(value, folder)?,
|
||||
}),
|
||||
PatternKind::MatchSingleton { value } => Ok(PatternKind::MatchSingleton {
|
||||
value: Foldable::fold(value, folder)?,
|
||||
}),
|
||||
PatternKind::MatchSequence { patterns } => Ok(PatternKind::MatchSequence {
|
||||
patterns: Foldable::fold(patterns, folder)?,
|
||||
}),
|
||||
PatternKind::MatchMapping {
|
||||
keys,
|
||||
patterns,
|
||||
rest,
|
||||
} => Ok(PatternKind::MatchMapping {
|
||||
keys: Foldable::fold(keys, folder)?,
|
||||
patterns: Foldable::fold(patterns, folder)?,
|
||||
rest: Foldable::fold(rest, folder)?,
|
||||
}),
|
||||
PatternKind::MatchClass {
|
||||
cls,
|
||||
patterns,
|
||||
kwd_attrs,
|
||||
kwd_patterns,
|
||||
} => Ok(PatternKind::MatchClass {
|
||||
cls: Foldable::fold(cls, folder)?,
|
||||
patterns: Foldable::fold(patterns, folder)?,
|
||||
kwd_attrs: Foldable::fold(kwd_attrs, folder)?,
|
||||
kwd_patterns: Foldable::fold(kwd_patterns, folder)?,
|
||||
}),
|
||||
PatternKind::MatchStar { name } => Ok(PatternKind::MatchStar {
|
||||
name: Foldable::fold(name, folder)?,
|
||||
}),
|
||||
PatternKind::MatchAs { pattern, name } => Ok(PatternKind::MatchAs {
|
||||
pattern: Foldable::fold(pattern, folder)?,
|
||||
name: Foldable::fold(name, folder)?,
|
||||
}),
|
||||
PatternKind::MatchOr { patterns } => Ok(PatternKind::MatchOr {
|
||||
patterns: Foldable::fold(patterns, folder)?,
|
||||
}),
|
||||
})
|
||||
}
|
||||
impl<T, U> Foldable<T, U> for TypeIgnore {
|
||||
type Mapped = TypeIgnore;
|
||||
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use num_bigint::BigInt;
|
||||
pub use rustpython_bytecode::ConversionFlag;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Constant {
|
||||
@@ -70,29 +71,6 @@ impl std::fmt::Display for Constant {
|
||||
}
|
||||
}
|
||||
|
||||
/// Transforms a value prior to formatting it.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum ConversionFlag {
|
||||
/// Converts by calling `str(<value>)`.
|
||||
Str = b's',
|
||||
/// Converts by calling `ascii(<value>)`.
|
||||
Ascii = b'a',
|
||||
/// Converts by calling `repr(<value>)`.
|
||||
Repr = b'r',
|
||||
}
|
||||
|
||||
impl ConversionFlag {
|
||||
pub fn try_from_byte(b: u8) -> Option<Self> {
|
||||
match b {
|
||||
b's' => Some(Self::Str),
|
||||
b'a' => Some(Self::Ascii),
|
||||
b'r' => Some(Self::Repr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "constant-optimization")]
|
||||
#[non_exhaustive]
|
||||
#[derive(Default)]
|
||||
|
||||
@@ -63,10 +63,4 @@ macro_rules! simple_fold {
|
||||
};
|
||||
}
|
||||
|
||||
simple_fold!(
|
||||
usize,
|
||||
String,
|
||||
bool,
|
||||
constant::Constant,
|
||||
constant::ConversionFlag
|
||||
);
|
||||
simple_fold!(usize, String, bool, constant::Constant);
|
||||
|
||||
@@ -149,13 +149,14 @@ impl<'a> Unparser<'a> {
|
||||
ExprKind::Dict { keys, values } => {
|
||||
self.p("{")?;
|
||||
let mut first = true;
|
||||
for (k, v) in keys.iter().zip(values) {
|
||||
let (packed, unpacked) = values.split_at(keys.len());
|
||||
for (k, v) in keys.iter().zip(packed) {
|
||||
self.p_delim(&mut first, ", ")?;
|
||||
if let Some(k) = k {
|
||||
write!(self, "{}: {}", **k, *v)?;
|
||||
} else {
|
||||
write!(self, "**{}", *v)?;
|
||||
}
|
||||
write!(self, "{}: {}", *k, *v)?;
|
||||
}
|
||||
for d in unpacked {
|
||||
self.p_delim(&mut first, ", ")?;
|
||||
write!(self, "**{}", *d)?;
|
||||
}
|
||||
self.p("}")?;
|
||||
}
|
||||
@@ -397,7 +398,7 @@ impl<'a> Unparser<'a> {
|
||||
self.unparse_arg(kwarg)?;
|
||||
if let Some(default) = i
|
||||
.checked_sub(defaults_start)
|
||||
.and_then(|i| args.kw_defaults[i].as_deref())
|
||||
.and_then(|i| args.kw_defaults.get(i))
|
||||
{
|
||||
write!(self, "={}", default)?;
|
||||
}
|
||||
@@ -419,7 +420,7 @@ impl<'a> Unparser<'a> {
|
||||
|
||||
fn unparse_comp<U>(&mut self, generators: &[Comprehension<U>]) -> fmt::Result {
|
||||
for comp in generators {
|
||||
self.p(if comp.is_async {
|
||||
self.p(if comp.is_async > 0 {
|
||||
" async for "
|
||||
} else {
|
||||
" for "
|
||||
@@ -445,7 +446,7 @@ impl<'a> Unparser<'a> {
|
||||
fn unparse_formatted<U>(
|
||||
&mut self,
|
||||
val: &Expr<U>,
|
||||
conversion: Option<ConversionFlag>,
|
||||
conversion: usize,
|
||||
spec: Option<&Expr<U>>,
|
||||
) -> fmt::Result {
|
||||
let buffered = to_string_fmt(|f| Unparser::new(f).unparse_expr(val, precedence::TEST + 1));
|
||||
@@ -459,13 +460,11 @@ impl<'a> Unparser<'a> {
|
||||
self.p(&buffered)?;
|
||||
drop(buffered);
|
||||
|
||||
if let Some(conv) = conversion {
|
||||
let flag = match conv {
|
||||
ConversionFlag::Str => "!s",
|
||||
ConversionFlag::Ascii => "!a",
|
||||
ConversionFlag::Repr => "!r",
|
||||
};
|
||||
self.p(flag)?;
|
||||
if conversion != ConversionFlag::None as usize {
|
||||
self.p("!")?;
|
||||
let buf = &[conversion as u8];
|
||||
let c = std::str::from_utf8(buf).unwrap();
|
||||
self.p(c)?;
|
||||
}
|
||||
|
||||
if let Some(spec) = spec {
|
||||
|
||||
@@ -159,15 +159,30 @@ impl fmt::Display for Label {
|
||||
|
||||
/// Transforms a value prior to formatting it.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum ConversionFlag {
|
||||
/// No conversion
|
||||
None,
|
||||
None = 0,
|
||||
/// Converts by calling `str(<value>)`.
|
||||
Str,
|
||||
Str = b's',
|
||||
/// Converts by calling `ascii(<value>)`.
|
||||
Ascii,
|
||||
Ascii = b'a',
|
||||
/// Converts by calling `repr(<value>)`.
|
||||
Repr,
|
||||
Repr = b'r',
|
||||
}
|
||||
|
||||
impl TryFrom<usize> for ConversionFlag {
|
||||
type Error = usize;
|
||||
fn try_from(b: usize) -> Result<Self, Self::Error> {
|
||||
let b = b.try_into().map_err(|_| b)?;
|
||||
match b {
|
||||
0 => Ok(Self::None),
|
||||
b's' => Ok(Self::Str),
|
||||
b'a' => Ok(Self::Ascii),
|
||||
b'r' => Ok(Self::Repr),
|
||||
b => Err(b as usize),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The kind of Raise that occurred.
|
||||
@@ -357,6 +372,7 @@ pub enum Instruction {
|
||||
for_call: bool,
|
||||
size: u32,
|
||||
},
|
||||
DictUpdate,
|
||||
BuildSlice {
|
||||
/// whether build a slice with a third step argument
|
||||
step: bool,
|
||||
@@ -1040,6 +1056,7 @@ impl Instruction {
|
||||
let nargs = if *unpack { *size } else { *size * 2 };
|
||||
-(nargs as i32) + 1
|
||||
}
|
||||
DictUpdate => -1,
|
||||
BuildSlice { step } => -2 - (*step as i32) + 1,
|
||||
ListAppend { .. } | SetAdd { .. } => -1,
|
||||
MapAdd { .. } => -2,
|
||||
@@ -1202,6 +1219,7 @@ impl Instruction {
|
||||
unpack,
|
||||
for_call,
|
||||
} => w!(BuildMap, size, unpack, for_call),
|
||||
DictUpdate => w!(DictUpdate),
|
||||
BuildSlice { step } => w!(BuildSlice, step),
|
||||
ListAppend { i } => w!(ListAppend, i),
|
||||
SetAdd { i } => w!(SetAdd, i),
|
||||
|
||||
@@ -552,6 +552,7 @@ impl Compiler {
|
||||
Import { names } => {
|
||||
// import a, b, c as d
|
||||
for name in names {
|
||||
let name = &name.node;
|
||||
self.emit_constant(ConstantData::Integer {
|
||||
value: num_traits::Zero::zero(),
|
||||
});
|
||||
@@ -574,7 +575,7 @@ impl Compiler {
|
||||
module,
|
||||
names,
|
||||
} => {
|
||||
let import_star = names.iter().any(|n| n.name == "*");
|
||||
let import_star = names.iter().any(|n| n.node.name == "*");
|
||||
|
||||
let from_list = if import_star {
|
||||
if self.ctx.in_func() {
|
||||
@@ -588,7 +589,7 @@ impl Compiler {
|
||||
names
|
||||
.iter()
|
||||
.map(|n| ConstantData::Str {
|
||||
value: n.name.to_owned(),
|
||||
value: n.node.name.to_owned(),
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
@@ -597,7 +598,7 @@ impl Compiler {
|
||||
|
||||
// from .... import (*fromlist)
|
||||
self.emit_constant(ConstantData::Integer {
|
||||
value: (*level).into(),
|
||||
value: (*level).unwrap_or(0).into(),
|
||||
});
|
||||
self.emit_constant(ConstantData::Tuple {
|
||||
elements: from_list,
|
||||
@@ -615,6 +616,7 @@ impl Compiler {
|
||||
// from mod import a, b as c
|
||||
|
||||
for name in names {
|
||||
let name = &name.node;
|
||||
let idx = self.name(&name.name);
|
||||
// import symbol from module:
|
||||
self.emit(Instruction::ImportFrom { idx });
|
||||
@@ -678,6 +680,7 @@ impl Compiler {
|
||||
orelse,
|
||||
..
|
||||
} => self.compile_for(target, iter, body, orelse, true)?,
|
||||
Match { subject, cases } => self.compile_match(subject, cases)?,
|
||||
Raise { exc, cause } => {
|
||||
let kind = match exc {
|
||||
Some(value) => {
|
||||
@@ -879,19 +882,19 @@ impl Compiler {
|
||||
});
|
||||
}
|
||||
|
||||
let mut num_kw_only_defaults = 0;
|
||||
for (kw, default) in args.kwonlyargs.iter().zip(&args.kw_defaults) {
|
||||
if let Some(default) = default {
|
||||
if !args.kw_defaults.is_empty() {
|
||||
let required_kw_count = args.kwonlyargs.len().saturating_sub(args.kw_defaults.len());
|
||||
for (kw, default) in args.kwonlyargs[required_kw_count..]
|
||||
.iter()
|
||||
.zip(&args.kw_defaults)
|
||||
{
|
||||
self.emit_constant(ConstantData::Str {
|
||||
value: kw.node.arg.clone(),
|
||||
});
|
||||
self.compile_expression(default)?;
|
||||
num_kw_only_defaults += 1;
|
||||
}
|
||||
}
|
||||
if num_kw_only_defaults > 0 {
|
||||
self.emit(Instruction::BuildMap {
|
||||
size: num_kw_only_defaults,
|
||||
size: args.kw_defaults.len() as u32,
|
||||
unpack: false,
|
||||
for_call: false,
|
||||
});
|
||||
@@ -901,7 +904,7 @@ impl Compiler {
|
||||
if have_defaults {
|
||||
funcflags |= bytecode::MakeFunctionFlags::DEFAULTS;
|
||||
}
|
||||
if num_kw_only_defaults > 0 {
|
||||
if !args.kw_defaults.is_empty() {
|
||||
funcflags |= bytecode::MakeFunctionFlags::KW_ONLY_DEFAULTS;
|
||||
}
|
||||
|
||||
@@ -1519,6 +1522,16 @@ impl Compiler {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_match(
|
||||
&mut self,
|
||||
subject: &ast::Expr,
|
||||
cases: &[ast::MatchCase],
|
||||
) -> CompileResult<()> {
|
||||
eprintln!("match subject: {subject:?}");
|
||||
eprintln!("match cases: {cases:?}");
|
||||
Err(self.error(CompileErrorType::NotImplementedYet))
|
||||
}
|
||||
|
||||
fn compile_chained_comparison(
|
||||
&mut self,
|
||||
left: &ast::Expr,
|
||||
@@ -1928,51 +1941,26 @@ impl Compiler {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_dict(
|
||||
&mut self,
|
||||
keys: &[Option<Box<ast::Expr>>],
|
||||
values: &[ast::Expr],
|
||||
) -> CompileResult<()> {
|
||||
fn compile_dict(&mut self, keys: &[ast::Expr], values: &[ast::Expr]) -> CompileResult<()> {
|
||||
let mut size = 0;
|
||||
let mut has_unpacking = false;
|
||||
for (is_unpacking, subpairs) in &keys.iter().zip(values).group_by(|e| e.0.is_none()) {
|
||||
if is_unpacking {
|
||||
for (_, value) in subpairs {
|
||||
self.compile_expression(value)?;
|
||||
size += 1;
|
||||
}
|
||||
has_unpacking = true;
|
||||
} else {
|
||||
let mut subsize = 0;
|
||||
for (key, value) in subpairs {
|
||||
if let Some(key) = key {
|
||||
self.compile_expression(key)?;
|
||||
self.compile_expression(value)?;
|
||||
subsize += 1;
|
||||
}
|
||||
}
|
||||
self.emit(Instruction::BuildMap {
|
||||
size: subsize,
|
||||
unpack: false,
|
||||
for_call: false,
|
||||
});
|
||||
size += 1;
|
||||
}
|
||||
|
||||
let (packed_values, unpacked_values) = values.split_at(keys.len());
|
||||
for (key, value) in keys.iter().zip(packed_values) {
|
||||
self.compile_expression(key)?;
|
||||
self.compile_expression(value)?;
|
||||
size += 1;
|
||||
}
|
||||
if size == 0 {
|
||||
self.emit(Instruction::BuildMap {
|
||||
size,
|
||||
unpack: false,
|
||||
for_call: false,
|
||||
});
|
||||
}
|
||||
if size > 1 || has_unpacking {
|
||||
self.emit(Instruction::BuildMap {
|
||||
size,
|
||||
unpack: true,
|
||||
for_call: false,
|
||||
});
|
||||
self.emit(Instruction::BuildMap {
|
||||
size,
|
||||
unpack: false,
|
||||
for_call: false,
|
||||
});
|
||||
|
||||
for value in unpacked_values {
|
||||
self.compile_expression(value)?;
|
||||
self.emit(Instruction::DictUpdate);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2120,7 +2108,7 @@ impl Compiler {
|
||||
};
|
||||
self.compile_expression(value)?;
|
||||
self.emit(Instruction::FormatValue {
|
||||
conversion: compile_conversion_flag(*conversion),
|
||||
conversion: (*conversion).try_into().expect("invalid conversion flag"),
|
||||
});
|
||||
}
|
||||
Name { id, .. } => self.load_name(id)?,
|
||||
@@ -2475,7 +2463,7 @@ impl Compiler {
|
||||
|
||||
let mut loop_labels = vec![];
|
||||
for generator in generators {
|
||||
if generator.is_async {
|
||||
if generator.is_async > 0 {
|
||||
unimplemented!("async for comprehensions");
|
||||
}
|
||||
|
||||
@@ -2564,7 +2552,7 @@ impl Compiler {
|
||||
return Err(self.error(CompileErrorType::InvalidFuturePlacement));
|
||||
}
|
||||
for feature in features {
|
||||
match &*feature.name {
|
||||
match &*feature.node.name {
|
||||
// Python 3 features; we've already implemented them by default
|
||||
"nested_scopes" | "generators" | "division" | "absolute_import"
|
||||
| "with_statement" | "print_function" | "unicode_literals" => {}
|
||||
@@ -2688,17 +2676,6 @@ fn compile_location(location: &ast::Location) -> bytecode::Location {
|
||||
bytecode::Location::new(location.row(), location.column())
|
||||
}
|
||||
|
||||
fn compile_conversion_flag(
|
||||
conversion_flag: Option<ast::ConversionFlag>,
|
||||
) -> bytecode::ConversionFlag {
|
||||
match conversion_flag {
|
||||
None => bytecode::ConversionFlag::None,
|
||||
Some(ast::ConversionFlag::Ascii) => bytecode::ConversionFlag::Ascii,
|
||||
Some(ast::ConversionFlag::Repr) => bytecode::ConversionFlag::Repr,
|
||||
Some(ast::ConversionFlag::Str) => bytecode::ConversionFlag::Str,
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_constant(value: &ast::Constant) -> ConstantData {
|
||||
match value {
|
||||
ast::Constant::None => ConstantData::None,
|
||||
|
||||
@@ -37,6 +37,7 @@ pub enum CompileErrorType {
|
||||
TooManyStarUnpack,
|
||||
EmptyWithItems,
|
||||
EmptyWithBody,
|
||||
NotImplementedYet, // RustPython marker for unimplemented features
|
||||
}
|
||||
|
||||
impl fmt::Display for CompileErrorType {
|
||||
@@ -78,6 +79,9 @@ impl fmt::Display for CompileErrorType {
|
||||
CompileErrorType::EmptyWithBody => {
|
||||
write!(f, "empty body on With")
|
||||
}
|
||||
CompileErrorType::NotImplementedYet => {
|
||||
write!(f, "RustPython does not implement this feature yet")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,7 +639,7 @@ impl SymbolTableBuilder {
|
||||
if let ImportFrom { module, names, .. } = &statement.node {
|
||||
if module.as_deref() == Some("__future__") {
|
||||
for feature in names {
|
||||
if feature.name == "annotations" {
|
||||
if feature.node.name == "annotations" {
|
||||
self.future_annotations = true;
|
||||
}
|
||||
}
|
||||
@@ -739,13 +739,13 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
Import { names } | ImportFrom { names, .. } => {
|
||||
for name in names {
|
||||
if let Some(alias) = &name.asname {
|
||||
if let Some(alias) = &name.node.asname {
|
||||
// `import mymodule as myalias`
|
||||
self.register_name(alias, SymbolUsage::Imported, location)?;
|
||||
} else {
|
||||
// `import module`
|
||||
self.register_name(
|
||||
name.name.split('.').next().unwrap(),
|
||||
name.node.name.split('.').next().unwrap(),
|
||||
SymbolUsage::Imported,
|
||||
location,
|
||||
)?;
|
||||
@@ -782,7 +782,7 @@ impl SymbolTableBuilder {
|
||||
} => {
|
||||
// https://github.com/python/cpython/blob/main/Python/symtable.c#L1233
|
||||
match &target.node {
|
||||
ast::ExprKind::Name { id, .. } if *simple => {
|
||||
ast::ExprKind::Name { id, .. } if *simple > 0 => {
|
||||
self.register_name(id, SymbolUsage::AnnotationAssigned, location)?;
|
||||
}
|
||||
_ => {
|
||||
@@ -823,6 +823,15 @@ impl SymbolTableBuilder {
|
||||
self.scan_statements(orelse)?;
|
||||
self.scan_statements(finalbody)?;
|
||||
}
|
||||
Match {
|
||||
subject: _,
|
||||
cases: _,
|
||||
} => {
|
||||
return Err(SymbolTableError {
|
||||
error: "match expression is not implemented yet".to_owned(),
|
||||
location: Location::default(),
|
||||
});
|
||||
}
|
||||
Raise { exc, cause } => {
|
||||
if let Some(expression) = exc {
|
||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||
@@ -875,12 +884,13 @@ impl SymbolTableBuilder {
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
}
|
||||
Dict { keys, values } => {
|
||||
for (key, value) in keys.iter().zip(values) {
|
||||
if let Some(key) = key {
|
||||
self.scan_expression(key, context)?;
|
||||
} else {
|
||||
// dict unpacking marker
|
||||
}
|
||||
let (packed, unpacked) = values.split_at(keys.len());
|
||||
for (key, value) in keys.iter().zip(packed) {
|
||||
self.scan_expression(key, context)?;
|
||||
self.scan_expression(value, context)?;
|
||||
}
|
||||
for value in unpacked {
|
||||
// dict unpacking marker
|
||||
self.scan_expression(value, context)?;
|
||||
}
|
||||
}
|
||||
@@ -1094,7 +1104,7 @@ impl SymbolTableBuilder {
|
||||
) -> SymbolTableResult {
|
||||
// Evaluate eventual default parameters:
|
||||
self.scan_expressions(&args.defaults, ExpressionContext::Load)?;
|
||||
for expression in args.kw_defaults.iter().flatten() {
|
||||
for expression in args.kw_defaults.iter() {
|
||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ y = {'b': 2, 'c': 2, 'd': 2}
|
||||
z = {'c': 3, 'd': 3, 'e': 3}
|
||||
|
||||
w = {1: 1, **x, 2: 2, **y, 3: 3, **z, 4: 4}
|
||||
assert w == {1: 1, 'a': 1, 'b': 2, 'c': 3, 2: 2, 'd': 3, 3: 3, 'e': 3, 4: 4}
|
||||
assert w == {1: 1, 'a': 1, 'b': 2, 'c': 3, 2: 2, 'd': 3, 3: 3, 'e': 3, 4: 4} # not in cpython test suite
|
||||
|
||||
assert str({True: True, 1.0: 1.0}) == str({True: 1.0})
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ ExpressionStatement: ast::Stmt = {
|
||||
target: Box::new(target),
|
||||
annotation: Box::new(annotation),
|
||||
value: rhs.map(Box::new),
|
||||
simple,
|
||||
simple: if simple { 1 } else { 0 },
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -253,12 +253,12 @@ ImportStatement: ast::Stmt = {
|
||||
},
|
||||
};
|
||||
|
||||
ImportFromLocation: (usize, Option<String>) = {
|
||||
ImportFromLocation: (Option<usize>, Option<String>) = {
|
||||
<dots: ImportDots*> <name:DottedName> => {
|
||||
(dots.iter().sum(), Some(name))
|
||||
(Some(dots.iter().sum()), Some(name))
|
||||
},
|
||||
<dots: ImportDots+> => {
|
||||
(dots.iter().sum(), None)
|
||||
(Some(dots.iter().sum()), None)
|
||||
},
|
||||
};
|
||||
|
||||
@@ -268,19 +268,19 @@ ImportDots: usize = {
|
||||
};
|
||||
|
||||
ImportAsNames: Vec<ast::Alias> = {
|
||||
<i:OneOrMore<ImportAsAlias<Identifier>>> => i,
|
||||
"(" <i:OneOrMore<ImportAsAlias<Identifier>>> ","? ")" => i,
|
||||
"*" => {
|
||||
<location:@L> <i:OneOrMore<ImportAsAlias<Identifier>>> => i,
|
||||
<location:@L> "(" <i:OneOrMore<ImportAsAlias<Identifier>>> ","? ")" => i,
|
||||
<location:@L> "*" => {
|
||||
// Star import all
|
||||
vec![ast::Alias { name: "*".to_string(), asname: None }]
|
||||
vec![ast::Alias::new(location, ast::AliasData { name: "*".to_string(), asname: None })]
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
#[inline]
|
||||
ImportAsAlias<I>: ast::Alias = {
|
||||
<name:I> <a: ("as" Identifier)?> => ast::Alias { name, asname: a.map(|a| a.1) },
|
||||
};
|
||||
<location:@L> <name:I> <a: ("as" Identifier)?> => ast::Alias::new(location, ast::AliasData { name, asname: a.map(|a| a.1) }),
|
||||
}
|
||||
|
||||
// A name like abc or abc.def.ghi
|
||||
DottedName: String = {
|
||||
@@ -590,20 +590,26 @@ TypedParameter: ast::Arg = {
|
||||
// Use inline here to make sure the "," is not creating an ambiguity.
|
||||
// TODO: figure out another grammar that makes this inline no longer required.
|
||||
#[inline]
|
||||
ParameterListStarArgs<ArgType>: (Option<Box<ast::Arg>>, Vec<ast::Arg>, Vec<Option<Box<ast::Expr>>>, Option<Box<ast::Arg>>) = {
|
||||
ParameterListStarArgs<ArgType>: (Option<Box<ast::Arg>>, Vec<ast::Arg>, Vec<ast::Expr>, Option<Box<ast::Arg>>) = {
|
||||
"*" <va:ArgType?> <kw:("," ParameterDef<ArgType>)*> <kwarg:("," KwargParameter<ArgType>)?> => {
|
||||
// Extract keyword arguments:
|
||||
let mut kwonlyargs = vec![];
|
||||
let mut kw_defaults = vec![];
|
||||
let mut kwonlyargs = Vec::new();
|
||||
let mut kw_defaults = Vec::new();
|
||||
let mut kwargs = Vec::new();
|
||||
for (name, value) in kw.into_iter().map(|x| x.1) {
|
||||
kwonlyargs.push(name);
|
||||
kw_defaults.push(value.map(Box::new));
|
||||
if let Some(value) = value {
|
||||
kwonlyargs.push(name);
|
||||
kw_defaults.push(value);
|
||||
} else {
|
||||
kwargs.push(name);
|
||||
}
|
||||
}
|
||||
kwargs.extend(kwonlyargs.into_iter());
|
||||
|
||||
let kwarg = kwarg.map(|n| n.1).flatten();
|
||||
let va = va.map(Box::new);
|
||||
|
||||
(va, kwonlyargs, kw_defaults, kwarg)
|
||||
(va, kwargs, kw_defaults, kwarg)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1039,7 +1045,42 @@ Atom: ast::Expr = {
|
||||
}.into())
|
||||
},
|
||||
<location:@L> "{" <e:DictLiteralValues?> "}" => {
|
||||
let (keys, values) = e.unwrap_or_default();
|
||||
let pairs = e.unwrap_or_default();
|
||||
|
||||
let (keys, values) = match pairs.iter().position(|(k,_)| k.is_none()) {
|
||||
Some(unpack_idx) => {
|
||||
let mut pairs = pairs;
|
||||
let (keys, mut values): (_, Vec<_>) = pairs.drain(..unpack_idx).map(|(k, v)| (*k.unwrap(), v)).unzip();
|
||||
|
||||
fn build_map(items: &mut Vec<(ast::Expr, ast::Expr)>) -> ast::Expr {
|
||||
let location = items[0].0.location;
|
||||
let (keys, values) = items.drain(..).unzip();
|
||||
ast::Expr {
|
||||
location,
|
||||
custom: (),
|
||||
node: ast::ExprKind::Dict { keys, values }
|
||||
}
|
||||
}
|
||||
|
||||
let mut items = Vec::new();
|
||||
for (key, value) in pairs.into_iter() {
|
||||
if let Some(key) = key {
|
||||
items.push((*key, value));
|
||||
continue;
|
||||
}
|
||||
if !items.is_empty() {
|
||||
values.push(build_map(&mut items));
|
||||
}
|
||||
values.push(value);
|
||||
}
|
||||
if !items.is_empty() {
|
||||
values.push(build_map(&mut items));
|
||||
}
|
||||
(keys, values)
|
||||
},
|
||||
None => pairs.into_iter().map(|(k, v)| (*k.unwrap(), v)).unzip()
|
||||
};
|
||||
|
||||
ast::Expr {
|
||||
location,
|
||||
custom: (),
|
||||
@@ -1079,8 +1120,8 @@ ListLiteralValues: Vec<ast::Expr> = {
|
||||
<e:OneOrMore<TestOrStarNamedExpr>> ","? => e,
|
||||
};
|
||||
|
||||
DictLiteralValues: (Vec<Option<Box<ast::Expr>>>, Vec<ast::Expr>) = {
|
||||
<elements:OneOrMore<DictElement>> ","? => elements.into_iter().unzip(),
|
||||
DictLiteralValues: Vec<(Option<Box<ast::Expr>>, ast::Expr)> = {
|
||||
<elements:OneOrMore<DictElement>> ","? => elements,
|
||||
};
|
||||
|
||||
DictEntry: (ast::Expr, ast::Expr) = {
|
||||
@@ -1151,7 +1192,7 @@ SingleForComprehension: ast::Comprehension = {
|
||||
target: Box::new(target),
|
||||
iter: Box::new(iter),
|
||||
ifs,
|
||||
is_async
|
||||
is_async: if is_async { 1 } else { 0 },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -160,11 +160,7 @@ impl From<LalrpopError<Location, Tok, LexicalError>> for ParseError {
|
||||
LalrpopError::UnrecognizedToken { token, expected } => {
|
||||
// Hacky, but it's how CPython does it. See PyParser_AddToken,
|
||||
// in particular "Only one possible expected token" comment.
|
||||
let expected = if expected.len() == 1 {
|
||||
Some(expected[0].clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let expected = (expected.len() == 1).then(|| expected[0].clone());
|
||||
ParseError {
|
||||
error: ParseErrorType::UnrecognizedToken(token.1, expected),
|
||||
location: token.0,
|
||||
|
||||
@@ -30,7 +30,7 @@ impl<'a> FStringParser<'a> {
|
||||
let mut expression = String::new();
|
||||
let mut spec = None;
|
||||
let mut delims = Vec::new();
|
||||
let mut conversion = None;
|
||||
let mut conversion = ConversionFlag::None;
|
||||
let mut pred_expression_text = String::new();
|
||||
let mut trailing_seq = String::new();
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<'a> FStringParser<'a> {
|
||||
return Err(EmptyExpression);
|
||||
}
|
||||
|
||||
conversion = Some(match self.chars.next() {
|
||||
conversion = match self.chars.next() {
|
||||
Some('s') => ConversionFlag::Str,
|
||||
Some('a') => ConversionFlag::Ascii,
|
||||
Some('r') => ConversionFlag::Repr,
|
||||
@@ -73,7 +73,7 @@ impl<'a> FStringParser<'a> {
|
||||
None => {
|
||||
return Err(ExpectedRbrace);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if let Some(&peek) = self.chars.peek() {
|
||||
if peek != '}' && peek != ':' {
|
||||
@@ -115,7 +115,7 @@ impl<'a> FStringParser<'a> {
|
||||
)
|
||||
.parse()?,
|
||||
),
|
||||
conversion: None,
|
||||
conversion: ConversionFlag::None as _,
|
||||
format_spec: None,
|
||||
}),
|
||||
);
|
||||
@@ -187,7 +187,7 @@ impl<'a> FStringParser<'a> {
|
||||
parse_fstring_expr(&expression)
|
||||
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
|
||||
),
|
||||
conversion,
|
||||
conversion: conversion as _,
|
||||
format_spec: spec,
|
||||
})]
|
||||
} else {
|
||||
@@ -205,7 +205,7 @@ impl<'a> FStringParser<'a> {
|
||||
parse_fstring_expr(&expression)
|
||||
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
|
||||
),
|
||||
conversion,
|
||||
conversion: conversion as _,
|
||||
format_spec: spec,
|
||||
}),
|
||||
]
|
||||
|
||||
@@ -54,7 +54,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -67,7 +67,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
@@ -128,7 +128,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/fstring.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -55,7 +54,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: Some(
|
||||
Located {
|
||||
location: Location {
|
||||
|
||||
@@ -28,7 +28,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
@@ -50,7 +50,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/fstring.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -58,7 +57,7 @@ Located {
|
||||
],
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/fstring.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -29,7 +28,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: Some(
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -85,14 +84,14 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/fstring.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -58,7 +57,7 @@ Located {
|
||||
],
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/fstring.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -29,7 +28,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: Some(
|
||||
Located {
|
||||
location: Location {
|
||||
|
||||
@@ -54,7 +54,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -54,7 +54,7 @@ Located {
|
||||
ctx: Load,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/fstring.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -28,7 +27,7 @@ Located {
|
||||
value: None,
|
||||
},
|
||||
},
|
||||
conversion: None,
|
||||
conversion: 0,
|
||||
format_spec: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -56,7 +56,7 @@ Located {
|
||||
},
|
||||
},
|
||||
ifs: [],
|
||||
is_async: false,
|
||||
is_async: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
source: parser/src/parser.rs
|
||||
expression: parse_ast
|
||||
|
||||
---
|
||||
Located {
|
||||
location: Location {
|
||||
@@ -69,7 +68,7 @@ Located {
|
||||
},
|
||||
},
|
||||
ifs: [],
|
||||
is_async: false,
|
||||
is_async: 0,
|
||||
},
|
||||
Comprehension {
|
||||
target: Located {
|
||||
@@ -172,7 +171,7 @@ Located {
|
||||
},
|
||||
},
|
||||
],
|
||||
is_async: false,
|
||||
is_async: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -45,7 +45,7 @@ Located {
|
||||
},
|
||||
},
|
||||
ifs: [],
|
||||
is_async: false,
|
||||
is_async: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -71,15 +71,12 @@ impl PyDict {
|
||||
}
|
||||
|
||||
// Used in update and ior.
|
||||
fn merge_object(
|
||||
dict: &DictContentType,
|
||||
other: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
pub(crate) fn merge_object(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let other = match other.downcast_exact(vm) {
|
||||
Ok(dict_other) => return Self::merge_dict(dict, dict_other, vm),
|
||||
Ok(dict_other) => return self.merge_dict(dict_other, vm),
|
||||
Err(other) => other,
|
||||
};
|
||||
let dict = &self.entries;
|
||||
if let Some(keys) = vm.get_method(other.clone(), vm.ctx.intern_str("keys")) {
|
||||
let keys = vm.invoke(&keys?, ())?.get_iter(vm)?;
|
||||
while let PyIterReturn::Return(key) = keys.next(vm)? {
|
||||
@@ -108,11 +105,8 @@ impl PyDict {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn merge_dict(
|
||||
dict: &DictContentType,
|
||||
dict_other: PyDictRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
fn merge_dict(&self, dict_other: PyDictRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let dict = &self.entries;
|
||||
let dict_size = &dict_other.size();
|
||||
for (key, value) in &dict_other {
|
||||
dict.insert(vm, &*key, value)?;
|
||||
@@ -363,7 +357,7 @@ impl PyDict {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
if let OptionalArg::Present(dict_obj) = dict_obj {
|
||||
Self::merge_object(&self.entries, dict_obj, vm)?;
|
||||
self.merge_object(dict_obj, vm)?;
|
||||
}
|
||||
for (key, value) in kwargs.into_iter() {
|
||||
self.entries.insert(vm, &key, value)?;
|
||||
@@ -373,7 +367,7 @@ impl PyDict {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn ior(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
||||
PyDict::merge_object(&zelf.entries, other, vm)?;
|
||||
zelf.merge_object(other, vm)?;
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
@@ -382,7 +376,7 @@ impl PyDict {
|
||||
let dicted: Result<PyDictRef, _> = other.downcast();
|
||||
if let Ok(other) = dicted {
|
||||
let other_cp = other.copy();
|
||||
PyDict::merge_dict(&other_cp.entries, zelf, vm)?;
|
||||
other_cp.merge_dict(zelf, vm)?;
|
||||
return Ok(other_cp.into_pyobject(vm));
|
||||
}
|
||||
Ok(vm.ctx.not_implemented())
|
||||
@@ -393,7 +387,7 @@ impl PyDict {
|
||||
let dicted: Result<PyDictRef, _> = other.downcast();
|
||||
if let Ok(other) = dicted {
|
||||
let self_cp = self.copy();
|
||||
PyDict::merge_dict(&self_cp.entries, other, vm)?;
|
||||
self_cp.merge_dict(other, vm)?;
|
||||
return Ok(self_cp.into_pyobject(vm));
|
||||
}
|
||||
Ok(vm.ctx.not_implemented())
|
||||
|
||||
@@ -677,6 +677,15 @@ impl ExecutingFrame<'_> {
|
||||
unpack,
|
||||
for_call,
|
||||
} => self.execute_build_map(vm, *size, *unpack, *for_call),
|
||||
bytecode::Instruction::DictUpdate => {
|
||||
let other = self.pop_value();
|
||||
let dict = self
|
||||
.last_value_ref()
|
||||
.downcast_ref::<PyDict>()
|
||||
.expect("exact dict expected");
|
||||
dict.merge_object(other, vm)?;
|
||||
Ok(None)
|
||||
}
|
||||
bytecode::Instruction::BuildSlice { step } => self.execute_build_slice(vm, *step),
|
||||
bytecode::Instruction::ListAppend { i } => {
|
||||
let item = self.pop_value();
|
||||
|
||||
@@ -239,7 +239,11 @@ impl Node for ast::Constant {
|
||||
}
|
||||
builtins::singletons::PyNone => ast::Constant::None,
|
||||
builtins::slice::PyEllipsis => ast::Constant::Ellipsis,
|
||||
_ => return Err(vm.new_type_error("unsupported type for constant".to_owned())),
|
||||
obj =>
|
||||
return Err(vm.new_type_error(format!(
|
||||
"invalid type in Constant: type '{}'",
|
||||
obj.class().name()
|
||||
))),
|
||||
});
|
||||
Ok(constant)
|
||||
}
|
||||
@@ -252,8 +256,8 @@ impl Node for ast::ConversionFlag {
|
||||
|
||||
fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult<Self> {
|
||||
i32::try_from_object(vm, object)?
|
||||
.to_u8()
|
||||
.and_then(ast::ConversionFlag::try_from_byte)
|
||||
.to_usize()
|
||||
.and_then(|f| f.try_into().ok())
|
||||
.ok_or_else(|| vm.new_value_error("invalid conversion flag".to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
596
vm/src/stdlib/ast/gen.rs
generated
596
vm/src/stdlib/ast/gen.rs
generated
@@ -458,6 +458,32 @@ impl NodeAsyncWith {
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "Match", base = "NodeKindStmt")]
|
||||
struct NodeMatch;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatch {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("subject")).into(),
|
||||
ctx.new_str(ascii!("cases")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "Raise", base = "NodeKindStmt")]
|
||||
struct NodeRaise;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
@@ -1755,9 +1781,9 @@ impl NodeNotIn {
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "comprehension", base = "AstNode")]
|
||||
struct Nodecomprehension;
|
||||
struct NodeComprehension;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl Nodecomprehension {
|
||||
impl NodeComprehension {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
@@ -1809,9 +1835,9 @@ impl NodeExceptHandler {
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "arguments", base = "AstNode")]
|
||||
struct Nodearguments;
|
||||
struct NodeArguments;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl Nodearguments {
|
||||
impl NodeArguments {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
@@ -1831,9 +1857,9 @@ impl Nodearguments {
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "arg", base = "AstNode")]
|
||||
struct Nodearg;
|
||||
struct NodeArg;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl Nodearg {
|
||||
impl NodeArg {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
@@ -1858,9 +1884,9 @@ impl Nodearg {
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "keyword", base = "AstNode")]
|
||||
struct Nodekeyword;
|
||||
struct NodeKeyword;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl Nodekeyword {
|
||||
impl NodeKeyword {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
@@ -1884,9 +1910,9 @@ impl Nodekeyword {
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "alias", base = "AstNode")]
|
||||
struct Nodealias;
|
||||
struct NodeAlias;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl Nodealias {
|
||||
impl NodeAlias {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
@@ -1897,13 +1923,22 @@ impl Nodealias {
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(identifier!(ctx, _attributes), ctx.new_list(vec![]).into());
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "withitem", base = "AstNode")]
|
||||
struct Nodewithitem;
|
||||
struct NodeWithitem;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl Nodewithitem {
|
||||
impl NodeWithitem {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
@@ -1917,6 +1952,224 @@ impl Nodewithitem {
|
||||
class.set_attr(identifier!(ctx, _attributes), ctx.new_list(vec![]).into());
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "match_case", base = "AstNode")]
|
||||
struct NodeMatchCase;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchCase {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("pattern")).into(),
|
||||
ctx.new_str(ascii!("guard")).into(),
|
||||
ctx.new_str(ascii!("body")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(identifier!(ctx, _attributes), ctx.new_list(vec![]).into());
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "pattern", base = "AstNode")]
|
||||
struct NodeKindPattern;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeKindPattern {}
|
||||
#[pyclass(module = "_ast", name = "MatchValue", base = "NodeKindPattern")]
|
||||
struct NodeMatchValue;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchValue {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![ctx.new_str(ascii!("value")).into()])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchSingleton", base = "NodeKindPattern")]
|
||||
struct NodeMatchSingleton;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchSingleton {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![ctx.new_str(ascii!("value")).into()])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchSequence", base = "NodeKindPattern")]
|
||||
struct NodeMatchSequence;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchSequence {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![ctx.new_str(ascii!("patterns")).into()])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchMapping", base = "NodeKindPattern")]
|
||||
struct NodeMatchMapping;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchMapping {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("keys")).into(),
|
||||
ctx.new_str(ascii!("patterns")).into(),
|
||||
ctx.new_str(ascii!("rest")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchClass", base = "NodeKindPattern")]
|
||||
struct NodeMatchClass;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchClass {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("cls")).into(),
|
||||
ctx.new_str(ascii!("patterns")).into(),
|
||||
ctx.new_str(ascii!("kwd_attrs")).into(),
|
||||
ctx.new_str(ascii!("kwd_patterns")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchStar", base = "NodeKindPattern")]
|
||||
struct NodeMatchStar;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchStar {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![ctx.new_str(ascii!("name")).into()])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchAs", base = "NodeKindPattern")]
|
||||
struct NodeMatchAs;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchAs {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("pattern")).into(),
|
||||
ctx.new_str(ascii!("name")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "MatchOr", base = "NodeKindPattern")]
|
||||
struct NodeMatchOr;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
impl NodeMatchOr {
|
||||
#[extend_class]
|
||||
fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
|
||||
class.set_attr(
|
||||
identifier!(ctx, _fields),
|
||||
ctx.new_list(vec![ctx.new_str(ascii!("patterns")).into()])
|
||||
.into(),
|
||||
);
|
||||
class.set_attr(
|
||||
identifier!(ctx, _attributes),
|
||||
ctx.new_list(vec![
|
||||
ctx.new_str(ascii!("lineno")).into(),
|
||||
ctx.new_str(ascii!("col_offset")).into(),
|
||||
ctx.new_str(ascii!("end_lineno")).into(),
|
||||
ctx.new_str(ascii!("end_col_offset")).into(),
|
||||
])
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
#[pyclass(module = "_ast", name = "type_ignore", base = "AstNode")]
|
||||
struct NodeKindTypeIgnore;
|
||||
#[pyclass(flags(HAS_DICT, BASETYPE))]
|
||||
@@ -2334,6 +2587,19 @@ impl Node for ast::StmtKind {
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::StmtKind::Match { subject, cases } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatch::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("subject", subject.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("cases", cases.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::StmtKind::Raise { exc, cause } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeRaise::static_type().to_owned())
|
||||
@@ -2629,6 +2895,14 @@ impl Node for ast::StmtKind {
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
}
|
||||
} else if _cls.is(NodeMatch::static_type()) {
|
||||
ast::StmtKind::Match {
|
||||
subject: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "subject", "stmt")?,
|
||||
)?,
|
||||
cases: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "cases", "stmt")?)?,
|
||||
}
|
||||
} else if _cls.is(NodeRaise::static_type()) {
|
||||
ast::StmtKind::Raise {
|
||||
exc: get_node_field_opt(_vm, &_object, "exc")?
|
||||
@@ -2671,7 +2945,9 @@ impl Node for ast::StmtKind {
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
names: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "names", "stmt")?)?,
|
||||
level: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "level", "stmt")?)?,
|
||||
level: get_node_field_opt(_vm, &_object, "level")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
}
|
||||
} else if _cls.is(NodeGlobal::static_type()) {
|
||||
ast::StmtKind::Global {
|
||||
@@ -3186,9 +3462,10 @@ impl Node for ast::ExprKind {
|
||||
} else if _cls.is(NodeFormattedValue::static_type()) {
|
||||
ast::ExprKind::FormattedValue {
|
||||
value: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "value", "expr")?)?,
|
||||
conversion: get_node_field_opt(_vm, &_object, "conversion")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
conversion: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "conversion", "expr")?,
|
||||
)?,
|
||||
format_spec: get_node_field_opt(_vm, &_object, "format_spec")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
@@ -3617,7 +3894,7 @@ impl Node for ast::Comprehension {
|
||||
is_async,
|
||||
} = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, Nodecomprehension::static_type().to_owned())
|
||||
.into_ref_with_type(_vm, NodeComprehension::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
@@ -3725,7 +4002,7 @@ impl Node for ast::Arguments {
|
||||
defaults,
|
||||
} = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, Nodearguments::static_type().to_owned())
|
||||
.into_ref_with_type(_vm, NodeArguments::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
@@ -3790,7 +4067,7 @@ impl Node for ast::ArgData {
|
||||
type_comment,
|
||||
} = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, Nodearg::static_type().to_owned())
|
||||
.into_ref_with_type(_vm, NodeArg::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap();
|
||||
@@ -3825,7 +4102,7 @@ impl Node for ast::KeywordData {
|
||||
fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ast::KeywordData { arg, value } = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, Nodekeyword::static_type().to_owned())
|
||||
.into_ref_with_type(_vm, NodeKeyword::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap();
|
||||
@@ -3847,14 +4124,14 @@ impl Node for ast::KeywordData {
|
||||
})
|
||||
}
|
||||
}
|
||||
impl NamedNode for ast::Alias {
|
||||
impl NamedNode for ast::AliasData {
|
||||
const NAME: &'static str = "alias";
|
||||
}
|
||||
impl Node for ast::Alias {
|
||||
impl Node for ast::AliasData {
|
||||
fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ast::Alias { name, asname } = self;
|
||||
let ast::AliasData { name, asname } = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, Nodealias::static_type().to_owned())
|
||||
.into_ref_with_type(_vm, NodeAlias::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
@@ -3866,7 +4143,11 @@ impl Node for ast::Alias {
|
||||
_node.into()
|
||||
}
|
||||
fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {
|
||||
Ok(ast::Alias {
|
||||
let _location = ast::Location::new(
|
||||
Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "alias")?)?,
|
||||
Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "alias")?)?,
|
||||
);
|
||||
Ok(ast::AliasData {
|
||||
name: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "name", "alias")?)?,
|
||||
asname: get_node_field_opt(_vm, &_object, "asname")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
@@ -3884,7 +4165,7 @@ impl Node for ast::Withitem {
|
||||
optional_vars,
|
||||
} = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, Nodewithitem::static_type().to_owned())
|
||||
.into_ref_with_type(_vm, NodeWithitem::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
@@ -3907,6 +4188,244 @@ impl Node for ast::Withitem {
|
||||
})
|
||||
}
|
||||
}
|
||||
impl NamedNode for ast::MatchCase {
|
||||
const NAME: &'static str = "match_case";
|
||||
}
|
||||
impl Node for ast::MatchCase {
|
||||
fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ast::MatchCase {
|
||||
pattern,
|
||||
guard,
|
||||
body,
|
||||
} = self;
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchCase::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("pattern", pattern.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("guard", guard.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("body", body.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {
|
||||
Ok(ast::MatchCase {
|
||||
pattern: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "pattern", "match_case")?,
|
||||
)?,
|
||||
guard: get_node_field_opt(_vm, &_object, "guard")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
body: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "body", "match_case")?)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl NamedNode for ast::PatternKind {
|
||||
const NAME: &'static str = "pattern";
|
||||
}
|
||||
impl Node for ast::PatternKind {
|
||||
fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
match self {
|
||||
ast::PatternKind::MatchValue { value } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchValue::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("value", value.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchSingleton { value } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchSingleton::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("value", value.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchSequence { patterns } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchSequence::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("patterns", patterns.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchMapping {
|
||||
keys,
|
||||
patterns,
|
||||
rest,
|
||||
} => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchMapping::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("keys", keys.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("patterns", patterns.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("rest", rest.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchClass {
|
||||
cls,
|
||||
patterns,
|
||||
kwd_attrs,
|
||||
kwd_patterns,
|
||||
} => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchClass::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict.set_item("cls", cls.ast_to_object(_vm), _vm).unwrap();
|
||||
_dict
|
||||
.set_item("patterns", patterns.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("kwd_attrs", kwd_attrs.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("kwd_patterns", kwd_patterns.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchStar { name } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchStar::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("name", name.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchAs { pattern, name } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchAs::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("pattern", pattern.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_dict
|
||||
.set_item("name", name.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
ast::PatternKind::MatchOr { patterns } => {
|
||||
let _node = AstNode
|
||||
.into_ref_with_type(_vm, NodeMatchOr::static_type().to_owned())
|
||||
.unwrap();
|
||||
let _dict = _node.as_object().dict().unwrap();
|
||||
_dict
|
||||
.set_item("patterns", patterns.ast_to_object(_vm), _vm)
|
||||
.unwrap();
|
||||
_node.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {
|
||||
let _location = ast::Location::new(
|
||||
Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "pattern")?)?,
|
||||
Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "pattern")?)?,
|
||||
);
|
||||
let _cls = _object.class();
|
||||
Ok(if _cls.is(NodeMatchValue::static_type()) {
|
||||
ast::PatternKind::MatchValue {
|
||||
value: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "value", "pattern")?,
|
||||
)?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchSingleton::static_type()) {
|
||||
ast::PatternKind::MatchSingleton {
|
||||
value: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "value", "pattern")?,
|
||||
)?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchSequence::static_type()) {
|
||||
ast::PatternKind::MatchSequence {
|
||||
patterns: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "patterns", "pattern")?,
|
||||
)?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchMapping::static_type()) {
|
||||
ast::PatternKind::MatchMapping {
|
||||
keys: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "keys", "pattern")?,
|
||||
)?,
|
||||
patterns: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "patterns", "pattern")?,
|
||||
)?,
|
||||
rest: get_node_field_opt(_vm, &_object, "rest")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchClass::static_type()) {
|
||||
ast::PatternKind::MatchClass {
|
||||
cls: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "cls", "pattern")?)?,
|
||||
patterns: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "patterns", "pattern")?,
|
||||
)?,
|
||||
kwd_attrs: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "kwd_attrs", "pattern")?,
|
||||
)?,
|
||||
kwd_patterns: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "kwd_patterns", "pattern")?,
|
||||
)?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchStar::static_type()) {
|
||||
ast::PatternKind::MatchStar {
|
||||
name: get_node_field_opt(_vm, &_object, "name")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchAs::static_type()) {
|
||||
ast::PatternKind::MatchAs {
|
||||
pattern: get_node_field_opt(_vm, &_object, "pattern")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
name: get_node_field_opt(_vm, &_object, "name")?
|
||||
.map(|obj| Node::ast_from_object(_vm, obj))
|
||||
.transpose()?,
|
||||
}
|
||||
} else if _cls.is(NodeMatchOr::static_type()) {
|
||||
ast::PatternKind::MatchOr {
|
||||
patterns: Node::ast_from_object(
|
||||
_vm,
|
||||
get_node_field(_vm, &_object, "patterns", "pattern")?,
|
||||
)?,
|
||||
}
|
||||
} else {
|
||||
return Err(_vm.new_type_error(format!(
|
||||
"expected some sort of pattern, but got {}",
|
||||
_object.repr(_vm)?
|
||||
)));
|
||||
})
|
||||
}
|
||||
}
|
||||
impl NamedNode for ast::TypeIgnore {
|
||||
const NAME: &'static str = "type_ignore";
|
||||
}
|
||||
@@ -3970,6 +4489,7 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &PyObject) {
|
||||
"If" => NodeIf::make_class(&vm.ctx),
|
||||
"With" => NodeWith::make_class(&vm.ctx),
|
||||
"AsyncWith" => NodeAsyncWith::make_class(&vm.ctx),
|
||||
"Match" => NodeMatch::make_class(&vm.ctx),
|
||||
"Raise" => NodeRaise::make_class(&vm.ctx),
|
||||
"Try" => NodeTry::make_class(&vm.ctx),
|
||||
"Assert" => NodeAssert::make_class(&vm.ctx),
|
||||
@@ -4046,14 +4566,24 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &PyObject) {
|
||||
"IsNot" => NodeIsNot::make_class(&vm.ctx),
|
||||
"In" => NodeIn::make_class(&vm.ctx),
|
||||
"NotIn" => NodeNotIn::make_class(&vm.ctx),
|
||||
"comprehension" => Nodecomprehension::make_class(&vm.ctx),
|
||||
"comprehension" => NodeComprehension::make_class(&vm.ctx),
|
||||
"excepthandler" => NodeKindExcepthandler::make_class(&vm.ctx),
|
||||
"ExceptHandler" => NodeExceptHandler::make_class(&vm.ctx),
|
||||
"arguments" => Nodearguments::make_class(&vm.ctx),
|
||||
"arg" => Nodearg::make_class(&vm.ctx),
|
||||
"keyword" => Nodekeyword::make_class(&vm.ctx),
|
||||
"alias" => Nodealias::make_class(&vm.ctx),
|
||||
"withitem" => Nodewithitem::make_class(&vm.ctx),
|
||||
"arguments" => NodeArguments::make_class(&vm.ctx),
|
||||
"arg" => NodeArg::make_class(&vm.ctx),
|
||||
"keyword" => NodeKeyword::make_class(&vm.ctx),
|
||||
"alias" => NodeAlias::make_class(&vm.ctx),
|
||||
"withitem" => NodeWithitem::make_class(&vm.ctx),
|
||||
"match_case" => NodeMatchCase::make_class(&vm.ctx),
|
||||
"pattern" => NodeKindPattern::make_class(&vm.ctx),
|
||||
"MatchValue" => NodeMatchValue::make_class(&vm.ctx),
|
||||
"MatchSingleton" => NodeMatchSingleton::make_class(&vm.ctx),
|
||||
"MatchSequence" => NodeMatchSequence::make_class(&vm.ctx),
|
||||
"MatchMapping" => NodeMatchMapping::make_class(&vm.ctx),
|
||||
"MatchClass" => NodeMatchClass::make_class(&vm.ctx),
|
||||
"MatchStar" => NodeMatchStar::make_class(&vm.ctx),
|
||||
"MatchAs" => NodeMatchAs::make_class(&vm.ctx),
|
||||
"MatchOr" => NodeMatchOr::make_class(&vm.ctx),
|
||||
"type_ignore" => NodeKindTypeIgnore::make_class(&vm.ctx),
|
||||
"TypeIgnore" => NodeTypeIgnore::make_class(&vm.ctx),
|
||||
})
|
||||
|
||||
@@ -109,6 +109,8 @@ mod builtins {
|
||||
dont_inherit: OptionalArg<bool>,
|
||||
#[pyarg(any, optional)]
|
||||
optimize: OptionalArg<PyIntRef>,
|
||||
#[pyarg(any, optional)]
|
||||
_feature_version: OptionalArg<i32>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
@@ -122,6 +124,10 @@ mod builtins {
|
||||
{
|
||||
use crate::{class::PyClassImpl, stdlib::ast};
|
||||
|
||||
if args._feature_version.is_present() {
|
||||
eprintln!("TODO: compile() got `_feature_version` but ignored");
|
||||
}
|
||||
|
||||
let mode_str = args.mode.as_str();
|
||||
|
||||
if args
|
||||
|
||||
Reference in New Issue
Block a user