diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index fc04114949c0c3..ff94c8ee71e730 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -152,9 +152,9 @@ Literals .. doctest:: - >>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('123', mode='eval'), indent=4, omit_defaults=False)) Expression( - body=Constant(value=123)) + body=Constant(value=123, kind=None)) .. class:: FormattedValue(value, conversion, format_spec) @@ -184,15 +184,16 @@ Literals .. doctest:: - >>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4, omit_defaults=False)) Expression( body=JoinedStr( values=[ - Constant(value='sin('), + Constant(value='sin(', kind=None), FormattedValue( value=Name(id='a', ctx=Load()), - conversion=-1), - Constant(value=') is '), + conversion=-1, + format_spec=None), + Constant(value=') is ', kind=None), FormattedValue( value=Call( func=Name(id='sin', ctx=Load()), @@ -202,7 +203,7 @@ Literals conversion=-1, format_spec=JoinedStr( values=[ - Constant(value='.3')]))])) + Constant(value='.3', kind=None)]))])) .. class:: List(elts, ctx) @@ -214,21 +215,21 @@ Literals .. doctest:: - >>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4, omit_defaults=False)) Expression( body=List( elts=[ - Constant(value=1), - Constant(value=2), - Constant(value=3)], + Constant(value=1, kind=None), + Constant(value=2, kind=None), + Constant(value=3, kind=None)], ctx=Load())) - >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Tuple( elts=[ - Constant(value=1), - Constant(value=2), - Constant(value=3)], + Constant(value=1, kind=None), + Constant(value=2, kind=None), + Constant(value=3, kind=None)], ctx=Load())) @@ -238,13 +239,13 @@ Literals .. doctest:: - >>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Set( elts=[ - Constant(value=1), - Constant(value=2), - Constant(value=3)])) + Constant(value=1, kind=None), + Constant(value=2, kind=None), + Constant(value=3, kind=None)])) .. class:: Dict(keys, values) @@ -259,14 +260,14 @@ Literals .. doctest:: - >>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Dict( keys=[ - Constant(value='a'), + Constant(value='a', kind=None), None], values=[ - Constant(value=1), + Constant(value=1, kind=None), Name(id='d', ctx=Load())])) @@ -289,23 +290,24 @@ Variables .. doctest:: - >>> print(ast.dump(ast.parse('a'), indent=4)) + >>> print(ast.dump(ast.parse('a'), indent=4, omit_defaults=False)) Module( body=[ Expr( value=Name(id='a', ctx=Load()))], type_ignores=[]) - >>> print(ast.dump(ast.parse('a = 1'), indent=4)) + >>> print(ast.dump(ast.parse('a = 1'), indent=4, omit_defaults=False)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], - value=Constant(value=1))], + value=Constant(value=1, kind=None), + type_comment=None)], type_ignores=[]) - >>> print(ast.dump(ast.parse('del a'), indent=4)) + >>> print(ast.dump(ast.parse('del a'), indent=4, omit_defaults=False)) Module( body=[ Delete( @@ -322,7 +324,7 @@ Variables .. doctest:: - >>> print(ast.dump(ast.parse('a, *b = it'), indent=4)) + >>> print(ast.dump(ast.parse('a, *b = it'), indent=4, omit_defaults=False)) Module( body=[ Assign( @@ -334,7 +336,8 @@ Variables value=Name(id='b', ctx=Store()), ctx=Store())], ctx=Store())], - value=Name(id='it', ctx=Load()))], + value=Name(id='it', ctx=Load()), + type_comment=None)], type_ignores=[]) @@ -350,7 +353,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('-a'), indent=4)) + >>> print(ast.dump(ast.parse('-a'), indent=4, omit_defaults=False)) Module( body=[ Expr( @@ -376,7 +379,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4, omit_defaults=False)) Expression( body=UnaryOp( op=Not(), @@ -390,7 +393,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4, omit_defaults=False)) Expression( body=BinOp( left=Name(id='x', ctx=Load()), @@ -426,7 +429,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4, omit_defaults=False)) Expression( body=BoolOp( op=Or(), @@ -449,16 +452,16 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Compare( - left=Constant(value=1), + left=Constant(value=1, kind=None), ops=[ LtE(), Lt()], comparators=[ Name(id='a', ctx=Load()), - Constant(value=10)])) + Constant(value=10, kind=None)])) .. class:: Eq @@ -489,7 +492,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Call( func=Name(id='func', ctx=Load()), @@ -503,6 +506,7 @@ Expressions arg='b', value=Name(id='c', ctx=Load())), keyword( + arg=None, value=Name(id='e', ctx=Load()))])) @@ -519,7 +523,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4, omit_defaults=False)) Expression( body=IfExp( test=Name(id='b', ctx=Load()), @@ -536,7 +540,7 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Attribute( value=Name(id='snake', ctx=Load()), @@ -553,11 +557,11 @@ Expressions .. doctest:: - >>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4, omit_defaults=False)) Expression( body=NamedExpr( target=Name(id='x', ctx=Store()), - value=Constant(value=4))) + value=Constant(value=4, kind=None))) Subscripting @@ -571,18 +575,20 @@ Subscripting ``ctx`` is :class:`Load`, :class:`Store` or :class:`Del` according to the action performed with the subscript. + .. doctest:: - >>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Tuple( elts=[ Slice( - lower=Constant(value=1), - upper=Constant(value=2)), - Constant(value=3)], + lower=Constant(value=1, kind=None), + upper=Constant(value=2, kind=None), + step=None), + Constant(value=3, kind=None)], ctx=Load()), ctx=Load())) @@ -595,13 +601,14 @@ Subscripting .. doctest:: - >>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4, omit_defaults=False)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Slice( - lower=Constant(value=1), - upper=Constant(value=2)), + lower=Constant(value=1, kind=None), + upper=Constant(value=2, kind=None), + step=None), ctx=Load())) @@ -621,7 +628,7 @@ Comprehensions .. doctest:: - >>> print(ast.dump(ast.parse('[x for x in numbers]', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('[x for x in numbers]', mode='eval'), indent=4, omit_defaults=False)) Expression( body=ListComp( elt=Name(id='x', ctx=Load()), @@ -631,21 +638,21 @@ Comprehensions iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) - >>> print(ast.dump(ast.parse('{x: x**2 for x in numbers}', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('{x: x**2 for x in numbers}', mode='eval'), indent=4, omit_defaults=False)) Expression( body=DictComp( key=Name(id='x', ctx=Load()), value=BinOp( left=Name(id='x', ctx=Load()), op=Pow(), - right=Constant(value=2)), + right=Constant(value=2, kind=None)), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) - >>> print(ast.dump(ast.parse('{x for x in numbers}', mode='eval'), indent=4)) + >>> print(ast.dump(ast.parse('{x for x in numbers}', mode='eval'), indent=4, omit_defaults=False)) Expression( body=SetComp( elt=Name(id='x', ctx=Load()), @@ -670,7 +677,7 @@ Comprehensions .. doctest:: >>> print(ast.dump(ast.parse('[ord(c) for line in file for c in line]', mode='eval'), - ... indent=4)) # Multiple comprehensions in one. + ... indent=4, omit_defaults=False)) # Multiple comprehensions in one. Expression( body=ListComp( elt=Call( @@ -691,13 +698,13 @@ Comprehensions is_async=0)])) >>> print(ast.dump(ast.parse('(n**2 for n in it if n>5 if n<10)', mode='eval'), - ... indent=4)) # generator comprehension + ... indent=4, omit_defaults=False)) # generator comprehension Expression( body=GeneratorExp( elt=BinOp( left=Name(id='n', ctx=Load()), op=Pow(), - right=Constant(value=2)), + right=Constant(value=2, kind=None)), generators=[ comprehension( target=Name(id='n', ctx=Store()), @@ -708,17 +715,17 @@ Comprehensions ops=[ Gt()], comparators=[ - Constant(value=5)]), + Constant(value=5, kind=None)]), Compare( left=Name(id='n', ctx=Load()), ops=[ Lt()], comparators=[ - Constant(value=10)])], + Constant(value=10, kind=None)])], is_async=0)])) >>> print(ast.dump(ast.parse('[i async for i in soc]', mode='eval'), - ... indent=4)) # Async comprehension + ... indent=4, omit_defaults=False)) # Async comprehension Expression( body=ListComp( elt=Name(id='i', ctx=Load()), @@ -746,17 +753,18 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('a = b = 1'), indent=4)) # Multiple assignment + >>> print(ast.dump(ast.parse('a = b = 1'), indent=4, omit_defaults=False)) # Multiple assignment Module( body=[ Assign( targets=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], - value=Constant(value=1))], + value=Constant(value=1, kind=None), + type_comment=None)], type_ignores=[]) - >>> print(ast.dump(ast.parse('a,b = c'), indent=4)) # Unpacking + >>> print(ast.dump(ast.parse('a,b = c'), indent=4, omit_defaults=False)) # Unpacking Module( body=[ Assign( @@ -766,7 +774,8 @@ Statements Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store())], - value=Name(id='c', ctx=Load()))], + value=Name(id='c', ctx=Load()), + type_comment=None)], type_ignores=[]) @@ -781,26 +790,27 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('c: int'), indent=4)) + >>> print(ast.dump(ast.parse('c: int'), indent=4, omit_defaults=False)) Module( body=[ AnnAssign( target=Name(id='c', ctx=Store()), annotation=Name(id='int', ctx=Load()), + value=None, simple=1)], type_ignores=[]) - >>> print(ast.dump(ast.parse('(a): int = 1'), indent=4)) # Annotation with parenthesis + >>> print(ast.dump(ast.parse('(a): int = 1'), indent=4, omit_defaults=False)) # Annotation with parenthesis Module( body=[ AnnAssign( target=Name(id='a', ctx=Store()), annotation=Name(id='int', ctx=Load()), - value=Constant(value=1), + value=Constant(value=1, kind=None), simple=0)], type_ignores=[]) - >>> print(ast.dump(ast.parse('a.b: int'), indent=4)) # Attribute annotation + >>> print(ast.dump(ast.parse('a.b: int'), indent=4, omit_defaults=False)) # Attribute annotation Module( body=[ AnnAssign( @@ -809,18 +819,20 @@ Statements attr='b', ctx=Store()), annotation=Name(id='int', ctx=Load()), + value=None, simple=0)], type_ignores=[]) - >>> print(ast.dump(ast.parse('a[1]: int'), indent=4)) # Subscript annotation + >>> print(ast.dump(ast.parse('a[1]: int'), indent=4, omit_defaults=False)) # Subscript annotation Module( body=[ AnnAssign( target=Subscript( value=Name(id='a', ctx=Load()), - slice=Constant(value=1), + slice=Constant(value=1, kind=None), ctx=Store()), annotation=Name(id='int', ctx=Load()), + value=None, simple=0)], type_ignores=[]) @@ -837,13 +849,13 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('x += 2'), indent=4)) + >>> print(ast.dump(ast.parse('x += 2'), indent=4, omit_defaults=False)) Module( body=[ AugAssign( target=Name(id='x', ctx=Store()), op=Add(), - value=Constant(value=2))], + value=Constant(value=2, kind=None))], type_ignores=[]) @@ -855,7 +867,7 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('raise x from y'), indent=4)) + >>> print(ast.dump(ast.parse('raise x from y'), indent=4, omit_defaults=False)) Module( body=[ Raise( @@ -871,7 +883,7 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('assert x,y'), indent=4)) + >>> print(ast.dump(ast.parse('assert x,y'), indent=4, omit_defaults=False)) Module( body=[ Assert( @@ -887,7 +899,7 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('del x,y,z'), indent=4)) + >>> print(ast.dump(ast.parse('del x,y,z'), indent=4, omit_defaults=False)) Module( body=[ Delete( @@ -904,7 +916,7 @@ Statements .. doctest:: - >>> print(ast.dump(ast.parse('pass'), indent=4)) + >>> print(ast.dump(ast.parse('pass'), indent=4, omit_defaults=False)) Module( body=[ Pass()], @@ -923,14 +935,14 @@ Imports .. doctest:: - >>> print(ast.dump(ast.parse('import x,y,z'), indent=4)) + >>> print(ast.dump(ast.parse('import x,y,z'), indent=4, omit_defaults=False)) Module( body=[ Import( names=[ - alias(name='x'), - alias(name='y'), - alias(name='z')])], + alias(name='x', asname=None), + alias(name='y', asname=None), + alias(name='z', asname=None)])], type_ignores=[]) @@ -943,15 +955,15 @@ Imports .. doctest:: - >>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4)) + >>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4, omit_defaults=False)) Module( body=[ ImportFrom( module='y', names=[ - alias(name='x'), - alias(name='y'), - alias(name='z')], + alias(name='x', asname=None), + alias(name='y', asname=None), + alias(name='z', asname=None)], level=0)], type_ignores=[]) @@ -963,14 +975,14 @@ Imports .. doctest:: - >>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4)) + >>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4, omit_defaults=False)) Module( body=[ ImportFrom( module='foo.bar', names=[ alias(name='a', asname='b'), - alias(name='c')], + alias(name='c', asname=None)], level=2)], type_ignores=[]) @@ -999,23 +1011,23 @@ Control flow ... ... ... else: ... ... - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ If( test=Name(id='x', ctx=Load()), body=[ Expr( - value=Constant(value=Ellipsis))], + value=Constant(value=Ellipsis, kind=None))], orelse=[ If( test=Name(id='y', ctx=Load()), body=[ Expr( - value=Constant(value=Ellipsis))], + value=Constant(value=Ellipsis, kind=None))], orelse=[ Expr( - value=Constant(value=Ellipsis))])])], + value=Constant(value=Ellipsis, kind=None))])])], type_ignores=[]) @@ -1038,7 +1050,7 @@ Control flow ... ... ... else: ... ... - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ For( @@ -1046,10 +1058,11 @@ Control flow iter=Name(id='y', ctx=Load()), body=[ Expr( - value=Constant(value=Ellipsis))], + value=Constant(value=Ellipsis, kind=None))], orelse=[ Expr( - value=Constant(value=Ellipsis))])], + value=Constant(value=Ellipsis, kind=None))], + type_comment=None)], type_ignores=[]) @@ -1065,17 +1078,17 @@ Control flow ... ... ... else: ... ... - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ While( test=Name(id='x', ctx=Load()), body=[ Expr( - value=Constant(value=Ellipsis))], + value=Constant(value=Ellipsis, kind=None))], orelse=[ Expr( - value=Constant(value=Ellipsis))])], + value=Constant(value=Ellipsis, kind=None))])], type_ignores=[]) @@ -1093,7 +1106,7 @@ Control flow ... else: ... continue ... - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ For( @@ -1106,12 +1119,13 @@ Control flow ops=[ Gt()], comparators=[ - Constant(value=5)]), + Constant(value=5, kind=None)]), body=[ Break()], orelse=[ Continue()])], - orelse=[])], + orelse=[], + type_comment=None)], type_ignores=[]) @@ -1133,31 +1147,32 @@ Control flow ... ... ... finally: ... ... - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ Try( body=[ Expr( - value=Constant(value=Ellipsis))], + value=Constant(value=Ellipsis, kind=None))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), + name=None, body=[ Expr( - value=Constant(value=Ellipsis))]), + value=Constant(value=Ellipsis, kind=None))]), ExceptHandler( type=Name(id='OtherException', ctx=Load()), name='e', body=[ Expr( - value=Constant(value=Ellipsis))])], + value=Constant(value=Ellipsis, kind=None))])], orelse=[ Expr( - value=Constant(value=Ellipsis))], + value=Constant(value=Ellipsis, kind=None))], finalbody=[ Expr( - value=Constant(value=Ellipsis))])], + value=Constant(value=Ellipsis, kind=None))])], type_ignores=[]) @@ -1175,7 +1190,7 @@ Control flow ... a + 1 ... except TypeError: ... pass - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ Try( @@ -1184,10 +1199,11 @@ Control flow value=BinOp( left=Name(id='a', ctx=Load()), op=Add(), - right=Constant(value=1)))], + right=Constant(value=1, kind=None)))], handlers=[ ExceptHandler( type=Name(id='TypeError', ctx=Load()), + name=None, body=[ Pass()])], orelse=[], @@ -1217,7 +1233,7 @@ Control flow >>> print(ast.dump(ast.parse("""\ ... with a as b, c as d: ... something(b, d) - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ With( @@ -1235,7 +1251,8 @@ Control flow args=[ Name(id='b', ctx=Load()), Name(id='d', ctx=Load())], - keywords=[]))])], + keywords=[]))], + type_comment=None)], type_ignores=[]) @@ -1265,7 +1282,7 @@ Function and class definitions .. doctest:: - >>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4)) + >>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4, omit_defaults=False)) Module( body=[ Expr( @@ -1273,12 +1290,14 @@ Function and class definitions args=arguments( posonlyargs=[], args=[ - arg(arg='x'), - arg(arg='y')], + arg(arg='x', annotation=None, type_comment=None), + arg(arg='y', annotation=None, type_comment=None)], + vararg=None, kwonlyargs=[], kw_defaults=[], + kwarg=None, defaults=[]), - body=Constant(value=Ellipsis)))], + body=Constant(value=Ellipsis, kind=None)))], type_ignores=[]) @@ -1313,7 +1332,7 @@ Function and class definitions ... @decorator2 ... def f(a: 'annotation', b=1, c=2, *d, e, f=3, **g) -> 'return annotation': ... pass - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ FunctionDef( @@ -1323,26 +1342,28 @@ Function and class definitions args=[ arg( arg='a', - annotation=Constant(value='annotation')), - arg(arg='b'), - arg(arg='c')], - vararg=arg(arg='d'), + annotation=Constant(value='annotation', kind=None), + type_comment=None), + arg(arg='b', annotation=None, type_comment=None), + arg(arg='c', annotation=None, type_comment=None)], + vararg=arg(arg='d', annotation=None, type_comment=None), kwonlyargs=[ - arg(arg='e'), - arg(arg='f')], + arg(arg='e', annotation=None, type_comment=None), + arg(arg='f', annotation=None, type_comment=None)], kw_defaults=[ None, - Constant(value=3)], - kwarg=arg(arg='g'), + Constant(value=3, kind=None)], + kwarg=arg(arg='g', annotation=None, type_comment=None), defaults=[ - Constant(value=1), - Constant(value=2)]), + Constant(value=1, kind=None), + Constant(value=2, kind=None)]), body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())], - returns=Constant(value='return annotation'))], + returns=Constant(value='return annotation', kind=None), + type_comment=None)], type_ignores=[]) @@ -1352,11 +1373,11 @@ Function and class definitions .. doctest:: - >>> print(ast.dump(ast.parse('return 4'), indent=4)) + >>> print(ast.dump(ast.parse('return 4'), indent=4, omit_defaults=False)) Module( body=[ Return( - value=Constant(value=4))], + value=Constant(value=4, kind=None))], type_ignores=[]) @@ -1368,7 +1389,7 @@ Function and class definitions .. doctest:: - >>> print(ast.dump(ast.parse('yield x'), indent=4)) + >>> print(ast.dump(ast.parse('yield x'), indent=4, omit_defaults=False)) Module( body=[ Expr( @@ -1376,7 +1397,7 @@ Function and class definitions value=Name(id='x', ctx=Load())))], type_ignores=[]) - >>> print(ast.dump(ast.parse('yield from x'), indent=4)) + >>> print(ast.dump(ast.parse('yield from x'), indent=4, omit_defaults=False)) Module( body=[ Expr( @@ -1392,7 +1413,7 @@ Function and class definitions .. doctest:: - >>> print(ast.dump(ast.parse('global x,y,z'), indent=4)) + >>> print(ast.dump(ast.parse('global x,y,z'), indent=4, omit_defaults=False)) Module( body=[ Global( @@ -1402,7 +1423,7 @@ Function and class definitions 'z'])], type_ignores=[]) - >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4)) + >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4, omit_defaults=False)) Module( body=[ Nonlocal( @@ -1436,7 +1457,7 @@ Function and class definitions ... @decorator2 ... class Foo(base1, base2, metaclass=meta): ... pass - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ ClassDef( @@ -1474,7 +1495,7 @@ Async and await >>> print(ast.dump(ast.parse("""\ ... async def f(): ... await other_func() - ... """), indent=4)) + ... """), indent=4, omit_defaults=False)) Module( body=[ AsyncFunctionDef( @@ -1482,8 +1503,10 @@ Async and await args=arguments( posonlyargs=[], args=[], + vararg=None, kwonlyargs=[], kw_defaults=[], + kwarg=None, defaults=[]), body=[ Expr( @@ -1492,7 +1515,9 @@ Async and await func=Name(id='other_func', ctx=Load()), args=[], keywords=[])))], - decorator_list=[])], + decorator_list=[], + returns=None, + type_comment=None)], type_ignores=[]) @@ -1702,7 +1727,7 @@ and classes for traversing abstract syntax trees: def visit_Name(self, node): return Subscript( value=Name(id='data', ctx=Load()), - slice=Constant(value=node.id), + slice=Constant(value=node.id, kind=None), ctx=node.ctx ) @@ -1727,7 +1752,7 @@ and classes for traversing abstract syntax trees: node = YourTransformer().visit(node) -.. function:: dump(node, annotate_fields=True, include_attributes=False, *, indent=None) +.. function:: dump(node, annotate_fields=True, include_attributes=False, *, indent=None, omit_defaults=True) Return a formatted dump of the tree in *node*. This is mainly useful for debugging purposes. If *annotate_fields* is true (by default), @@ -1735,7 +1760,8 @@ and classes for traversing abstract syntax trees: If *annotate_fields* is false, the result string will be more compact by omitting unambiguous field names. Attributes such as line numbers and column offsets are not dumped by default. If this is wanted, - *include_attributes* can be set to true. + *include_attributes* can be set to true. In case of *omit_defaults* is true, + any field that has its default value will be omitted from the output. If *indent* is a non-negative integer or string, then the tree will be pretty-printed with that indent level. An indent level @@ -1747,6 +1773,9 @@ and classes for traversing abstract syntax trees: .. versionchanged:: 3.9 Added the *indent* option. + .. versionchanged:: 3.9 + Added the *omit_defaults* option. + .. _ast-cli: diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 6a6d1ee38c7b60..cbb6c5905782ed 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -159,6 +159,10 @@ Added the *indent* option to :func:`~ast.dump` which allows it to produce a multiline indented output. (Contributed by Serhiy Storchaka in :issue:`37995`.) +Added the *omit_defaults* option to :func:`~ast.dump` which allows to +produce a representation without printing default values. +(Contributed by Serhiy Storchaka and Batuhan Taskaya in :issue:`36287`) + Added :func:`ast.unparse` as a function in the :mod:`ast` module that can be used to unparse an :class:`ast.AST` object and produce a string with code that would produce an equivalent :class:`ast.AST` object when parsed. @@ -167,6 +171,9 @@ that would produce an equivalent :class:`ast.AST` object when parsed. Added docstrings to AST nodes that contains the ASDL signature used to construct that node. (Contributed by Batuhan Taskaya in :issue:`39638`.) +Added default values to AST node classes. +(Contributed by Batuhan Taskaya in :issue:`39981`) + asyncio ------- diff --git a/Lib/ast.py b/Lib/ast.py index e347d8b9dab1d4..e0b4bb9f54bb70 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -28,6 +28,7 @@ from _ast import * from contextlib import contextmanager, nullcontext from enum import IntEnum, auto +from functools import lru_cache def parse(source, filename='', mode='exec', *, @@ -102,7 +103,7 @@ def _convert(node): return _convert(node_or_string) -def dump(node, annotate_fields=True, include_attributes=False, *, indent=None): +def dump(node, annotate_fields=True, include_attributes=False, *, indent=None, omit_defaults=True): """ Return a formatted dump of the tree in node. This is mainly useful for debugging purposes. If annotate_fields is true (by default), @@ -112,7 +113,9 @@ def dump(node, annotate_fields=True, include_attributes=False, *, indent=None): numbers and column offsets are not dumped by default. If this is wanted, include_attributes can be set to true. If indent is a non-negative integer or string, then the tree will be pretty-printed with that indent - level. None (the default) selects the single line representation. + level. None (the default) selects the single line representation. If + omit_defaults is true, fields that have their default values will be + omitted. """ def _format(node, level=0): if indent is not None: @@ -127,13 +130,18 @@ def _format(node, level=0): args = [] allsimple = True keywords = annotate_fields + field_defaults = cls._field_defaults for name in node._fields: try: value = getattr(node, name) except AttributeError: keywords = True continue - if value is None and getattr(cls, name, ...) is None: + if ( + omit_defaults + and name in field_defaults + and field_defaults[name] == value + ): keywords = True continue value, simple = _format(value, level) @@ -148,7 +156,11 @@ def _format(node, level=0): value = getattr(node, name) except AttributeError: continue - if value is None and getattr(cls, name, ...) is None: + if ( + omit_defaults + and value is None + and getattr(cls, name, ...) is None + ): continue value, simple = _format(value, level) allsimple = allsimple and simple diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 66f83841ce3417..fa9b6745319285 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -352,23 +352,42 @@ def test_field_attr_existence(self): self.assertEqual(type(x._fields), tuple) def test_arguments(self): - x = ast.arguments() - self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs', - 'kw_defaults', 'kwarg', 'defaults')) + x = ast.FunctionDef() + self.assertEqual(x._fields, ('name', 'args', 'body', 'decorator_list', 'returns', 'type_comment')) + self.assertEqual(x._field_defaults, {'body': [], 'decorator_list': [], 'returns': None, 'type_comment': None}) with self.assertRaises(AttributeError): - x.args - self.assertIsNone(x.vararg) + x.name - x = ast.arguments(*range(1, 8)) + self.assertIsNone(x.returns) + self.assertEqual(x.body, []) + + x = ast.FunctionDef(*range(1, 4)) self.assertEqual(x.args, 2) - self.assertEqual(x.vararg, 3) + self.assertEqual(x.body, 3) + self.assertEqual(x.decorator_list, []) + self.assertIsNone(x.returns) + self.assertIsNone(x.type_comment) + + x = ast.Module(body=1) + self.assertEqual(x.body, 1) + self.assertEqual(x.type_ignores, []) + + x = ast.Module(body=1, type_ignores=2) + self.assertEqual(x.body, 1) + self.assertEqual(x.type_ignores, 2) + + x = ast.Module(type_ignores=2) + self.assertEqual(x.body, []) + self.assertEqual(x.type_ignores, 2) def test_field_attr_writable(self): x = ast.Num() # We can assign to _fields x._fields = 666 + x._field_defaults = 999 self.assertEqual(x._fields, 666) + self.assertEqual(x._field_defaults, 999) def test_classattrs(self): x = ast.Num() @@ -666,21 +685,21 @@ def test_dump(self): 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')], " - "keywords=[]))], type_ignores=[])" + "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')" + "]))])" ) self.assertEqual(ast.dump(node, annotate_fields=False), "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), " - "Constant('and cheese')], []))], [])" + "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', " - "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], " + "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], " "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=[])" + "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)])" ) def test_dump_indent(self): @@ -693,9 +712,7 @@ def test_dump_indent(self): func=Name(id='spam', ctx=Load()), args=[ Name(id='eggs', ctx=Load()), - Constant(value='and cheese')], - keywords=[]))], - type_ignores=[])""") + Constant(value='and cheese')]))])""") self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\ Module( \t[ @@ -704,9 +721,7 @@ def test_dump_indent(self): \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[])""") +\t\t\t\t\tConstant('and cheese')]))])""") self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\ Module( body=[ @@ -733,7 +748,6 @@ def test_dump_indent(self): col_offset=11, end_lineno=1, end_col_offset=23)], - keywords=[], lineno=1, col_offset=0, end_lineno=1, @@ -741,8 +755,7 @@ def test_dump_indent(self): lineno=1, col_offset=0, end_lineno=1, - end_col_offset=24)], - type_ignores=[])""") + end_col_offset=24)])""") def test_dump_incomplete(self): node = ast.Raise(lineno=3, col_offset=4) @@ -791,16 +804,13 @@ def test_fix_missing_locations(self): self.maxDiff = None 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', 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(), " - "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), " - "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, " - "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, " - "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], " - "type_ignores=[])" + "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), args=[" + "Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, end_col_offset=12)], " + "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(), " + "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), args=[Constant(value='eggs', " + "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], lineno=1, col_offset=0, " + "end_lineno=1, end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)])" ) def test_increment_lineno(self): diff --git a/Misc/NEWS.d/next/Library/2020-03-16-22-18-30.bpo-39981.5TKqVR.rst b/Misc/NEWS.d/next/Library/2020-03-16-22-18-30.bpo-39981.5TKqVR.rst new file mode 100644 index 00000000000000..49e8fd3c4d44f0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-16-22-18-30.bpo-39981.5TKqVR.rst @@ -0,0 +1 @@ +Add default values for :mod:`ast` node classes. Patch by Batuhan Taskaya. diff --git a/Parser/asdl.py b/Parser/asdl.py index 5416377100c64a..0962a15b6ce0b5 100644 --- a/Parser/asdl.py +++ b/Parser/asdl.py @@ -71,16 +71,15 @@ def __init__(self, type, name=None, seq=False, opt=False): self.name = name self.seq = seq self.opt = opt - - def __str__(self): - if self.seq: - extra = "*" - elif self.opt: - extra = "?" + if seq: + self.extra = "*" + elif opt: + self.extra = "?" else: - extra = "" + self.extra = "" - return "{}{} {}".format(self.type, extra, self.name) + def __str__(self): + return "{}{} {}".format(self.type, self.extra, self.name) def __repr__(self): if self.seq: diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 478f0e8925b9af..3bb958fe7ab8b1 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -614,6 +614,9 @@ def visitProduct(self, prod, name): for f in prod.fields: self.emit('"%s",' % f.name, 1) self.emit("};", 0) + self.emit("static const char %s_field_defaults[]={" % name, 0) + self.emit_field_defaults(prod.fields) + self.emit("};", 0) def visitSum(self, sum, name): self.emit_type("%s_type" % name) @@ -641,6 +644,17 @@ def visitConstructor(self, cons, name): for t in cons.fields: self.emit('"%s",' % t.name, 1) self.emit("};",0) + self.emit("static const char %s_field_defaults[]={" % cons.name, 0) + self.emit_field_defaults(cons.fields) + self.emit("};",0) + + def emit_field_defaults(self, fields): + for field in fields: + if field.extra: + self.emit("%r," % field.extra, 1) + else: + self.emit("' ',", 1) + class PyTypesVisitor(PickleVisitor): @@ -684,8 +698,11 @@ def visitModule(self, mod): { Py_ssize_t i, numfields = 0; int res = -1; - PyObject *key, *value, *fields; - if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), astmodulestate_global->_fields, &fields) < 0) { + PyObject *key, *value, *fields, *field_defaults; + if (_PyObject_LookupAttr(self, astmodulestate_global->_fields, &fields) < 0) { + goto cleanup; + } + if (_PyObject_LookupAttr(self, astmodulestate_global->_field_defaults, &field_defaults) < 0) { goto cleanup; } if (fields) { @@ -723,8 +740,32 @@ def visitModule(self, mod): goto cleanup; } } + PyObject *field, *field_default; + for (i = 0; i < numfields; i++) { + field = PySequence_GetItem(fields, i); + if (!field) { + res = -1; + goto cleanup; + } + int attr_present = PyObject_HasAttr(self, field); + field_default = PyDict_GetItem(field_defaults, field); + Py_DECREF(field); + if (!attr_present && field_default) { + if (PyList_Check(field_default)) { + field_default = PyList_New(0); + } else { + Py_INCREF(field_default); + } + res = PyObject_SetAttr(self, field, field_default); + Py_DECREF(field_default); + if (res < 0) { + goto cleanup; + } + } + } cleanup: Py_XDECREF(fields); + Py_XDECREF(field_defaults); return res; } @@ -782,27 +823,59 @@ def visitModule(self, mod): }; static PyObject * -make_type(const char *type, PyObject* base, const char* const* fields, int num_fields, const char *doc) +make_type( + const char *type, + PyObject* base, + const char* const* fields, + const char* field_defaults, + Py_ssize_t num_fields, + const char *doc +) { - PyObject *fnames, *result; - int i; + Py_ssize_t i; + PyObject *fnames, *fdefaults = NULL; + PyObject *result = NULL; + fnames = PyTuple_New(num_fields); - if (!fnames) return NULL; + if (!fnames) { + goto exit; + } + fdefaults = PyDict_New(); + if (!fdefaults) { + goto exit; + } + PyObject *field, *field_default; for (i = 0; i < num_fields; i++) { - PyObject *field = PyUnicode_InternFromString(fields[i]); + field = PyUnicode_InternFromString(fields[i]); if (!field) { - Py_DECREF(fnames); - return NULL; + goto exit; } PyTuple_SET_ITEM(fnames, i, field); + if (field_defaults[i] == '?') { + field_default = Py_None; + Py_INCREF(field_default); + } else if (field_defaults[i] == '*') { + field_default = PyList_New(0); + if (!field_default) { + goto exit; + } + } else { + continue; + } + PyDict_SetItem(fdefaults, field, field_default); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOs}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOOOs}", type, base, astmodulestate_global->_fields, fnames, + astmodulestate_global->_field_defaults, + fdefaults, astmodulestate_global->__module__, astmodulestate_global->_ast, astmodulestate_global->__doc__, doc); - Py_DECREF(fnames); + goto exit; + exit: + Py_XDECREF(fnames); + Py_XDECREF(fdefaults); return result; } @@ -931,7 +1004,8 @@ def visitModule(self, mod): empty_tuple = PyTuple_New(0); if (!empty_tuple || PyObject_SetAttrString(astmodulestate_global->AST_type, "_fields", empty_tuple) < 0 || - PyObject_SetAttrString(astmodulestate_global->AST_type, "_attributes", empty_tuple) < 0) { + PyObject_SetAttrString(astmodulestate_global->AST_type, "_attributes", empty_tuple) < 0 || + PyObject_SetAttrString(astmodulestate_global->AST_type, "_field_defaults", empty_tuple) < 0) { Py_XDECREF(empty_tuple); return -1; } @@ -964,10 +1038,11 @@ def visitModule(self, mod): def visitProduct(self, prod, name): if prod.fields: fields = name+"_fields" + field_defaults = name+"_field_defaults" else: - fields = "NULL" - self.emit('state->%s_type = make_type("%s", state->AST_type, %s, %d,' % - (name, name, fields, len(prod.fields)), 1) + fields = field_defaults = "NULL" + self.emit('state->%s_type = make_type("%s", state->AST_type, %s, %s, %d,' % + (name, name, fields, field_defaults, len(prod.fields)), 1) self.emit('%s);' % reflow_c_string(asdl_of(name, prod), 2), 2, reflow=False) self.emit("if (!state->%s_type) return 0;" % name, 1) self.emit_type("AST_type") @@ -981,7 +1056,7 @@ def visitProduct(self, prod, name): self.emit_defaults(name, prod.attributes, 1) def visitSum(self, sum, name): - self.emit('state->%s_type = make_type("%s", state->AST_type, NULL, 0,' % + self.emit('state->%s_type = make_type("%s", state->AST_type, NULL, NULL, 0,' % (name, name), 1) self.emit('%s);' % reflow_c_string(asdl_of(name, sum), 2), 2, reflow=False) self.emit_type("%s_type" % name) @@ -999,10 +1074,11 @@ def visitSum(self, sum, name): def visitConstructor(self, cons, name, simple): if cons.fields: fields = cons.name+"_fields" + field_defaults = cons.name+"_field_defaults" else: - fields = "NULL" - self.emit('state->%s_type = make_type("%s", state->%s_type, %s, %d,' % - (cons.name, cons.name, name, fields, len(cons.fields)), 1) + fields = field_defaults = "NULL" + self.emit('state->%s_type = make_type("%s", state->%s_type, %s, %s, %d,' % + (cons.name, cons.name, name, fields, field_defaults, len(cons.fields)), 1) self.emit('%s);' % reflow_c_string(asdl_of(cons.name, cons), 2), 2, reflow=False) self.emit("if (!state->%s_type) return 0;" % cons.name, 1) self.emit_type("%s_type" % cons.name) @@ -1304,6 +1380,7 @@ def generate_module_def(f, mod): state_strings = { "_ast", "_fields", + "_field_defaults", "__doc__", "__dict__", "__module__", diff --git a/Python/Python-ast.c b/Python/Python-ast.c index aba83fb6033d3d..34cd3b457dfc54 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -136,6 +136,7 @@ typedef struct { PyObject *__module__; PyObject *_ast; PyObject *_attributes; + PyObject *_field_defaults; PyObject *_fields; PyObject *alias_type; PyObject *annotation; @@ -356,6 +357,7 @@ static int astmodule_clear(PyObject *module) Py_CLEAR(astmodulestate(module)->__module__); Py_CLEAR(astmodulestate(module)->_ast); Py_CLEAR(astmodulestate(module)->_attributes); + Py_CLEAR(astmodulestate(module)->_field_defaults); Py_CLEAR(astmodulestate(module)->_fields); Py_CLEAR(astmodulestate(module)->alias_type); Py_CLEAR(astmodulestate(module)->annotation); @@ -575,6 +577,7 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg) Py_VISIT(astmodulestate(module)->__module__); Py_VISIT(astmodulestate(module)->_ast); Py_VISIT(astmodulestate(module)->_attributes); + Py_VISIT(astmodulestate(module)->_field_defaults); Py_VISIT(astmodulestate(module)->_fields); Py_VISIT(astmodulestate(module)->alias_type); Py_VISIT(astmodulestate(module)->annotation); @@ -690,6 +693,7 @@ static int init_identifiers(void) if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0; if ((state->_ast = PyUnicode_InternFromString("_ast")) == NULL) return 0; if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0; + if ((state->_field_defaults = PyUnicode_InternFromString("_field_defaults")) == NULL) return 0; if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0; if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0; if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return 0; @@ -767,16 +771,30 @@ static const char * const Module_fields[]={ "body", "type_ignores", }; +static const char Module_field_defaults[]={ + '*', + '*', +}; static const char * const Interactive_fields[]={ "body", }; +static const char Interactive_field_defaults[]={ + '*', +}; static const char * const Expression_fields[]={ "body", }; +static const char Expression_field_defaults[]={ + ' ', +}; static const char * const FunctionType_fields[]={ "argtypes", "returns", }; +static const char FunctionType_field_defaults[]={ + '*', + ' ', +}; static const char * const stmt_attributes[] = { "lineno", "col_offset", @@ -792,6 +810,14 @@ static const char * const FunctionDef_fields[]={ "returns", "type_comment", }; +static const char FunctionDef_field_defaults[]={ + ' ', + ' ', + '*', + '*', + '?', + '?', +}; static const char * const AsyncFunctionDef_fields[]={ "name", "args", @@ -800,6 +826,14 @@ static const char * const AsyncFunctionDef_fields[]={ "returns", "type_comment", }; +static const char AsyncFunctionDef_field_defaults[]={ + ' ', + ' ', + '*', + '*', + '?', + '?', +}; static const char * const ClassDef_fields[]={ "name", "bases", @@ -807,28 +841,57 @@ static const char * const ClassDef_fields[]={ "body", "decorator_list", }; +static const char ClassDef_field_defaults[]={ + ' ', + '*', + '*', + '*', + '*', +}; static const char * const Return_fields[]={ "value", }; +static const char Return_field_defaults[]={ + '?', +}; static const char * const Delete_fields[]={ "targets", }; +static const char Delete_field_defaults[]={ + '*', +}; static const char * const Assign_fields[]={ "targets", "value", "type_comment", }; +static const char Assign_field_defaults[]={ + '*', + ' ', + '?', +}; static const char * const AugAssign_fields[]={ "target", "op", "value", }; +static const char AugAssign_field_defaults[]={ + ' ', + ' ', + ' ', +}; static const char * const AnnAssign_fields[]={ "target", "annotation", "value", "simple", }; +static const char AnnAssign_field_defaults[]={ + ' ', + ' ', + '?', + ' ', +}; static const char * const For_fields[]={ "target", "iter", @@ -836,6 +899,13 @@ static const char * const For_fields[]={ "orelse", "type_comment", }; +static const char For_field_defaults[]={ + ' ', + ' ', + '*', + '*', + '?', +}; static const char * const AsyncFor_fields[]={ "target", "iter", @@ -843,57 +913,115 @@ static const char * const AsyncFor_fields[]={ "orelse", "type_comment", }; +static const char AsyncFor_field_defaults[]={ + ' ', + ' ', + '*', + '*', + '?', +}; static const char * const While_fields[]={ "test", "body", "orelse", }; +static const char While_field_defaults[]={ + ' ', + '*', + '*', +}; static const char * const If_fields[]={ "test", "body", "orelse", }; +static const char If_field_defaults[]={ + ' ', + '*', + '*', +}; static const char * const With_fields[]={ "items", "body", "type_comment", }; +static const char With_field_defaults[]={ + '*', + '*', + '?', +}; static const char * const AsyncWith_fields[]={ "items", "body", "type_comment", }; +static const char AsyncWith_field_defaults[]={ + '*', + '*', + '?', +}; static const char * const Raise_fields[]={ "exc", "cause", }; +static const char Raise_field_defaults[]={ + '?', + '?', +}; static const char * const Try_fields[]={ "body", "handlers", "orelse", "finalbody", }; +static const char Try_field_defaults[]={ + '*', + '*', + '*', + '*', +}; static const char * const Assert_fields[]={ "test", "msg", }; +static const char Assert_field_defaults[]={ + ' ', + '?', +}; static const char * const Import_fields[]={ "names", }; +static const char Import_field_defaults[]={ + '*', +}; static const char * const ImportFrom_fields[]={ "module", "names", "level", }; +static const char ImportFrom_field_defaults[]={ + '?', + '*', + '?', +}; static const char * const Global_fields[]={ "names", }; +static const char Global_field_defaults[]={ + '*', +}; static const char * const Nonlocal_fields[]={ "names", }; +static const char Nonlocal_field_defaults[]={ + '*', +}; static const char * const Expr_fields[]={ "value", }; +static const char Expr_field_defaults[]={ + ' ', +}; static const char * const expr_attributes[] = { "lineno", "col_offset", @@ -905,114 +1033,226 @@ static const char * const BoolOp_fields[]={ "op", "values", }; +static const char BoolOp_field_defaults[]={ + ' ', + '*', +}; static const char * const NamedExpr_fields[]={ "target", "value", }; +static const char NamedExpr_field_defaults[]={ + ' ', + ' ', +}; static const char * const BinOp_fields[]={ "left", "op", "right", }; +static const char BinOp_field_defaults[]={ + ' ', + ' ', + ' ', +}; static const char * const UnaryOp_fields[]={ "op", "operand", }; +static const char UnaryOp_field_defaults[]={ + ' ', + ' ', +}; static const char * const Lambda_fields[]={ "args", "body", }; +static const char Lambda_field_defaults[]={ + ' ', + ' ', +}; static const char * const IfExp_fields[]={ "test", "body", "orelse", }; +static const char IfExp_field_defaults[]={ + ' ', + ' ', + ' ', +}; static const char * const Dict_fields[]={ "keys", "values", }; +static const char Dict_field_defaults[]={ + '*', + '*', +}; static const char * const Set_fields[]={ "elts", }; +static const char Set_field_defaults[]={ + '*', +}; static const char * const ListComp_fields[]={ "elt", "generators", }; +static const char ListComp_field_defaults[]={ + ' ', + '*', +}; static const char * const SetComp_fields[]={ "elt", "generators", }; +static const char SetComp_field_defaults[]={ + ' ', + '*', +}; static const char * const DictComp_fields[]={ "key", "value", "generators", }; +static const char DictComp_field_defaults[]={ + ' ', + ' ', + '*', +}; static const char * const GeneratorExp_fields[]={ "elt", "generators", }; +static const char GeneratorExp_field_defaults[]={ + ' ', + '*', +}; static const char * const Await_fields[]={ "value", }; +static const char Await_field_defaults[]={ + ' ', +}; static const char * const Yield_fields[]={ "value", }; +static const char Yield_field_defaults[]={ + '?', +}; static const char * const YieldFrom_fields[]={ "value", }; +static const char YieldFrom_field_defaults[]={ + ' ', +}; static const char * const Compare_fields[]={ "left", "ops", "comparators", }; +static const char Compare_field_defaults[]={ + ' ', + '*', + '*', +}; static const char * const Call_fields[]={ "func", "args", "keywords", }; +static const char Call_field_defaults[]={ + ' ', + '*', + '*', +}; static const char * const FormattedValue_fields[]={ "value", "conversion", "format_spec", }; +static const char FormattedValue_field_defaults[]={ + ' ', + '?', + '?', +}; static const char * const JoinedStr_fields[]={ "values", }; +static const char JoinedStr_field_defaults[]={ + '*', +}; static const char * const Constant_fields[]={ "value", "kind", }; +static const char Constant_field_defaults[]={ + ' ', + '?', +}; static const char * const Attribute_fields[]={ "value", "attr", "ctx", }; +static const char Attribute_field_defaults[]={ + ' ', + ' ', + ' ', +}; static const char * const Subscript_fields[]={ "value", "slice", "ctx", }; +static const char Subscript_field_defaults[]={ + ' ', + ' ', + ' ', +}; static const char * const Starred_fields[]={ "value", "ctx", }; +static const char Starred_field_defaults[]={ + ' ', + ' ', +}; static const char * const Name_fields[]={ "id", "ctx", }; +static const char Name_field_defaults[]={ + ' ', + ' ', +}; static const char * const List_fields[]={ "elts", "ctx", }; +static const char List_field_defaults[]={ + '*', + ' ', +}; static const char * const Tuple_fields[]={ "elts", "ctx", }; +static const char Tuple_field_defaults[]={ + '*', + ' ', +}; static const char * const Slice_fields[]={ "lower", "upper", "step", }; +static const char Slice_field_defaults[]={ + '?', + '?', + '?', +}; static PyObject* ast2obj_expr_context(expr_context_ty); static PyObject* ast2obj_boolop(boolop_ty); static PyObject* ast2obj_operator(operator_ty); @@ -1025,6 +1265,12 @@ static const char * const comprehension_fields[]={ "ifs", "is_async", }; +static const char comprehension_field_defaults[]={ + ' ', + ' ', + '*', + ' ', +}; static const char * const excepthandler_attributes[] = { "lineno", "col_offset", @@ -1037,6 +1283,11 @@ static const char * const ExceptHandler_fields[]={ "name", "body", }; +static const char ExceptHandler_field_defaults[]={ + '?', + '?', + '*', +}; static PyObject* ast2obj_arguments(void*); static const char * const arguments_fields[]={ "posonlyargs", @@ -1047,6 +1298,15 @@ static const char * const arguments_fields[]={ "kwarg", "defaults", }; +static const char arguments_field_defaults[]={ + '*', + '*', + '?', + '*', + '*', + '?', + '*', +}; static PyObject* ast2obj_arg(void*); static const char * const arg_attributes[] = { "lineno", @@ -1059,26 +1319,47 @@ static const char * const arg_fields[]={ "annotation", "type_comment", }; +static const char arg_field_defaults[]={ + ' ', + '?', + '?', +}; static PyObject* ast2obj_keyword(void*); static const char * const keyword_fields[]={ "arg", "value", }; +static const char keyword_field_defaults[]={ + '?', + ' ', +}; static PyObject* ast2obj_alias(void*); static const char * const alias_fields[]={ "name", "asname", }; +static const char alias_field_defaults[]={ + ' ', + '?', +}; static PyObject* ast2obj_withitem(void*); static const char * const withitem_fields[]={ "context_expr", "optional_vars", }; +static const char withitem_field_defaults[]={ + ' ', + '?', +}; static PyObject* ast2obj_type_ignore(void*); static const char * const TypeIgnore_fields[]={ "lineno", "tag", }; +static const char TypeIgnore_field_defaults[]={ + ' ', + ' ', +}; @@ -1119,8 +1400,11 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw) { Py_ssize_t i, numfields = 0; int res = -1; - PyObject *key, *value, *fields; - if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), astmodulestate_global->_fields, &fields) < 0) { + PyObject *key, *value, *fields, *field_defaults; + if (_PyObject_LookupAttr(self, astmodulestate_global->_fields, &fields) < 0) { + goto cleanup; + } + if (_PyObject_LookupAttr(self, astmodulestate_global->_field_defaults, &field_defaults) < 0) { goto cleanup; } if (fields) { @@ -1158,8 +1442,32 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw) goto cleanup; } } + PyObject *field, *field_default; + for (i = 0; i < numfields; i++) { + field = PySequence_GetItem(fields, i); + if (!field) { + res = -1; + goto cleanup; + } + int attr_present = PyObject_HasAttr(self, field); + field_default = PyDict_GetItem(field_defaults, field); + Py_DECREF(field); + if (!attr_present && field_default) { + if (PyList_Check(field_default)) { + field_default = PyList_New(0); + } else { + Py_INCREF(field_default); + } + res = PyObject_SetAttr(self, field, field_default); + Py_DECREF(field_default); + if (res < 0) { + goto cleanup; + } + } + } cleanup: Py_XDECREF(fields); + Py_XDECREF(field_defaults); return res; } @@ -1217,27 +1525,59 @@ static PyType_Spec AST_type_spec = { }; static PyObject * -make_type(const char *type, PyObject* base, const char* const* fields, int num_fields, const char *doc) +make_type( + const char *type, + PyObject* base, + const char* const* fields, + const char* field_defaults, + Py_ssize_t num_fields, + const char *doc +) { - PyObject *fnames, *result; - int i; + Py_ssize_t i; + PyObject *fnames, *fdefaults = NULL; + PyObject *result = NULL; + fnames = PyTuple_New(num_fields); - if (!fnames) return NULL; + if (!fnames) { + goto exit; + } + fdefaults = PyDict_New(); + if (!fdefaults) { + goto exit; + } + PyObject *field, *field_default; for (i = 0; i < num_fields; i++) { - PyObject *field = PyUnicode_InternFromString(fields[i]); + field = PyUnicode_InternFromString(fields[i]); if (!field) { - Py_DECREF(fnames); - return NULL; + goto exit; } PyTuple_SET_ITEM(fnames, i, field); + if (field_defaults[i] == '?') { + field_default = Py_None; + Py_INCREF(field_default); + } else if (field_defaults[i] == '*') { + field_default = PyList_New(0); + if (!field_default) { + goto exit; + } + } else { + continue; + } + PyDict_SetItem(fdefaults, field, field_default); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOs}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOOOs}", type, base, astmodulestate_global->_fields, fnames, + astmodulestate_global->_field_defaults, + fdefaults, astmodulestate_global->__module__, astmodulestate_global->_ast, astmodulestate_global->__doc__, doc); - Py_DECREF(fnames); + goto exit; + exit: + Py_XDECREF(fnames); + Py_XDECREF(fdefaults); return result; } @@ -1366,7 +1706,8 @@ static int add_ast_fields(void) empty_tuple = PyTuple_New(0); if (!empty_tuple || PyObject_SetAttrString(astmodulestate_global->AST_type, "_fields", empty_tuple) < 0 || - PyObject_SetAttrString(astmodulestate_global->AST_type, "_attributes", empty_tuple) < 0) { + PyObject_SetAttrString(astmodulestate_global->AST_type, "_attributes", empty_tuple) < 0 || + PyObject_SetAttrString(astmodulestate_global->AST_type, "_field_defaults", empty_tuple) < 0) { Py_XDECREF(empty_tuple); return -1; } @@ -1389,29 +1730,33 @@ static int init_types(void) state->AST_type = PyType_FromSpec(&AST_type_spec); if (!state->AST_type) return 0; if (add_ast_fields() < 0) return 0; - state->mod_type = make_type("mod", state->AST_type, NULL, 0, + state->mod_type = make_type("mod", state->AST_type, NULL, NULL, 0, "mod = Module(stmt* body, type_ignore* type_ignores)\n" " | Interactive(stmt* body)\n" " | Expression(expr body)\n" " | FunctionType(expr* argtypes, expr returns)"); if (!state->mod_type) return 0; if (!add_attributes(state->mod_type, NULL, 0)) return 0; - state->Module_type = make_type("Module", state->mod_type, Module_fields, 2, + state->Module_type = make_type("Module", state->mod_type, Module_fields, + Module_field_defaults, 2, "Module(stmt* body, type_ignore* type_ignores)"); if (!state->Module_type) return 0; state->Interactive_type = make_type("Interactive", state->mod_type, - Interactive_fields, 1, + Interactive_fields, + Interactive_field_defaults, 1, "Interactive(stmt* body)"); if (!state->Interactive_type) return 0; state->Expression_type = make_type("Expression", state->mod_type, - Expression_fields, 1, + Expression_fields, + Expression_field_defaults, 1, "Expression(expr body)"); if (!state->Expression_type) return 0; state->FunctionType_type = make_type("FunctionType", state->mod_type, - FunctionType_fields, 2, + FunctionType_fields, + FunctionType_field_defaults, 2, "FunctionType(expr* argtypes, expr returns)"); if (!state->FunctionType_type) return 0; - state->stmt_type = make_type("stmt", state->AST_type, NULL, 0, + state->stmt_type = make_type("stmt", state->AST_type, NULL, NULL, 0, "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n" " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n" " | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n" @@ -1445,7 +1790,8 @@ static int init_types(void) -1) return 0; state->FunctionDef_type = make_type("FunctionDef", state->stmt_type, - FunctionDef_fields, 6, + FunctionDef_fields, + FunctionDef_field_defaults, 6, "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)"); if (!state->FunctionDef_type) return 0; if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) == @@ -1456,7 +1802,8 @@ static int init_types(void) return 0; state->AsyncFunctionDef_type = make_type("AsyncFunctionDef", state->stmt_type, - AsyncFunctionDef_fields, 6, + AsyncFunctionDef_fields, + AsyncFunctionDef_field_defaults, 6, "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)"); if (!state->AsyncFunctionDef_type) return 0; if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None) @@ -1466,109 +1813,130 @@ static int init_types(void) Py_None) == -1) return 0; state->ClassDef_type = make_type("ClassDef", state->stmt_type, - ClassDef_fields, 5, + ClassDef_fields, ClassDef_field_defaults, + 5, "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)"); if (!state->ClassDef_type) return 0; - state->Return_type = make_type("Return", state->stmt_type, Return_fields, 1, + state->Return_type = make_type("Return", state->stmt_type, Return_fields, + Return_field_defaults, 1, "Return(expr? value)"); if (!state->Return_type) return 0; if (PyObject_SetAttr(state->Return_type, state->value, Py_None) == -1) return 0; - state->Delete_type = make_type("Delete", state->stmt_type, Delete_fields, 1, + state->Delete_type = make_type("Delete", state->stmt_type, Delete_fields, + Delete_field_defaults, 1, "Delete(expr* targets)"); if (!state->Delete_type) return 0; - state->Assign_type = make_type("Assign", state->stmt_type, Assign_fields, 3, + state->Assign_type = make_type("Assign", state->stmt_type, Assign_fields, + Assign_field_defaults, 3, "Assign(expr* targets, expr value, string? type_comment)"); if (!state->Assign_type) return 0; if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) == -1) return 0; state->AugAssign_type = make_type("AugAssign", state->stmt_type, - AugAssign_fields, 3, + AugAssign_fields, + AugAssign_field_defaults, 3, "AugAssign(expr target, operator op, expr value)"); if (!state->AugAssign_type) return 0; state->AnnAssign_type = make_type("AnnAssign", state->stmt_type, - AnnAssign_fields, 4, + AnnAssign_fields, + AnnAssign_field_defaults, 4, "AnnAssign(expr target, expr annotation, expr? value, int simple)"); if (!state->AnnAssign_type) return 0; if (PyObject_SetAttr(state->AnnAssign_type, state->value, Py_None) == -1) return 0; - state->For_type = make_type("For", state->stmt_type, For_fields, 5, + state->For_type = make_type("For", state->stmt_type, For_fields, + For_field_defaults, 5, "For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)"); if (!state->For_type) return 0; if (PyObject_SetAttr(state->For_type, state->type_comment, Py_None) == -1) return 0; state->AsyncFor_type = make_type("AsyncFor", state->stmt_type, - AsyncFor_fields, 5, + AsyncFor_fields, AsyncFor_field_defaults, + 5, "AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)"); if (!state->AsyncFor_type) return 0; if (PyObject_SetAttr(state->AsyncFor_type, state->type_comment, Py_None) == -1) return 0; - state->While_type = make_type("While", state->stmt_type, While_fields, 3, + state->While_type = make_type("While", state->stmt_type, While_fields, + While_field_defaults, 3, "While(expr test, stmt* body, stmt* orelse)"); if (!state->While_type) return 0; - state->If_type = make_type("If", state->stmt_type, If_fields, 3, + state->If_type = make_type("If", state->stmt_type, If_fields, + If_field_defaults, 3, "If(expr test, stmt* body, stmt* orelse)"); if (!state->If_type) return 0; - state->With_type = make_type("With", state->stmt_type, With_fields, 3, + state->With_type = make_type("With", state->stmt_type, With_fields, + With_field_defaults, 3, "With(withitem* items, stmt* body, string? type_comment)"); if (!state->With_type) return 0; if (PyObject_SetAttr(state->With_type, state->type_comment, Py_None) == -1) return 0; state->AsyncWith_type = make_type("AsyncWith", state->stmt_type, - AsyncWith_fields, 3, + AsyncWith_fields, + AsyncWith_field_defaults, 3, "AsyncWith(withitem* items, stmt* body, string? type_comment)"); if (!state->AsyncWith_type) return 0; if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None) == -1) return 0; - state->Raise_type = make_type("Raise", state->stmt_type, Raise_fields, 2, + state->Raise_type = make_type("Raise", state->stmt_type, Raise_fields, + Raise_field_defaults, 2, "Raise(expr? exc, expr? cause)"); if (!state->Raise_type) return 0; if (PyObject_SetAttr(state->Raise_type, state->exc, Py_None) == -1) return 0; if (PyObject_SetAttr(state->Raise_type, state->cause, Py_None) == -1) return 0; - state->Try_type = make_type("Try", state->stmt_type, Try_fields, 4, + state->Try_type = make_type("Try", state->stmt_type, Try_fields, + Try_field_defaults, 4, "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); if (!state->Try_type) return 0; - state->Assert_type = make_type("Assert", state->stmt_type, Assert_fields, 2, + state->Assert_type = make_type("Assert", state->stmt_type, Assert_fields, + Assert_field_defaults, 2, "Assert(expr test, expr? msg)"); if (!state->Assert_type) return 0; if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1) return 0; - state->Import_type = make_type("Import", state->stmt_type, Import_fields, 1, + state->Import_type = make_type("Import", state->stmt_type, Import_fields, + Import_field_defaults, 1, "Import(alias* names)"); if (!state->Import_type) return 0; state->ImportFrom_type = make_type("ImportFrom", state->stmt_type, - ImportFrom_fields, 3, + ImportFrom_fields, + ImportFrom_field_defaults, 3, "ImportFrom(identifier? module, alias* names, int? level)"); if (!state->ImportFrom_type) return 0; if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1) return 0; if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1) return 0; - state->Global_type = make_type("Global", state->stmt_type, Global_fields, 1, + state->Global_type = make_type("Global", state->stmt_type, Global_fields, + Global_field_defaults, 1, "Global(identifier* names)"); if (!state->Global_type) return 0; state->Nonlocal_type = make_type("Nonlocal", state->stmt_type, - Nonlocal_fields, 1, + Nonlocal_fields, Nonlocal_field_defaults, + 1, "Nonlocal(identifier* names)"); if (!state->Nonlocal_type) return 0; - state->Expr_type = make_type("Expr", state->stmt_type, Expr_fields, 1, + state->Expr_type = make_type("Expr", state->stmt_type, Expr_fields, + Expr_field_defaults, 1, "Expr(expr value)"); if (!state->Expr_type) return 0; - state->Pass_type = make_type("Pass", state->stmt_type, NULL, 0, + state->Pass_type = make_type("Pass", state->stmt_type, NULL, NULL, 0, "Pass"); if (!state->Pass_type) return 0; - state->Break_type = make_type("Break", state->stmt_type, NULL, 0, + state->Break_type = make_type("Break", state->stmt_type, NULL, NULL, 0, "Break"); if (!state->Break_type) return 0; - state->Continue_type = make_type("Continue", state->stmt_type, NULL, 0, + state->Continue_type = make_type("Continue", state->stmt_type, NULL, NULL, + 0, "Continue"); if (!state->Continue_type) return 0; - state->expr_type = make_type("expr", state->AST_type, NULL, 0, + state->expr_type = make_type("expr", state->AST_type, NULL, NULL, 0, "expr = BoolOp(boolop op, expr* values)\n" " | NamedExpr(expr target, expr value)\n" " | BinOp(expr left, operator op, expr right)\n" @@ -1603,69 +1971,84 @@ static int init_types(void) if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) == -1) return 0; - state->BoolOp_type = make_type("BoolOp", state->expr_type, BoolOp_fields, 2, + state->BoolOp_type = make_type("BoolOp", state->expr_type, BoolOp_fields, + BoolOp_field_defaults, 2, "BoolOp(boolop op, expr* values)"); if (!state->BoolOp_type) return 0; state->NamedExpr_type = make_type("NamedExpr", state->expr_type, - NamedExpr_fields, 2, + NamedExpr_fields, + NamedExpr_field_defaults, 2, "NamedExpr(expr target, expr value)"); if (!state->NamedExpr_type) return 0; - state->BinOp_type = make_type("BinOp", state->expr_type, BinOp_fields, 3, + state->BinOp_type = make_type("BinOp", state->expr_type, BinOp_fields, + BinOp_field_defaults, 3, "BinOp(expr left, operator op, expr right)"); if (!state->BinOp_type) return 0; state->UnaryOp_type = make_type("UnaryOp", state->expr_type, - UnaryOp_fields, 2, + UnaryOp_fields, UnaryOp_field_defaults, 2, "UnaryOp(unaryop op, expr operand)"); if (!state->UnaryOp_type) return 0; - state->Lambda_type = make_type("Lambda", state->expr_type, Lambda_fields, 2, + state->Lambda_type = make_type("Lambda", state->expr_type, Lambda_fields, + Lambda_field_defaults, 2, "Lambda(arguments args, expr body)"); if (!state->Lambda_type) return 0; - state->IfExp_type = make_type("IfExp", state->expr_type, IfExp_fields, 3, + state->IfExp_type = make_type("IfExp", state->expr_type, IfExp_fields, + IfExp_field_defaults, 3, "IfExp(expr test, expr body, expr orelse)"); if (!state->IfExp_type) return 0; - state->Dict_type = make_type("Dict", state->expr_type, Dict_fields, 2, + state->Dict_type = make_type("Dict", state->expr_type, Dict_fields, + Dict_field_defaults, 2, "Dict(expr* keys, expr* values)"); if (!state->Dict_type) return 0; - state->Set_type = make_type("Set", state->expr_type, Set_fields, 1, + state->Set_type = make_type("Set", state->expr_type, Set_fields, + Set_field_defaults, 1, "Set(expr* elts)"); if (!state->Set_type) return 0; state->ListComp_type = make_type("ListComp", state->expr_type, - ListComp_fields, 2, + ListComp_fields, ListComp_field_defaults, + 2, "ListComp(expr elt, comprehension* generators)"); if (!state->ListComp_type) return 0; state->SetComp_type = make_type("SetComp", state->expr_type, - SetComp_fields, 2, + SetComp_fields, SetComp_field_defaults, 2, "SetComp(expr elt, comprehension* generators)"); if (!state->SetComp_type) return 0; state->DictComp_type = make_type("DictComp", state->expr_type, - DictComp_fields, 3, + DictComp_fields, DictComp_field_defaults, + 3, "DictComp(expr key, expr value, comprehension* generators)"); if (!state->DictComp_type) return 0; state->GeneratorExp_type = make_type("GeneratorExp", state->expr_type, - GeneratorExp_fields, 2, + GeneratorExp_fields, + GeneratorExp_field_defaults, 2, "GeneratorExp(expr elt, comprehension* generators)"); if (!state->GeneratorExp_type) return 0; - state->Await_type = make_type("Await", state->expr_type, Await_fields, 1, + state->Await_type = make_type("Await", state->expr_type, Await_fields, + Await_field_defaults, 1, "Await(expr value)"); if (!state->Await_type) return 0; - state->Yield_type = make_type("Yield", state->expr_type, Yield_fields, 1, + state->Yield_type = make_type("Yield", state->expr_type, Yield_fields, + Yield_field_defaults, 1, "Yield(expr? value)"); if (!state->Yield_type) return 0; if (PyObject_SetAttr(state->Yield_type, state->value, Py_None) == -1) return 0; state->YieldFrom_type = make_type("YieldFrom", state->expr_type, - YieldFrom_fields, 1, + YieldFrom_fields, + YieldFrom_field_defaults, 1, "YieldFrom(expr value)"); if (!state->YieldFrom_type) return 0; state->Compare_type = make_type("Compare", state->expr_type, - Compare_fields, 3, + Compare_fields, Compare_field_defaults, 3, "Compare(expr left, cmpop* ops, expr* comparators)"); if (!state->Compare_type) return 0; - state->Call_type = make_type("Call", state->expr_type, Call_fields, 3, + state->Call_type = make_type("Call", state->expr_type, Call_fields, + Call_field_defaults, 3, "Call(expr func, expr* args, keyword* keywords)"); if (!state->Call_type) return 0; state->FormattedValue_type = make_type("FormattedValue", state->expr_type, - FormattedValue_fields, 3, + FormattedValue_fields, + FormattedValue_field_defaults, 3, "FormattedValue(expr value, int? conversion, expr? format_spec)"); if (!state->FormattedValue_type) return 0; if (PyObject_SetAttr(state->FormattedValue_type, state->conversion, @@ -1675,37 +2058,45 @@ static int init_types(void) Py_None) == -1) return 0; state->JoinedStr_type = make_type("JoinedStr", state->expr_type, - JoinedStr_fields, 1, + JoinedStr_fields, + JoinedStr_field_defaults, 1, "JoinedStr(expr* values)"); if (!state->JoinedStr_type) return 0; state->Constant_type = make_type("Constant", state->expr_type, - Constant_fields, 2, + Constant_fields, Constant_field_defaults, + 2, "Constant(constant value, string? kind)"); if (!state->Constant_type) return 0; if (PyObject_SetAttr(state->Constant_type, state->kind, Py_None) == -1) return 0; state->Attribute_type = make_type("Attribute", state->expr_type, - Attribute_fields, 3, + Attribute_fields, + Attribute_field_defaults, 3, "Attribute(expr value, identifier attr, expr_context ctx)"); if (!state->Attribute_type) return 0; state->Subscript_type = make_type("Subscript", state->expr_type, - Subscript_fields, 3, + Subscript_fields, + Subscript_field_defaults, 3, "Subscript(expr value, expr slice, expr_context ctx)"); if (!state->Subscript_type) return 0; state->Starred_type = make_type("Starred", state->expr_type, - Starred_fields, 2, + Starred_fields, Starred_field_defaults, 2, "Starred(expr value, expr_context ctx)"); if (!state->Starred_type) return 0; - state->Name_type = make_type("Name", state->expr_type, Name_fields, 2, + state->Name_type = make_type("Name", state->expr_type, Name_fields, + Name_field_defaults, 2, "Name(identifier id, expr_context ctx)"); if (!state->Name_type) return 0; - state->List_type = make_type("List", state->expr_type, List_fields, 2, + state->List_type = make_type("List", state->expr_type, List_fields, + List_field_defaults, 2, "List(expr* elts, expr_context ctx)"); if (!state->List_type) return 0; - state->Tuple_type = make_type("Tuple", state->expr_type, Tuple_fields, 2, + state->Tuple_type = make_type("Tuple", state->expr_type, Tuple_fields, + Tuple_field_defaults, 2, "Tuple(expr* elts, expr_context ctx)"); if (!state->Tuple_type) return 0; - state->Slice_type = make_type("Slice", state->expr_type, Slice_fields, 3, + state->Slice_type = make_type("Slice", state->expr_type, Slice_fields, + Slice_field_defaults, 3, "Slice(expr? lower, expr? upper, expr? step)"); if (!state->Slice_type) return 0; if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1) @@ -1715,232 +2106,241 @@ static int init_types(void) if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1) return 0; state->expr_context_type = make_type("expr_context", state->AST_type, NULL, - 0, + NULL, 0, "expr_context = Load | Store | Del"); if (!state->expr_context_type) return 0; if (!add_attributes(state->expr_context_type, NULL, 0)) return 0; - state->Load_type = make_type("Load", state->expr_context_type, NULL, 0, + state->Load_type = make_type("Load", state->expr_context_type, NULL, NULL, + 0, "Load"); if (!state->Load_type) return 0; state->Load_singleton = PyType_GenericNew((PyTypeObject *)state->Load_type, NULL, NULL); if (!state->Load_singleton) return 0; - state->Store_type = make_type("Store", state->expr_context_type, NULL, 0, + state->Store_type = make_type("Store", state->expr_context_type, NULL, + NULL, 0, "Store"); if (!state->Store_type) return 0; state->Store_singleton = PyType_GenericNew((PyTypeObject *)state->Store_type, NULL, NULL); if (!state->Store_singleton) return 0; - state->Del_type = make_type("Del", state->expr_context_type, NULL, 0, + state->Del_type = make_type("Del", state->expr_context_type, NULL, NULL, 0, "Del"); if (!state->Del_type) return 0; state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type, NULL, NULL); if (!state->Del_singleton) return 0; - state->boolop_type = make_type("boolop", state->AST_type, NULL, 0, + state->boolop_type = make_type("boolop", state->AST_type, NULL, NULL, 0, "boolop = And | Or"); if (!state->boolop_type) return 0; if (!add_attributes(state->boolop_type, NULL, 0)) return 0; - state->And_type = make_type("And", state->boolop_type, NULL, 0, + state->And_type = make_type("And", state->boolop_type, NULL, NULL, 0, "And"); if (!state->And_type) return 0; state->And_singleton = PyType_GenericNew((PyTypeObject *)state->And_type, NULL, NULL); if (!state->And_singleton) return 0; - state->Or_type = make_type("Or", state->boolop_type, NULL, 0, + state->Or_type = make_type("Or", state->boolop_type, NULL, NULL, 0, "Or"); if (!state->Or_type) return 0; state->Or_singleton = PyType_GenericNew((PyTypeObject *)state->Or_type, NULL, NULL); if (!state->Or_singleton) return 0; - state->operator_type = make_type("operator", state->AST_type, NULL, 0, + state->operator_type = make_type("operator", state->AST_type, NULL, NULL, 0, "operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv"); if (!state->operator_type) return 0; if (!add_attributes(state->operator_type, NULL, 0)) return 0; - state->Add_type = make_type("Add", state->operator_type, NULL, 0, + state->Add_type = make_type("Add", state->operator_type, NULL, NULL, 0, "Add"); if (!state->Add_type) return 0; state->Add_singleton = PyType_GenericNew((PyTypeObject *)state->Add_type, NULL, NULL); if (!state->Add_singleton) return 0; - state->Sub_type = make_type("Sub", state->operator_type, NULL, 0, + state->Sub_type = make_type("Sub", state->operator_type, NULL, NULL, 0, "Sub"); if (!state->Sub_type) return 0; state->Sub_singleton = PyType_GenericNew((PyTypeObject *)state->Sub_type, NULL, NULL); if (!state->Sub_singleton) return 0; - state->Mult_type = make_type("Mult", state->operator_type, NULL, 0, + state->Mult_type = make_type("Mult", state->operator_type, NULL, NULL, 0, "Mult"); if (!state->Mult_type) return 0; state->Mult_singleton = PyType_GenericNew((PyTypeObject *)state->Mult_type, NULL, NULL); if (!state->Mult_singleton) return 0; - state->MatMult_type = make_type("MatMult", state->operator_type, NULL, 0, + state->MatMult_type = make_type("MatMult", state->operator_type, NULL, + NULL, 0, "MatMult"); if (!state->MatMult_type) return 0; state->MatMult_singleton = PyType_GenericNew((PyTypeObject *)state->MatMult_type, NULL, NULL); if (!state->MatMult_singleton) return 0; - state->Div_type = make_type("Div", state->operator_type, NULL, 0, + state->Div_type = make_type("Div", state->operator_type, NULL, NULL, 0, "Div"); if (!state->Div_type) return 0; state->Div_singleton = PyType_GenericNew((PyTypeObject *)state->Div_type, NULL, NULL); if (!state->Div_singleton) return 0; - state->Mod_type = make_type("Mod", state->operator_type, NULL, 0, + state->Mod_type = make_type("Mod", state->operator_type, NULL, NULL, 0, "Mod"); if (!state->Mod_type) return 0; state->Mod_singleton = PyType_GenericNew((PyTypeObject *)state->Mod_type, NULL, NULL); if (!state->Mod_singleton) return 0; - state->Pow_type = make_type("Pow", state->operator_type, NULL, 0, + state->Pow_type = make_type("Pow", state->operator_type, NULL, NULL, 0, "Pow"); if (!state->Pow_type) return 0; state->Pow_singleton = PyType_GenericNew((PyTypeObject *)state->Pow_type, NULL, NULL); if (!state->Pow_singleton) return 0; - state->LShift_type = make_type("LShift", state->operator_type, NULL, 0, + state->LShift_type = make_type("LShift", state->operator_type, NULL, NULL, + 0, "LShift"); if (!state->LShift_type) return 0; state->LShift_singleton = PyType_GenericNew((PyTypeObject *)state->LShift_type, NULL, NULL); if (!state->LShift_singleton) return 0; - state->RShift_type = make_type("RShift", state->operator_type, NULL, 0, + state->RShift_type = make_type("RShift", state->operator_type, NULL, NULL, + 0, "RShift"); if (!state->RShift_type) return 0; state->RShift_singleton = PyType_GenericNew((PyTypeObject *)state->RShift_type, NULL, NULL); if (!state->RShift_singleton) return 0; - state->BitOr_type = make_type("BitOr", state->operator_type, NULL, 0, + state->BitOr_type = make_type("BitOr", state->operator_type, NULL, NULL, 0, "BitOr"); if (!state->BitOr_type) return 0; state->BitOr_singleton = PyType_GenericNew((PyTypeObject *)state->BitOr_type, NULL, NULL); if (!state->BitOr_singleton) return 0; - state->BitXor_type = make_type("BitXor", state->operator_type, NULL, 0, + state->BitXor_type = make_type("BitXor", state->operator_type, NULL, NULL, + 0, "BitXor"); if (!state->BitXor_type) return 0; state->BitXor_singleton = PyType_GenericNew((PyTypeObject *)state->BitXor_type, NULL, NULL); if (!state->BitXor_singleton) return 0; - state->BitAnd_type = make_type("BitAnd", state->operator_type, NULL, 0, + state->BitAnd_type = make_type("BitAnd", state->operator_type, NULL, NULL, + 0, "BitAnd"); if (!state->BitAnd_type) return 0; state->BitAnd_singleton = PyType_GenericNew((PyTypeObject *)state->BitAnd_type, NULL, NULL); if (!state->BitAnd_singleton) return 0; - state->FloorDiv_type = make_type("FloorDiv", state->operator_type, NULL, 0, + state->FloorDiv_type = make_type("FloorDiv", state->operator_type, NULL, + NULL, 0, "FloorDiv"); if (!state->FloorDiv_type) return 0; state->FloorDiv_singleton = PyType_GenericNew((PyTypeObject *)state->FloorDiv_type, NULL, NULL); if (!state->FloorDiv_singleton) return 0; - state->unaryop_type = make_type("unaryop", state->AST_type, NULL, 0, + state->unaryop_type = make_type("unaryop", state->AST_type, NULL, NULL, 0, "unaryop = Invert | Not | UAdd | USub"); if (!state->unaryop_type) return 0; if (!add_attributes(state->unaryop_type, NULL, 0)) return 0; - state->Invert_type = make_type("Invert", state->unaryop_type, NULL, 0, + state->Invert_type = make_type("Invert", state->unaryop_type, NULL, NULL, 0, "Invert"); if (!state->Invert_type) return 0; state->Invert_singleton = PyType_GenericNew((PyTypeObject *)state->Invert_type, NULL, NULL); if (!state->Invert_singleton) return 0; - state->Not_type = make_type("Not", state->unaryop_type, NULL, 0, + state->Not_type = make_type("Not", state->unaryop_type, NULL, NULL, 0, "Not"); if (!state->Not_type) return 0; state->Not_singleton = PyType_GenericNew((PyTypeObject *)state->Not_type, NULL, NULL); if (!state->Not_singleton) return 0; - state->UAdd_type = make_type("UAdd", state->unaryop_type, NULL, 0, + state->UAdd_type = make_type("UAdd", state->unaryop_type, NULL, NULL, 0, "UAdd"); if (!state->UAdd_type) return 0; state->UAdd_singleton = PyType_GenericNew((PyTypeObject *)state->UAdd_type, NULL, NULL); if (!state->UAdd_singleton) return 0; - state->USub_type = make_type("USub", state->unaryop_type, NULL, 0, + state->USub_type = make_type("USub", state->unaryop_type, NULL, NULL, 0, "USub"); if (!state->USub_type) return 0; state->USub_singleton = PyType_GenericNew((PyTypeObject *)state->USub_type, NULL, NULL); if (!state->USub_singleton) return 0; - state->cmpop_type = make_type("cmpop", state->AST_type, NULL, 0, + state->cmpop_type = make_type("cmpop", state->AST_type, NULL, NULL, 0, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn"); if (!state->cmpop_type) return 0; if (!add_attributes(state->cmpop_type, NULL, 0)) return 0; - state->Eq_type = make_type("Eq", state->cmpop_type, NULL, 0, + state->Eq_type = make_type("Eq", state->cmpop_type, NULL, NULL, 0, "Eq"); if (!state->Eq_type) return 0; state->Eq_singleton = PyType_GenericNew((PyTypeObject *)state->Eq_type, NULL, NULL); if (!state->Eq_singleton) return 0; - state->NotEq_type = make_type("NotEq", state->cmpop_type, NULL, 0, + state->NotEq_type = make_type("NotEq", state->cmpop_type, NULL, NULL, 0, "NotEq"); if (!state->NotEq_type) return 0; state->NotEq_singleton = PyType_GenericNew((PyTypeObject *)state->NotEq_type, NULL, NULL); if (!state->NotEq_singleton) return 0; - state->Lt_type = make_type("Lt", state->cmpop_type, NULL, 0, + state->Lt_type = make_type("Lt", state->cmpop_type, NULL, NULL, 0, "Lt"); if (!state->Lt_type) return 0; state->Lt_singleton = PyType_GenericNew((PyTypeObject *)state->Lt_type, NULL, NULL); if (!state->Lt_singleton) return 0; - state->LtE_type = make_type("LtE", state->cmpop_type, NULL, 0, + state->LtE_type = make_type("LtE", state->cmpop_type, NULL, NULL, 0, "LtE"); if (!state->LtE_type) return 0; state->LtE_singleton = PyType_GenericNew((PyTypeObject *)state->LtE_type, NULL, NULL); if (!state->LtE_singleton) return 0; - state->Gt_type = make_type("Gt", state->cmpop_type, NULL, 0, + state->Gt_type = make_type("Gt", state->cmpop_type, NULL, NULL, 0, "Gt"); if (!state->Gt_type) return 0; state->Gt_singleton = PyType_GenericNew((PyTypeObject *)state->Gt_type, NULL, NULL); if (!state->Gt_singleton) return 0; - state->GtE_type = make_type("GtE", state->cmpop_type, NULL, 0, + state->GtE_type = make_type("GtE", state->cmpop_type, NULL, NULL, 0, "GtE"); if (!state->GtE_type) return 0; state->GtE_singleton = PyType_GenericNew((PyTypeObject *)state->GtE_type, NULL, NULL); if (!state->GtE_singleton) return 0; - state->Is_type = make_type("Is", state->cmpop_type, NULL, 0, + state->Is_type = make_type("Is", state->cmpop_type, NULL, NULL, 0, "Is"); if (!state->Is_type) return 0; state->Is_singleton = PyType_GenericNew((PyTypeObject *)state->Is_type, NULL, NULL); if (!state->Is_singleton) return 0; - state->IsNot_type = make_type("IsNot", state->cmpop_type, NULL, 0, + state->IsNot_type = make_type("IsNot", state->cmpop_type, NULL, NULL, 0, "IsNot"); if (!state->IsNot_type) return 0; state->IsNot_singleton = PyType_GenericNew((PyTypeObject *)state->IsNot_type, NULL, NULL); if (!state->IsNot_singleton) return 0; - state->In_type = make_type("In", state->cmpop_type, NULL, 0, + state->In_type = make_type("In", state->cmpop_type, NULL, NULL, 0, "In"); if (!state->In_type) return 0; state->In_singleton = PyType_GenericNew((PyTypeObject *)state->In_type, NULL, NULL); if (!state->In_singleton) return 0; - state->NotIn_type = make_type("NotIn", state->cmpop_type, NULL, 0, + state->NotIn_type = make_type("NotIn", state->cmpop_type, NULL, NULL, 0, "NotIn"); if (!state->NotIn_type) return 0; state->NotIn_singleton = PyType_GenericNew((PyTypeObject *)state->NotIn_type, NULL, NULL); if (!state->NotIn_singleton) return 0; state->comprehension_type = make_type("comprehension", state->AST_type, - comprehension_fields, 4, + comprehension_fields, + comprehension_field_defaults, 4, "comprehension(expr target, expr iter, expr* ifs, int is_async)"); if (!state->comprehension_type) return 0; if (!add_attributes(state->comprehension_type, NULL, 0)) return 0; state->excepthandler_type = make_type("excepthandler", state->AST_type, - NULL, 0, + NULL, NULL, 0, "excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)"); if (!state->excepthandler_type) return 0; if (!add_attributes(state->excepthandler_type, excepthandler_attributes, @@ -1953,7 +2353,8 @@ static int init_types(void) return 0; state->ExceptHandler_type = make_type("ExceptHandler", state->excepthandler_type, - ExceptHandler_fields, 3, + ExceptHandler_fields, + ExceptHandler_field_defaults, 3, "ExceptHandler(expr? type, identifier? name, stmt* body)"); if (!state->ExceptHandler_type) return 0; if (PyObject_SetAttr(state->ExceptHandler_type, state->type, Py_None) == -1) @@ -1961,7 +2362,8 @@ static int init_types(void) if (PyObject_SetAttr(state->ExceptHandler_type, state->name, Py_None) == -1) return 0; state->arguments_type = make_type("arguments", state->AST_type, - arguments_fields, 7, + arguments_fields, + arguments_field_defaults, 7, "arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults)"); if (!state->arguments_type) return 0; if (!add_attributes(state->arguments_type, NULL, 0)) return 0; @@ -1969,7 +2371,8 @@ static int init_types(void) return 0; if (PyObject_SetAttr(state->arguments_type, state->kwarg, Py_None) == -1) return 0; - state->arg_type = make_type("arg", state->AST_type, arg_fields, 3, + state->arg_type = make_type("arg", state->AST_type, arg_fields, + arg_field_defaults, 3, "arg(identifier arg, expr? annotation, string? type_comment)"); if (!state->arg_type) return 0; if (!add_attributes(state->arg_type, arg_attributes, 4)) return 0; @@ -1982,32 +2385,36 @@ static int init_types(void) if (PyObject_SetAttr(state->arg_type, state->end_col_offset, Py_None) == -1) return 0; state->keyword_type = make_type("keyword", state->AST_type, keyword_fields, - 2, + keyword_field_defaults, 2, "keyword(identifier? arg, expr value)"); if (!state->keyword_type) return 0; if (!add_attributes(state->keyword_type, NULL, 0)) return 0; if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1) return 0; - state->alias_type = make_type("alias", state->AST_type, alias_fields, 2, + state->alias_type = make_type("alias", state->AST_type, alias_fields, + alias_field_defaults, 2, "alias(identifier name, identifier? asname)"); if (!state->alias_type) return 0; if (!add_attributes(state->alias_type, NULL, 0)) return 0; if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1) return 0; state->withitem_type = make_type("withitem", state->AST_type, - withitem_fields, 2, + withitem_fields, withitem_field_defaults, + 2, "withitem(expr context_expr, expr? optional_vars)"); if (!state->withitem_type) return 0; if (!add_attributes(state->withitem_type, NULL, 0)) return 0; if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None) == -1) return 0; - state->type_ignore_type = make_type("type_ignore", state->AST_type, NULL, 0, + state->type_ignore_type = make_type("type_ignore", state->AST_type, NULL, + NULL, 0, "type_ignore = TypeIgnore(int lineno, string tag)"); if (!state->type_ignore_type) return 0; if (!add_attributes(state->type_ignore_type, NULL, 0)) return 0; state->TypeIgnore_type = make_type("TypeIgnore", state->type_ignore_type, - TypeIgnore_fields, 2, + TypeIgnore_fields, + TypeIgnore_field_defaults, 2, "TypeIgnore(int lineno, string tag)"); if (!state->TypeIgnore_type) return 0; state->initialized = 1;