summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2020-03-09 22:07:47 (GMT)
committerGitHub <noreply@github.com>2020-03-09 22:07:47 (GMT)
commitb7e9525f9c7ef02a1d2ad8253afdeb733b0951d4 (patch)
treea5a765156210e426d89e5f19a75f932dd2165834 /Lib
parent85f5a69ae1541271286bb0f0e0303aabf792dd5c (diff)
downloadcpython-b7e9525f9c7ef02a1d2ad8253afdeb733b0951d4.zip
cpython-b7e9525f9c7ef02a1d2ad8253afdeb733b0951d4.tar.gz
cpython-b7e9525f9c7ef02a1d2ad8253afdeb733b0951d4.tar.bz2
bpo-36287: Make ast.dump() not output optional fields and attributes with default values. (GH-18843)
The default values for optional fields and attributes of AST nodes are now set as class attributes (e.g. Constant.kind is set to None).
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ast.py46
-rw-r--r--Lib/test/test_ast.py29
2 files changed, 41 insertions, 34 deletions
diff --git a/Lib/ast.py b/Lib/ast.py
index 9a3d380..0bce4a4 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -123,31 +123,36 @@ def dump(node, annotate_fields=True, include_attributes=False, *, indent=None):
prefix = ''
sep = ', '
if isinstance(node, AST):
+ cls = type(node)
args = []
allsimple = True
keywords = annotate_fields
- for field in node._fields:
+ for name in node._fields:
try:
- value = getattr(node, field)
+ value = getattr(node, name)
except AttributeError:
keywords = True
+ continue
+ if value is None and getattr(cls, name, ...) is None:
+ keywords = True
+ continue
+ value, simple = _format(value, level)
+ allsimple = allsimple and simple
+ if keywords:
+ args.append('%s=%s' % (name, value))
else:
- value, simple = _format(value, level)
- allsimple = allsimple and simple
- if keywords:
- args.append('%s=%s' % (field, value))
- else:
- args.append(value)
+ args.append(value)
if include_attributes and node._attributes:
- for attr in node._attributes:
+ for name in node._attributes:
try:
- value = getattr(node, attr)
+ value = getattr(node, name)
except AttributeError:
- pass
- else:
- value, simple = _format(value, level)
- allsimple = allsimple and simple
- args.append('%s=%s' % (attr, value))
+ continue
+ if value is None and getattr(cls, name, ...) is None:
+ continue
+ value, simple = _format(value, level)
+ allsimple = allsimple and simple
+ args.append('%s=%s' % (name, value))
if allsimple and len(args) <= 3:
return '%s(%s)' % (node.__class__.__name__, ', '.join(args)), not args
return '%s(%s%s)' % (node.__class__.__name__, prefix, sep.join(args)), False
@@ -170,9 +175,10 @@ def copy_location(new_node, old_node):
attributes) from *old_node* to *new_node* if possible, and return *new_node*.
"""
for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':
- if attr in old_node._attributes and attr in new_node._attributes \
- and hasattr(old_node, attr):
- setattr(new_node, attr, getattr(old_node, attr))
+ if attr in old_node._attributes and attr in new_node._attributes:
+ value = getattr(old_node, attr, None)
+ if value is not None:
+ setattr(new_node, attr, value)
return new_node
@@ -191,7 +197,7 @@ def fix_missing_locations(node):
else:
lineno = node.lineno
if 'end_lineno' in node._attributes:
- if not hasattr(node, 'end_lineno'):
+ if getattr(node, 'end_lineno', None) is None:
node.end_lineno = end_lineno
else:
end_lineno = node.end_lineno
@@ -201,7 +207,7 @@ def fix_missing_locations(node):
else:
col_offset = node.col_offset
if 'end_col_offset' in node._attributes:
- if not hasattr(node, 'end_col_offset'):
+ if getattr(node, 'end_col_offset', None) is None:
node.end_col_offset = end_col_offset
else:
end_col_offset = node.end_col_offset
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index e788485..c1e9f00 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -353,9 +353,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):
@@ -650,18 +652,18 @@ 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=[])"
@@ -677,7 +679,7 @@ Module(
func=Name(id='spam', ctx=Load()),
args=[
Name(id='eggs', ctx=Load()),
- Constant(value='and cheese', kind=None)],
+ Constant(value='and cheese')],
keywords=[]))],
type_ignores=[])""")
self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
@@ -688,7 +690,7 @@ Module(
\t\t\t\tName('spam', Load()),
\t\t\t\t[
\t\t\t\t\tName('eggs', Load()),
-\t\t\t\t\tConstant('and cheese', None)],
+\t\t\t\t\tConstant('and cheese')],
\t\t\t\t[]))],
\t[])""")
self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
@@ -713,7 +715,6 @@ Module(
end_col_offset=9),
Constant(
value='and cheese',
- kind=None,
lineno=1,
col_offset=11,
end_lineno=1,
@@ -762,7 +763,7 @@ Module(
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))'
@@ -777,7 +778,7 @@ Module(
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(), "
@@ -792,8 +793,8 @@ Module(
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))'
)
@@ -801,8 +802,8 @@ Module(
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))'
)
@@ -821,7 +822,7 @@ Module(
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):