bpo-32911: Revert bpo-29463. (GH-7121) (GH-7197)
Remove the docstring attribute of AST types and restore docstring expression as a first stmt in their body. Co-authored-by: INADA Naoki <methane@users.noreply.github.com>
This commit is contained in:
parent
2179022d94
commit
73cbe7a01a
|
@ -151,10 +151,6 @@ and classes for traversing abstract syntax trees:
|
||||||
.. versionchanged:: 3.5
|
.. versionchanged:: 3.5
|
||||||
:class:`AsyncFunctionDef` is now supported.
|
:class:`AsyncFunctionDef` is now supported.
|
||||||
|
|
||||||
.. versionchanged:: 3.7
|
|
||||||
The docstring is now exported from the node docstring field, instead of
|
|
||||||
the first body statement.
|
|
||||||
|
|
||||||
|
|
||||||
.. function:: fix_missing_locations(node)
|
.. function:: fix_missing_locations(node)
|
||||||
|
|
||||||
|
|
|
@ -2161,13 +2161,6 @@ Changes in Python Behavior
|
||||||
Changes in the Python API
|
Changes in the Python API
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
* ``Module``, ``FunctionDef``, ``AsyncFunctionDef``, and
|
|
||||||
``ClassDef`` AST nodes now have the new ``docstring`` attribute.
|
|
||||||
The first statement in their body is not considered as a docstring
|
|
||||||
anymore. ``co_firstlineno`` and ``co_lnotab`` of code object for class
|
|
||||||
and module are affected by this change. (Contributed by INADA Naoki and
|
|
||||||
Eugene Toder in :issue:`29463`.)
|
|
||||||
|
|
||||||
* :meth:`socketserver.ThreadingMixIn.server_close` now waits until all
|
* :meth:`socketserver.ThreadingMixIn.server_close` now waits until all
|
||||||
non-daemon threads complete. Set the new
|
non-daemon threads complete. Set the new
|
||||||
:attr:`socketserver.ThreadingMixIn.block_on_close` class attribute to
|
:attr:`socketserver.ThreadingMixIn.block_on_close` class attribute to
|
||||||
|
|
|
@ -46,7 +46,6 @@ struct _mod {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
string docstring;
|
|
||||||
} Module;
|
} Module;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -81,7 +80,6 @@ struct _stmt {
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
asdl_seq *decorator_list;
|
asdl_seq *decorator_list;
|
||||||
expr_ty returns;
|
expr_ty returns;
|
||||||
string docstring;
|
|
||||||
} FunctionDef;
|
} FunctionDef;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -90,7 +88,6 @@ struct _stmt {
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
asdl_seq *decorator_list;
|
asdl_seq *decorator_list;
|
||||||
expr_ty returns;
|
expr_ty returns;
|
||||||
string docstring;
|
|
||||||
} AsyncFunctionDef;
|
} AsyncFunctionDef;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -99,7 +96,6 @@ struct _stmt {
|
||||||
asdl_seq *keywords;
|
asdl_seq *keywords;
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
asdl_seq *decorator_list;
|
asdl_seq *decorator_list;
|
||||||
string docstring;
|
|
||||||
} ClassDef;
|
} ClassDef;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -443,27 +439,26 @@ struct _withitem {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define Module(a0, a1, a2) _Py_Module(a0, a1, a2)
|
#define Module(a0, a1) _Py_Module(a0, a1)
|
||||||
mod_ty _Py_Module(asdl_seq * body, string docstring, PyArena *arena);
|
mod_ty _Py_Module(asdl_seq * body, PyArena *arena);
|
||||||
#define Interactive(a0, a1) _Py_Interactive(a0, a1)
|
#define Interactive(a0, a1) _Py_Interactive(a0, a1)
|
||||||
mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena);
|
mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena);
|
||||||
#define Expression(a0, a1) _Py_Expression(a0, a1)
|
#define Expression(a0, a1) _Py_Expression(a0, a1)
|
||||||
mod_ty _Py_Expression(expr_ty body, PyArena *arena);
|
mod_ty _Py_Expression(expr_ty body, PyArena *arena);
|
||||||
#define Suite(a0, a1) _Py_Suite(a0, a1)
|
#define Suite(a0, a1) _Py_Suite(a0, a1)
|
||||||
mod_ty _Py_Suite(asdl_seq * body, PyArena *arena);
|
mod_ty _Py_Suite(asdl_seq * body, PyArena *arena);
|
||||||
#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||||
stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
|
stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
|
||||||
asdl_seq * decorator_list, expr_ty returns, string
|
asdl_seq * decorator_list, expr_ty returns, int lineno,
|
||||||
docstring, int lineno, int col_offset, PyArena *arena);
|
int col_offset, PyArena *arena);
|
||||||
#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||||
stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq *
|
stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq *
|
||||||
body, asdl_seq * decorator_list, expr_ty returns,
|
body, asdl_seq * decorator_list, expr_ty returns,
|
||||||
string docstring, int lineno, int col_offset,
|
int lineno, int col_offset, PyArena *arena);
|
||||||
PyArena *arena);
|
#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||||
#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
|
||||||
stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords,
|
stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords,
|
||||||
asdl_seq * body, asdl_seq * decorator_list, string
|
asdl_seq * body, asdl_seq * decorator_list, int lineno,
|
||||||
docstring, int lineno, int col_offset, PyArena *arena);
|
int col_offset, PyArena *arena);
|
||||||
#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3)
|
#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3)
|
||||||
stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena);
|
stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena);
|
||||||
#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3)
|
#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3)
|
||||||
|
|
10
Lib/ast.py
10
Lib/ast.py
|
@ -206,7 +206,15 @@ def get_docstring(node, clean=True):
|
||||||
"""
|
"""
|
||||||
if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):
|
if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):
|
||||||
raise TypeError("%r can't have docstrings" % node.__class__.__name__)
|
raise TypeError("%r can't have docstrings" % node.__class__.__name__)
|
||||||
text = node.docstring
|
if not node.body:
|
||||||
|
return None
|
||||||
|
node = node.body[0].value
|
||||||
|
if isinstance(node, Str):
|
||||||
|
text = node.s
|
||||||
|
elif isinstance(node, Constant) and isinstance(node.value, str):
|
||||||
|
text = node.value
|
||||||
|
else:
|
||||||
|
return None
|
||||||
if clean and text:
|
if clean and text:
|
||||||
import inspect
|
import inspect
|
||||||
text = inspect.cleandoc(text)
|
text = inspect.cleandoc(text)
|
||||||
|
|
|
@ -327,24 +327,9 @@ class AST_Tests(unittest.TestCase):
|
||||||
|
|
||||||
def test_module(self):
|
def test_module(self):
|
||||||
body = [ast.Num(42)]
|
body = [ast.Num(42)]
|
||||||
x = ast.Module(body, None)
|
x = ast.Module(body)
|
||||||
self.assertEqual(x.body, body)
|
self.assertEqual(x.body, body)
|
||||||
|
|
||||||
def test_docstring(self):
|
|
||||||
body = [] # AST nodes having docstring must accept empty body
|
|
||||||
x = ast.Module(body, "module docstring")
|
|
||||||
self.assertEqual(x.docstring, "module docstring")
|
|
||||||
|
|
||||||
a = ast.arguments()
|
|
||||||
x = ast.FunctionDef("x", a, body, [], None, "func docstring")
|
|
||||||
self.assertEqual(x.docstring, "func docstring")
|
|
||||||
|
|
||||||
x = ast.AsyncFunctionDef("x", a, body, [], None, "async func docstring")
|
|
||||||
self.assertEqual(x.docstring, "async func docstring")
|
|
||||||
|
|
||||||
x = ast.ClassDef("x", [], [], body, [], "class docstring")
|
|
||||||
self.assertEqual(x.docstring, "class docstring")
|
|
||||||
|
|
||||||
def test_nodeclasses(self):
|
def test_nodeclasses(self):
|
||||||
# Zero arguments constructor explicitly allowed
|
# Zero arguments constructor explicitly allowed
|
||||||
x = ast.BinOp()
|
x = ast.BinOp()
|
||||||
|
@ -411,13 +396,13 @@ class AST_Tests(unittest.TestCase):
|
||||||
|
|
||||||
def test_invalid_sum(self):
|
def test_invalid_sum(self):
|
||||||
pos = dict(lineno=2, col_offset=3)
|
pos = dict(lineno=2, col_offset=3)
|
||||||
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], "doc")
|
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)])
|
||||||
with self.assertRaises(TypeError) as cm:
|
with self.assertRaises(TypeError) as cm:
|
||||||
compile(m, "<test>", "exec")
|
compile(m, "<test>", "exec")
|
||||||
self.assertIn("but got <_ast.expr", str(cm.exception))
|
self.assertIn("but got <_ast.expr", str(cm.exception))
|
||||||
|
|
||||||
def test_invalid_identitifer(self):
|
def test_invalid_identitifer(self):
|
||||||
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], None)
|
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))])
|
||||||
ast.fix_missing_locations(m)
|
ast.fix_missing_locations(m)
|
||||||
with self.assertRaises(TypeError) as cm:
|
with self.assertRaises(TypeError) as cm:
|
||||||
compile(m, "<test>", "exec")
|
compile(m, "<test>", "exec")
|
||||||
|
@ -462,18 +447,18 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||||
self.assertEqual(ast.dump(node),
|
self.assertEqual(ast.dump(node),
|
||||||
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
|
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
|
||||||
"args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
|
"args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
|
||||||
"keywords=[]))], docstring=None)"
|
"keywords=[]))])"
|
||||||
)
|
)
|
||||||
self.assertEqual(ast.dump(node, annotate_fields=False),
|
self.assertEqual(ast.dump(node, annotate_fields=False),
|
||||||
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
|
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
|
||||||
"Str('and cheese')], []))], None)"
|
"Str('and cheese')], []))])"
|
||||||
)
|
)
|
||||||
self.assertEqual(ast.dump(node, include_attributes=True),
|
self.assertEqual(ast.dump(node, include_attributes=True),
|
||||||
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
|
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
|
||||||
"lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
|
"lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
|
||||||
"lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
|
"lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
|
||||||
"col_offset=11)], keywords=[], "
|
"col_offset=11)], keywords=[], "
|
||||||
"lineno=1, col_offset=0), lineno=1, col_offset=0)], docstring=None)"
|
"lineno=1, col_offset=0), lineno=1, col_offset=0)])"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_copy_location(self):
|
def test_copy_location(self):
|
||||||
|
@ -498,7 +483,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||||
"Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, "
|
"Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, "
|
||||||
"col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], "
|
"col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], "
|
||||||
"keywords=[], lineno=1, "
|
"keywords=[], lineno=1, "
|
||||||
"col_offset=0), lineno=1, col_offset=0)], docstring=None)"
|
"col_offset=0), lineno=1, col_offset=0)])"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_increment_lineno(self):
|
def test_increment_lineno(self):
|
||||||
|
@ -589,7 +574,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||||
names=[ast.alias(name='sleep')],
|
names=[ast.alias(name='sleep')],
|
||||||
level=None,
|
level=None,
|
||||||
lineno=None, col_offset=None)]
|
lineno=None, col_offset=None)]
|
||||||
mod = ast.Module(body, None)
|
mod = ast.Module(body)
|
||||||
with self.assertRaises(ValueError) as cm:
|
with self.assertRaises(ValueError) as cm:
|
||||||
compile(mod, 'test', 'exec')
|
compile(mod, 'test', 'exec')
|
||||||
self.assertIn("invalid integer value: None", str(cm.exception))
|
self.assertIn("invalid integer value: None", str(cm.exception))
|
||||||
|
@ -599,7 +584,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
||||||
names=[ast.alias(name='sleep')],
|
names=[ast.alias(name='sleep')],
|
||||||
level=None,
|
level=None,
|
||||||
lineno=0, col_offset=0)]
|
lineno=0, col_offset=0)]
|
||||||
mod = ast.Module(body, None)
|
mod = ast.Module(body)
|
||||||
code = compile(mod, 'test', 'exec')
|
code = compile(mod, 'test', 'exec')
|
||||||
ns = {}
|
ns = {}
|
||||||
exec(code, ns)
|
exec(code, ns)
|
||||||
|
@ -617,11 +602,11 @@ class ASTValidatorTests(unittest.TestCase):
|
||||||
self.assertIn(msg, str(cm.exception))
|
self.assertIn(msg, str(cm.exception))
|
||||||
|
|
||||||
def expr(self, node, msg=None, *, exc=ValueError):
|
def expr(self, node, msg=None, *, exc=ValueError):
|
||||||
mod = ast.Module([ast.Expr(node)], None)
|
mod = ast.Module([ast.Expr(node)])
|
||||||
self.mod(mod, msg, exc=exc)
|
self.mod(mod, msg, exc=exc)
|
||||||
|
|
||||||
def stmt(self, stmt, msg=None):
|
def stmt(self, stmt, msg=None):
|
||||||
mod = ast.Module([stmt], None)
|
mod = ast.Module([stmt])
|
||||||
self.mod(mod, msg)
|
self.mod(mod, msg)
|
||||||
|
|
||||||
def test_module(self):
|
def test_module(self):
|
||||||
|
@ -663,16 +648,16 @@ class ASTValidatorTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_funcdef(self):
|
def test_funcdef(self):
|
||||||
a = ast.arguments([], None, [], [], None, [])
|
a = ast.arguments([], None, [], [], None, [])
|
||||||
f = ast.FunctionDef("x", a, [], [], None, None)
|
f = ast.FunctionDef("x", a, [], [], None)
|
||||||
self.stmt(f, "empty body on FunctionDef")
|
self.stmt(f, "empty body on FunctionDef")
|
||||||
f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
|
f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
|
||||||
None, None)
|
None)
|
||||||
self.stmt(f, "must have Load context")
|
self.stmt(f, "must have Load context")
|
||||||
f = ast.FunctionDef("x", a, [ast.Pass()], [],
|
f = ast.FunctionDef("x", a, [ast.Pass()], [],
|
||||||
ast.Name("x", ast.Store()), None)
|
ast.Name("x", ast.Store()))
|
||||||
self.stmt(f, "must have Load context")
|
self.stmt(f, "must have Load context")
|
||||||
def fac(args):
|
def fac(args):
|
||||||
return ast.FunctionDef("x", args, [ast.Pass()], [], None, None)
|
return ast.FunctionDef("x", args, [ast.Pass()], [], None)
|
||||||
self._check_arguments(fac, self.stmt)
|
self._check_arguments(fac, self.stmt)
|
||||||
|
|
||||||
def test_classdef(self):
|
def test_classdef(self):
|
||||||
|
@ -686,7 +671,7 @@ class ASTValidatorTests(unittest.TestCase):
|
||||||
if decorator_list is None:
|
if decorator_list is None:
|
||||||
decorator_list = []
|
decorator_list = []
|
||||||
return ast.ClassDef("myclass", bases, keywords,
|
return ast.ClassDef("myclass", bases, keywords,
|
||||||
body, decorator_list, None)
|
body, decorator_list)
|
||||||
self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
|
self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
|
||||||
"must have Load context")
|
"must have Load context")
|
||||||
self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
|
self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
|
||||||
|
@ -1124,53 +1109,53 @@ def main():
|
||||||
|
|
||||||
#### EVERYTHING BELOW IS GENERATED #####
|
#### EVERYTHING BELOW IS GENERATED #####
|
||||||
exec_results = [
|
exec_results = [
|
||||||
('Module', [('Expr', (1, 0), ('NameConstant', (1, 0), None))], None),
|
('Module', [('Expr', (1, 0), ('NameConstant', (1, 0), None))]),
|
||||||
('Module', [], 'module docstring'),
|
('Module', [('Expr', (1, 0), ('Str', (1, 0), 'module docstring'))]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (1, 9))], [], None)]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [], [], None, 'function docstring')], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (1, 9), ('Str', (1, 9), 'function docstring'))], [], None)]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, []), [('Pass', (1, 10))], [], None)]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Num', (1, 8), 0)]), [('Pass', (1, 12))], [], None, None)], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Num', (1, 8), 0)]), [('Pass', (1, 12))], [], None)]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None)]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None, None)], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None)]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Num', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [], [], None, 'doc for f()')], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Num', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Str', (1, 58), 'doc for f()'))], [], None)]),
|
||||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [], None)], None),
|
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])]),
|
||||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [], [], 'docstring for class C')], None),
|
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Str', (1, 9), 'docstring for class C'))], [])]),
|
||||||
('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [], None)], None),
|
('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])]),
|
||||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None, None)], None),
|
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]),
|
||||||
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], None),
|
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
|
||||||
('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))], None),
|
('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
|
||||||
('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))], None),
|
('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))]),
|
||||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])], None),
|
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
|
||||||
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], None),
|
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
|
||||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], None),
|
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
|
||||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])], None),
|
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
|
||||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])], None),
|
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
|
||||||
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], []), None)], None),
|
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], []), None)]),
|
||||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], None),
|
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]),
|
||||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], None),
|
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]),
|
||||||
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], None),
|
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
|
||||||
('Module', [('Import', (1, 0), [('alias', 'sys', None)])], None),
|
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
|
||||||
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], None),
|
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
|
||||||
('Module', [('Global', (1, 0), ['v'])], None),
|
('Module', [('Global', (1, 0), ['v'])]),
|
||||||
('Module', [('Expr', (1, 0), ('Num', (1, 0), 1))], None),
|
('Module', [('Expr', (1, 0), ('Num', (1, 0), 1))]),
|
||||||
('Module', [('Pass', (1, 0))], None),
|
('Module', [('Pass', (1, 0))]),
|
||||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [])], None),
|
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [])]),
|
||||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [])], None),
|
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [])]),
|
||||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])], None),
|
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]),
|
||||||
('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], None),
|
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))]),
|
||||||
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, 'async function')], None),
|
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Str', (2, 1), 'async function')), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None)]),
|
||||||
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 7), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Num', (2, 19), 1))], [('Expr', (3, 7), ('Num', (3, 7), 2))])], [], None, None)], None),
|
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 7), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Num', (2, 19), 1))], [('Expr', (3, 7), ('Num', (3, 7), 2))])], [], None)]),
|
||||||
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 7), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Num', (2, 20), 1))])], [], None, None)], None),
|
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 7), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Num', (2, 20), 1))])], [], None)]),
|
||||||
('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Num', (1, 10), 2)], [('Dict', (1, 3), [('Num', (1, 4), 1)], [('Num', (1, 6), 2)]), ('Num', (1, 12), 3)]))], None),
|
('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Num', (1, 10), 2)], [('Dict', (1, 3), [('Num', (1, 4), 1)], [('Num', (1, 6), 2)]), ('Num', (1, 12), 3)]))]),
|
||||||
('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Num', (1, 3), 1), ('Num', (1, 6), 2)]), ('Load',)), ('Num', (1, 10), 3)]))], None),
|
('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Num', (1, 3), 1), ('Num', (1, 6), 2)]), ('Load',)), ('Num', (1, 10), 3)]))]),
|
||||||
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 2), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], None),
|
('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 2), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None)]),
|
||||||
]
|
]
|
||||||
single_results = [
|
single_results = [
|
||||||
('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
|
('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
|
||||||
|
|
|
@ -27,7 +27,7 @@ class OpcodeTest(unittest.TestCase):
|
||||||
with open(ann_module.__file__) as f:
|
with open(ann_module.__file__) as f:
|
||||||
txt = f.read()
|
txt = f.read()
|
||||||
co = compile(txt, ann_module.__file__, 'exec')
|
co = compile(txt, ann_module.__file__, 'exec')
|
||||||
self.assertEqual(co.co_firstlineno, 8)
|
self.assertEqual(co.co_firstlineno, 6)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -788,7 +788,7 @@ objects.
|
||||||
Add ``docstring`` field to Module, ClassDef, FunctionDef, and
|
Add ``docstring`` field to Module, ClassDef, FunctionDef, and
|
||||||
AsyncFunctionDef ast nodes. docstring is not first stmt in their body
|
AsyncFunctionDef ast nodes. docstring is not first stmt in their body
|
||||||
anymore. It affects ``co_firstlineno`` and ``co_lnotab`` of code object for
|
anymore. It affects ``co_firstlineno`` and ``co_lnotab`` of code object for
|
||||||
module and class.
|
module and class. (Reverted in :issue:`32911`.)
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Due to unexpected compatibility issues discovered during downstream beta
|
||||||
|
testing, reverted :issue:`29463`. ``docstring`` field is removed from Module,
|
||||||
|
ClassDef, FunctionDef, and AsyncFunctionDef ast nodes which was added in
|
||||||
|
3.7a1. Docstring expression is restored as a first statement in their body.
|
||||||
|
Based on patch by Inada Naoki.
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
module Python
|
module Python
|
||||||
{
|
{
|
||||||
mod = Module(stmt* body, string? docstring)
|
mod = Module(stmt* body)
|
||||||
| Interactive(stmt* body)
|
| Interactive(stmt* body)
|
||||||
| Expression(expr body)
|
| Expression(expr body)
|
||||||
|
|
||||||
|
@ -14,18 +14,15 @@ module Python
|
||||||
| Suite(stmt* body)
|
| Suite(stmt* body)
|
||||||
|
|
||||||
stmt = FunctionDef(identifier name, arguments args,
|
stmt = FunctionDef(identifier name, arguments args,
|
||||||
stmt* body, expr* decorator_list, expr? returns,
|
stmt* body, expr* decorator_list, expr? returns)
|
||||||
string? docstring)
|
|
||||||
| AsyncFunctionDef(identifier name, arguments args,
|
| AsyncFunctionDef(identifier name, arguments args,
|
||||||
stmt* body, expr* decorator_list, expr? returns,
|
stmt* body, expr* decorator_list, expr? returns)
|
||||||
string? docstring)
|
|
||||||
|
|
||||||
| ClassDef(identifier name,
|
| ClassDef(identifier name,
|
||||||
expr* bases,
|
expr* bases,
|
||||||
keyword* keywords,
|
keyword* keywords,
|
||||||
stmt* body,
|
stmt* body,
|
||||||
expr* decorator_list,
|
expr* decorator_list)
|
||||||
string? docstring)
|
|
||||||
| Return(expr? value)
|
| Return(expr? value)
|
||||||
|
|
||||||
| Delete(expr* targets)
|
| Delete(expr* targets)
|
||||||
|
|
|
@ -10,10 +10,8 @@ static PyTypeObject *mod_type;
|
||||||
static PyObject* ast2obj_mod(void*);
|
static PyObject* ast2obj_mod(void*);
|
||||||
static PyTypeObject *Module_type;
|
static PyTypeObject *Module_type;
|
||||||
_Py_IDENTIFIER(body);
|
_Py_IDENTIFIER(body);
|
||||||
_Py_IDENTIFIER(docstring);
|
|
||||||
static char *Module_fields[]={
|
static char *Module_fields[]={
|
||||||
"body",
|
"body",
|
||||||
"docstring",
|
|
||||||
};
|
};
|
||||||
static PyTypeObject *Interactive_type;
|
static PyTypeObject *Interactive_type;
|
||||||
static char *Interactive_fields[]={
|
static char *Interactive_fields[]={
|
||||||
|
@ -46,7 +44,6 @@ static char *FunctionDef_fields[]={
|
||||||
"body",
|
"body",
|
||||||
"decorator_list",
|
"decorator_list",
|
||||||
"returns",
|
"returns",
|
||||||
"docstring",
|
|
||||||
};
|
};
|
||||||
static PyTypeObject *AsyncFunctionDef_type;
|
static PyTypeObject *AsyncFunctionDef_type;
|
||||||
static char *AsyncFunctionDef_fields[]={
|
static char *AsyncFunctionDef_fields[]={
|
||||||
|
@ -55,7 +52,6 @@ static char *AsyncFunctionDef_fields[]={
|
||||||
"body",
|
"body",
|
||||||
"decorator_list",
|
"decorator_list",
|
||||||
"returns",
|
"returns",
|
||||||
"docstring",
|
|
||||||
};
|
};
|
||||||
static PyTypeObject *ClassDef_type;
|
static PyTypeObject *ClassDef_type;
|
||||||
_Py_IDENTIFIER(bases);
|
_Py_IDENTIFIER(bases);
|
||||||
|
@ -66,7 +62,6 @@ static char *ClassDef_fields[]={
|
||||||
"keywords",
|
"keywords",
|
||||||
"body",
|
"body",
|
||||||
"decorator_list",
|
"decorator_list",
|
||||||
"docstring",
|
|
||||||
};
|
};
|
||||||
static PyTypeObject *Return_type;
|
static PyTypeObject *Return_type;
|
||||||
_Py_IDENTIFIER(value);
|
_Py_IDENTIFIER(value);
|
||||||
|
@ -847,7 +842,7 @@ static int init_types(void)
|
||||||
mod_type = make_type("mod", &AST_type, NULL, 0);
|
mod_type = make_type("mod", &AST_type, NULL, 0);
|
||||||
if (!mod_type) return 0;
|
if (!mod_type) return 0;
|
||||||
if (!add_attributes(mod_type, NULL, 0)) return 0;
|
if (!add_attributes(mod_type, NULL, 0)) return 0;
|
||||||
Module_type = make_type("Module", mod_type, Module_fields, 2);
|
Module_type = make_type("Module", mod_type, Module_fields, 1);
|
||||||
if (!Module_type) return 0;
|
if (!Module_type) return 0;
|
||||||
Interactive_type = make_type("Interactive", mod_type, Interactive_fields,
|
Interactive_type = make_type("Interactive", mod_type, Interactive_fields,
|
||||||
1);
|
1);
|
||||||
|
@ -860,12 +855,12 @@ static int init_types(void)
|
||||||
if (!stmt_type) return 0;
|
if (!stmt_type) return 0;
|
||||||
if (!add_attributes(stmt_type, stmt_attributes, 2)) return 0;
|
if (!add_attributes(stmt_type, stmt_attributes, 2)) return 0;
|
||||||
FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields,
|
FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields,
|
||||||
6);
|
5);
|
||||||
if (!FunctionDef_type) return 0;
|
if (!FunctionDef_type) return 0;
|
||||||
AsyncFunctionDef_type = make_type("AsyncFunctionDef", stmt_type,
|
AsyncFunctionDef_type = make_type("AsyncFunctionDef", stmt_type,
|
||||||
AsyncFunctionDef_fields, 6);
|
AsyncFunctionDef_fields, 5);
|
||||||
if (!AsyncFunctionDef_type) return 0;
|
if (!AsyncFunctionDef_type) return 0;
|
||||||
ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 6);
|
ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 5);
|
||||||
if (!ClassDef_type) return 0;
|
if (!ClassDef_type) return 0;
|
||||||
Return_type = make_type("Return", stmt_type, Return_fields, 1);
|
Return_type = make_type("Return", stmt_type, Return_fields, 1);
|
||||||
if (!Return_type) return 0;
|
if (!Return_type) return 0;
|
||||||
|
@ -1192,7 +1187,7 @@ static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena);
|
||||||
static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena);
|
static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena);
|
||||||
|
|
||||||
mod_ty
|
mod_ty
|
||||||
Module(asdl_seq * body, string docstring, PyArena *arena)
|
Module(asdl_seq * body, PyArena *arena)
|
||||||
{
|
{
|
||||||
mod_ty p;
|
mod_ty p;
|
||||||
p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
|
p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||||
|
@ -1200,7 +1195,6 @@ Module(asdl_seq * body, string docstring, PyArena *arena)
|
||||||
return NULL;
|
return NULL;
|
||||||
p->kind = Module_kind;
|
p->kind = Module_kind;
|
||||||
p->v.Module.body = body;
|
p->v.Module.body = body;
|
||||||
p->v.Module.docstring = docstring;
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1247,8 +1241,8 @@ Suite(asdl_seq * body, PyArena *arena)
|
||||||
|
|
||||||
stmt_ty
|
stmt_ty
|
||||||
FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
||||||
decorator_list, expr_ty returns, string docstring, int lineno, int
|
decorator_list, expr_ty returns, int lineno, int col_offset,
|
||||||
col_offset, PyArena *arena)
|
PyArena *arena)
|
||||||
{
|
{
|
||||||
stmt_ty p;
|
stmt_ty p;
|
||||||
if (!name) {
|
if (!name) {
|
||||||
|
@ -1270,7 +1264,6 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
||||||
p->v.FunctionDef.body = body;
|
p->v.FunctionDef.body = body;
|
||||||
p->v.FunctionDef.decorator_list = decorator_list;
|
p->v.FunctionDef.decorator_list = decorator_list;
|
||||||
p->v.FunctionDef.returns = returns;
|
p->v.FunctionDef.returns = returns;
|
||||||
p->v.FunctionDef.docstring = docstring;
|
|
||||||
p->lineno = lineno;
|
p->lineno = lineno;
|
||||||
p->col_offset = col_offset;
|
p->col_offset = col_offset;
|
||||||
return p;
|
return p;
|
||||||
|
@ -1278,8 +1271,8 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
||||||
|
|
||||||
stmt_ty
|
stmt_ty
|
||||||
AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
|
AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
|
||||||
* decorator_list, expr_ty returns, string docstring, int
|
* decorator_list, expr_ty returns, int lineno, int col_offset,
|
||||||
lineno, int col_offset, PyArena *arena)
|
PyArena *arena)
|
||||||
{
|
{
|
||||||
stmt_ty p;
|
stmt_ty p;
|
||||||
if (!name) {
|
if (!name) {
|
||||||
|
@ -1301,7 +1294,6 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
|
||||||
p->v.AsyncFunctionDef.body = body;
|
p->v.AsyncFunctionDef.body = body;
|
||||||
p->v.AsyncFunctionDef.decorator_list = decorator_list;
|
p->v.AsyncFunctionDef.decorator_list = decorator_list;
|
||||||
p->v.AsyncFunctionDef.returns = returns;
|
p->v.AsyncFunctionDef.returns = returns;
|
||||||
p->v.AsyncFunctionDef.docstring = docstring;
|
|
||||||
p->lineno = lineno;
|
p->lineno = lineno;
|
||||||
p->col_offset = col_offset;
|
p->col_offset = col_offset;
|
||||||
return p;
|
return p;
|
||||||
|
@ -1309,8 +1301,8 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
|
||||||
|
|
||||||
stmt_ty
|
stmt_ty
|
||||||
ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq *
|
ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq *
|
||||||
body, asdl_seq * decorator_list, string docstring, int lineno, int
|
body, asdl_seq * decorator_list, int lineno, int col_offset, PyArena
|
||||||
col_offset, PyArena *arena)
|
*arena)
|
||||||
{
|
{
|
||||||
stmt_ty p;
|
stmt_ty p;
|
||||||
if (!name) {
|
if (!name) {
|
||||||
|
@ -1327,7 +1319,6 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq *
|
||||||
p->v.ClassDef.keywords = keywords;
|
p->v.ClassDef.keywords = keywords;
|
||||||
p->v.ClassDef.body = body;
|
p->v.ClassDef.body = body;
|
||||||
p->v.ClassDef.decorator_list = decorator_list;
|
p->v.ClassDef.decorator_list = decorator_list;
|
||||||
p->v.ClassDef.docstring = docstring;
|
|
||||||
p->lineno = lineno;
|
p->lineno = lineno;
|
||||||
p->col_offset = col_offset;
|
p->col_offset = col_offset;
|
||||||
return p;
|
return p;
|
||||||
|
@ -2591,11 +2582,6 @@ ast2obj_mod(void* _o)
|
||||||
if (_PyObject_SetAttrId(result, &PyId_body, value) == -1)
|
if (_PyObject_SetAttrId(result, &PyId_body, value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = ast2obj_string(o->v.Module.docstring);
|
|
||||||
if (!value) goto failed;
|
|
||||||
if (_PyObject_SetAttrId(result, &PyId_docstring, value) == -1)
|
|
||||||
goto failed;
|
|
||||||
Py_DECREF(value);
|
|
||||||
break;
|
break;
|
||||||
case Interactive_kind:
|
case Interactive_kind:
|
||||||
result = PyType_GenericNew(Interactive_type, NULL, NULL);
|
result = PyType_GenericNew(Interactive_type, NULL, NULL);
|
||||||
|
@ -2670,11 +2656,6 @@ ast2obj_stmt(void* _o)
|
||||||
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = ast2obj_string(o->v.FunctionDef.docstring);
|
|
||||||
if (!value) goto failed;
|
|
||||||
if (_PyObject_SetAttrId(result, &PyId_docstring, value) == -1)
|
|
||||||
goto failed;
|
|
||||||
Py_DECREF(value);
|
|
||||||
break;
|
break;
|
||||||
case AsyncFunctionDef_kind:
|
case AsyncFunctionDef_kind:
|
||||||
result = PyType_GenericNew(AsyncFunctionDef_type, NULL, NULL);
|
result = PyType_GenericNew(AsyncFunctionDef_type, NULL, NULL);
|
||||||
|
@ -2705,11 +2686,6 @@ ast2obj_stmt(void* _o)
|
||||||
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = ast2obj_string(o->v.AsyncFunctionDef.docstring);
|
|
||||||
if (!value) goto failed;
|
|
||||||
if (_PyObject_SetAttrId(result, &PyId_docstring, value) == -1)
|
|
||||||
goto failed;
|
|
||||||
Py_DECREF(value);
|
|
||||||
break;
|
break;
|
||||||
case ClassDef_kind:
|
case ClassDef_kind:
|
||||||
result = PyType_GenericNew(ClassDef_type, NULL, NULL);
|
result = PyType_GenericNew(ClassDef_type, NULL, NULL);
|
||||||
|
@ -2739,11 +2715,6 @@ ast2obj_stmt(void* _o)
|
||||||
if (_PyObject_SetAttrId(result, &PyId_decorator_list, value) == -1)
|
if (_PyObject_SetAttrId(result, &PyId_decorator_list, value) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
value = ast2obj_string(o->v.ClassDef.docstring);
|
|
||||||
if (!value) goto failed;
|
|
||||||
if (_PyObject_SetAttrId(result, &PyId_docstring, value) == -1)
|
|
||||||
goto failed;
|
|
||||||
Py_DECREF(value);
|
|
||||||
break;
|
break;
|
||||||
case Return_kind:
|
case Return_kind:
|
||||||
result = PyType_GenericNew(Return_type, NULL, NULL);
|
result = PyType_GenericNew(Return_type, NULL, NULL);
|
||||||
|
@ -3984,7 +3955,6 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
|
||||||
}
|
}
|
||||||
if (isinstance) {
|
if (isinstance) {
|
||||||
asdl_seq* body;
|
asdl_seq* body;
|
||||||
string docstring;
|
|
||||||
|
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) {
|
if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -4016,20 +3986,7 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
|
||||||
}
|
}
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_docstring, &tmp) < 0) {
|
*out = Module(body, arena);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (tmp == NULL || tmp == Py_None) {
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
docstring = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int res;
|
|
||||||
res = obj2ast_string(tmp, &docstring, arena);
|
|
||||||
if (res != 0) goto failed;
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
}
|
|
||||||
*out = Module(body, docstring, arena);
|
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4195,7 +4152,6 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
asdl_seq* body;
|
asdl_seq* body;
|
||||||
asdl_seq* decorator_list;
|
asdl_seq* decorator_list;
|
||||||
expr_ty returns;
|
expr_ty returns;
|
||||||
string docstring;
|
|
||||||
|
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -4296,21 +4252,8 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
if (res != 0) goto failed;
|
if (res != 0) goto failed;
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_docstring, &tmp) < 0) {
|
*out = FunctionDef(name, args, body, decorator_list, returns, lineno,
|
||||||
return 1;
|
col_offset, arena);
|
||||||
}
|
|
||||||
if (tmp == NULL || tmp == Py_None) {
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
docstring = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int res;
|
|
||||||
res = obj2ast_string(tmp, &docstring, arena);
|
|
||||||
if (res != 0) goto failed;
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
}
|
|
||||||
*out = FunctionDef(name, args, body, decorator_list, returns,
|
|
||||||
docstring, lineno, col_offset, arena);
|
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4324,7 +4267,6 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
asdl_seq* body;
|
asdl_seq* body;
|
||||||
asdl_seq* decorator_list;
|
asdl_seq* decorator_list;
|
||||||
expr_ty returns;
|
expr_ty returns;
|
||||||
string docstring;
|
|
||||||
|
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -4425,21 +4367,8 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
if (res != 0) goto failed;
|
if (res != 0) goto failed;
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_docstring, &tmp) < 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (tmp == NULL || tmp == Py_None) {
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
docstring = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int res;
|
|
||||||
res = obj2ast_string(tmp, &docstring, arena);
|
|
||||||
if (res != 0) goto failed;
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
}
|
|
||||||
*out = AsyncFunctionDef(name, args, body, decorator_list, returns,
|
*out = AsyncFunctionDef(name, args, body, decorator_list, returns,
|
||||||
docstring, lineno, col_offset, arena);
|
lineno, col_offset, arena);
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4453,7 +4382,6 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
asdl_seq* keywords;
|
asdl_seq* keywords;
|
||||||
asdl_seq* body;
|
asdl_seq* body;
|
||||||
asdl_seq* decorator_list;
|
asdl_seq* decorator_list;
|
||||||
string docstring;
|
|
||||||
|
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -4588,21 +4516,8 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
||||||
}
|
}
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
if (_PyObject_LookupAttrId(obj, &PyId_docstring, &tmp) < 0) {
|
*out = ClassDef(name, bases, keywords, body, decorator_list, lineno,
|
||||||
return 1;
|
col_offset, arena);
|
||||||
}
|
|
||||||
if (tmp == NULL || tmp == Py_None) {
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
docstring = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int res;
|
|
||||||
res = obj2ast_string(tmp, &docstring, arena);
|
|
||||||
if (res != 0) goto failed;
|
|
||||||
Py_CLEAR(tmp);
|
|
||||||
}
|
|
||||||
*out = ClassDef(name, bases, keywords, body, decorator_list, docstring,
|
|
||||||
lineno, col_offset, arena);
|
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
87
Python/ast.c
87
Python/ast.c
|
@ -367,12 +367,9 @@ validate_assignlist(asdl_seq *targets, expr_context_ty ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
validate_body(asdl_seq *body, const char *owner, int allowempty)
|
validate_body(asdl_seq *body, const char *owner)
|
||||||
{
|
{
|
||||||
if (!allowempty && !validate_nonempty_seq(body, "body", owner)) {
|
return validate_nonempty_seq(body, "body", owner) && validate_stmts(body);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return validate_stmts(body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -381,15 +378,13 @@ validate_stmt(stmt_ty stmt)
|
||||||
int i;
|
int i;
|
||||||
switch (stmt->kind) {
|
switch (stmt->kind) {
|
||||||
case FunctionDef_kind:
|
case FunctionDef_kind:
|
||||||
return validate_body(stmt->v.FunctionDef.body, "FunctionDef",
|
return validate_body(stmt->v.FunctionDef.body, "FunctionDef") &&
|
||||||
stmt->v.FunctionDef.docstring != NULL) &&
|
|
||||||
validate_arguments(stmt->v.FunctionDef.args) &&
|
validate_arguments(stmt->v.FunctionDef.args) &&
|
||||||
validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) &&
|
validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) &&
|
||||||
(!stmt->v.FunctionDef.returns ||
|
(!stmt->v.FunctionDef.returns ||
|
||||||
validate_expr(stmt->v.FunctionDef.returns, Load));
|
validate_expr(stmt->v.FunctionDef.returns, Load));
|
||||||
case ClassDef_kind:
|
case ClassDef_kind:
|
||||||
return validate_body(stmt->v.ClassDef.body, "ClassDef",
|
return validate_body(stmt->v.ClassDef.body, "ClassDef") &&
|
||||||
stmt->v.ClassDef.docstring != NULL) &&
|
|
||||||
validate_exprs(stmt->v.ClassDef.bases, Load, 0) &&
|
validate_exprs(stmt->v.ClassDef.bases, Load, 0) &&
|
||||||
validate_keywords(stmt->v.ClassDef.keywords) &&
|
validate_keywords(stmt->v.ClassDef.keywords) &&
|
||||||
validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0);
|
validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0);
|
||||||
|
@ -417,20 +412,20 @@ validate_stmt(stmt_ty stmt)
|
||||||
case For_kind:
|
case For_kind:
|
||||||
return validate_expr(stmt->v.For.target, Store) &&
|
return validate_expr(stmt->v.For.target, Store) &&
|
||||||
validate_expr(stmt->v.For.iter, Load) &&
|
validate_expr(stmt->v.For.iter, Load) &&
|
||||||
validate_body(stmt->v.For.body, "For", 0) &&
|
validate_body(stmt->v.For.body, "For") &&
|
||||||
validate_stmts(stmt->v.For.orelse);
|
validate_stmts(stmt->v.For.orelse);
|
||||||
case AsyncFor_kind:
|
case AsyncFor_kind:
|
||||||
return validate_expr(stmt->v.AsyncFor.target, Store) &&
|
return validate_expr(stmt->v.AsyncFor.target, Store) &&
|
||||||
validate_expr(stmt->v.AsyncFor.iter, Load) &&
|
validate_expr(stmt->v.AsyncFor.iter, Load) &&
|
||||||
validate_body(stmt->v.AsyncFor.body, "AsyncFor", 0) &&
|
validate_body(stmt->v.AsyncFor.body, "AsyncFor") &&
|
||||||
validate_stmts(stmt->v.AsyncFor.orelse);
|
validate_stmts(stmt->v.AsyncFor.orelse);
|
||||||
case While_kind:
|
case While_kind:
|
||||||
return validate_expr(stmt->v.While.test, Load) &&
|
return validate_expr(stmt->v.While.test, Load) &&
|
||||||
validate_body(stmt->v.While.body, "While", 0) &&
|
validate_body(stmt->v.While.body, "While") &&
|
||||||
validate_stmts(stmt->v.While.orelse);
|
validate_stmts(stmt->v.While.orelse);
|
||||||
case If_kind:
|
case If_kind:
|
||||||
return validate_expr(stmt->v.If.test, Load) &&
|
return validate_expr(stmt->v.If.test, Load) &&
|
||||||
validate_body(stmt->v.If.body, "If", 0) &&
|
validate_body(stmt->v.If.body, "If") &&
|
||||||
validate_stmts(stmt->v.If.orelse);
|
validate_stmts(stmt->v.If.orelse);
|
||||||
case With_kind:
|
case With_kind:
|
||||||
if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
|
if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
|
||||||
|
@ -441,7 +436,7 @@ validate_stmt(stmt_ty stmt)
|
||||||
(item->optional_vars && !validate_expr(item->optional_vars, Store)))
|
(item->optional_vars && !validate_expr(item->optional_vars, Store)))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return validate_body(stmt->v.With.body, "With", 0);
|
return validate_body(stmt->v.With.body, "With");
|
||||||
case AsyncWith_kind:
|
case AsyncWith_kind:
|
||||||
if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
|
if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -451,7 +446,7 @@ validate_stmt(stmt_ty stmt)
|
||||||
(item->optional_vars && !validate_expr(item->optional_vars, Store)))
|
(item->optional_vars && !validate_expr(item->optional_vars, Store)))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return validate_body(stmt->v.AsyncWith.body, "AsyncWith", 0);
|
return validate_body(stmt->v.AsyncWith.body, "AsyncWith");
|
||||||
case Raise_kind:
|
case Raise_kind:
|
||||||
if (stmt->v.Raise.exc) {
|
if (stmt->v.Raise.exc) {
|
||||||
return validate_expr(stmt->v.Raise.exc, Load) &&
|
return validate_expr(stmt->v.Raise.exc, Load) &&
|
||||||
|
@ -463,7 +458,7 @@ validate_stmt(stmt_ty stmt)
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
case Try_kind:
|
case Try_kind:
|
||||||
if (!validate_body(stmt->v.Try.body, "Try", 0))
|
if (!validate_body(stmt->v.Try.body, "Try"))
|
||||||
return 0;
|
return 0;
|
||||||
if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
|
if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
|
||||||
!asdl_seq_LEN(stmt->v.Try.finalbody)) {
|
!asdl_seq_LEN(stmt->v.Try.finalbody)) {
|
||||||
|
@ -479,7 +474,7 @@ validate_stmt(stmt_ty stmt)
|
||||||
excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
|
excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
|
||||||
if ((handler->v.ExceptHandler.type &&
|
if ((handler->v.ExceptHandler.type &&
|
||||||
!validate_expr(handler->v.ExceptHandler.type, Load)) ||
|
!validate_expr(handler->v.ExceptHandler.type, Load)) ||
|
||||||
!validate_body(handler->v.ExceptHandler.body, "ExceptHandler", 0))
|
!validate_body(handler->v.ExceptHandler.body, "ExceptHandler"))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
|
return (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
|
||||||
|
@ -504,8 +499,7 @@ validate_stmt(stmt_ty stmt)
|
||||||
case Expr_kind:
|
case Expr_kind:
|
||||||
return validate_expr(stmt->v.Expr.value, Load);
|
return validate_expr(stmt->v.Expr.value, Load);
|
||||||
case AsyncFunctionDef_kind:
|
case AsyncFunctionDef_kind:
|
||||||
return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef",
|
return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
|
||||||
stmt->v.AsyncFunctionDef.docstring != NULL) &&
|
|
||||||
validate_arguments(stmt->v.AsyncFunctionDef.args) &&
|
validate_arguments(stmt->v.AsyncFunctionDef.args) &&
|
||||||
validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
|
validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
|
||||||
(!stmt->v.AsyncFunctionDef.returns ||
|
(!stmt->v.AsyncFunctionDef.returns ||
|
||||||
|
@ -600,9 +594,7 @@ struct compiling {
|
||||||
static asdl_seq *seq_for_testlist(struct compiling *, const node *);
|
static asdl_seq *seq_for_testlist(struct compiling *, const node *);
|
||||||
static expr_ty ast_for_expr(struct compiling *, const node *);
|
static expr_ty ast_for_expr(struct compiling *, const node *);
|
||||||
static stmt_ty ast_for_stmt(struct compiling *, const node *);
|
static stmt_ty ast_for_stmt(struct compiling *, const node *);
|
||||||
static asdl_seq *ast_for_body(struct compiling *c, const node *n,
|
static asdl_seq *ast_for_suite(struct compiling *c, const node *n);
|
||||||
string *docstring);
|
|
||||||
static string docstring_from_stmts(asdl_seq *stmts);
|
|
||||||
static asdl_seq *ast_for_exprlist(struct compiling *, const node *,
|
static asdl_seq *ast_for_exprlist(struct compiling *, const node *,
|
||||||
expr_context_ty);
|
expr_context_ty);
|
||||||
static expr_ty ast_for_testlist(struct compiling *, const node *);
|
static expr_ty ast_for_testlist(struct compiling *, const node *);
|
||||||
|
@ -820,7 +812,7 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = Module(stmts, docstring_from_stmts(stmts), arena);
|
res = Module(stmts, arena);
|
||||||
break;
|
break;
|
||||||
case eval_input: {
|
case eval_input: {
|
||||||
expr_ty testlist_ast;
|
expr_ty testlist_ast;
|
||||||
|
@ -1585,7 +1577,6 @@ ast_for_funcdef_impl(struct compiling *c, const node *n,
|
||||||
arguments_ty args;
|
arguments_ty args;
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
expr_ty returns = NULL;
|
expr_ty returns = NULL;
|
||||||
string docstring;
|
|
||||||
int name_i = 1;
|
int name_i = 1;
|
||||||
|
|
||||||
REQ(n, funcdef);
|
REQ(n, funcdef);
|
||||||
|
@ -1604,18 +1595,16 @@ ast_for_funcdef_impl(struct compiling *c, const node *n,
|
||||||
return NULL;
|
return NULL;
|
||||||
name_i += 2;
|
name_i += 2;
|
||||||
}
|
}
|
||||||
body = ast_for_body(c, CHILD(n, name_i + 3), &docstring);
|
body = ast_for_suite(c, CHILD(n, name_i + 3));
|
||||||
if (!body)
|
if (!body)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (is_async)
|
if (is_async)
|
||||||
return AsyncFunctionDef(name, args, body, decorator_seq, returns,
|
return AsyncFunctionDef(name, args, body, decorator_seq, returns,
|
||||||
docstring, LINENO(n),
|
LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
n->n_col_offset, c->c_arena);
|
|
||||||
else
|
else
|
||||||
return FunctionDef(name, args, body, decorator_seq, returns,
|
return FunctionDef(name, args, body, decorator_seq, returns,
|
||||||
docstring, LINENO(n),
|
LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
n->n_col_offset, c->c_arena);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static stmt_ty
|
static stmt_ty
|
||||||
|
@ -3528,32 +3517,6 @@ ast_for_suite(struct compiling *c, const node *n)
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string
|
|
||||||
docstring_from_stmts(asdl_seq *stmts)
|
|
||||||
{
|
|
||||||
if (stmts && stmts->size) {
|
|
||||||
stmt_ty s = (stmt_ty)asdl_seq_GET(stmts, 0);
|
|
||||||
/* If first statement is a literal string, it's the doc string. */
|
|
||||||
if (s->kind == Expr_kind && s->v.Expr.value->kind == Str_kind) {
|
|
||||||
string doc = s->v.Expr.value->v.Str.s;
|
|
||||||
/* not very efficient, but simple */
|
|
||||||
memmove(&asdl_seq_GET(stmts, 0), &asdl_seq_GET(stmts, 1),
|
|
||||||
(stmts->size - 1) * sizeof(void*));
|
|
||||||
stmts->size--;
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static asdl_seq *
|
|
||||||
ast_for_body(struct compiling *c, const node *n, string *docstring)
|
|
||||||
{
|
|
||||||
asdl_seq *stmts = ast_for_suite(c, n);
|
|
||||||
*docstring = docstring_from_stmts(stmts);
|
|
||||||
return stmts;
|
|
||||||
}
|
|
||||||
|
|
||||||
static stmt_ty
|
static stmt_ty
|
||||||
ast_for_if_stmt(struct compiling *c, const node *n)
|
ast_for_if_stmt(struct compiling *c, const node *n)
|
||||||
{
|
{
|
||||||
|
@ -3938,13 +3901,12 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
||||||
/* classdef: 'class' NAME ['(' arglist ')'] ':' suite */
|
/* classdef: 'class' NAME ['(' arglist ')'] ':' suite */
|
||||||
PyObject *classname;
|
PyObject *classname;
|
||||||
asdl_seq *s;
|
asdl_seq *s;
|
||||||
string docstring;
|
|
||||||
expr_ty call;
|
expr_ty call;
|
||||||
|
|
||||||
REQ(n, classdef);
|
REQ(n, classdef);
|
||||||
|
|
||||||
if (NCH(n) == 4) { /* class NAME ':' suite */
|
if (NCH(n) == 4) { /* class NAME ':' suite */
|
||||||
s = ast_for_body(c, CHILD(n, 3), &docstring);
|
s = ast_for_suite(c, CHILD(n, 3));
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
classname = NEW_IDENTIFIER(CHILD(n, 1));
|
classname = NEW_IDENTIFIER(CHILD(n, 1));
|
||||||
|
@ -3952,12 +3914,12 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (forbidden_name(c, classname, CHILD(n, 3), 0))
|
if (forbidden_name(c, classname, CHILD(n, 3), 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
return ClassDef(classname, NULL, NULL, s, decorator_seq, docstring,
|
return ClassDef(classname, NULL, NULL, s, decorator_seq,
|
||||||
LINENO(n), n->n_col_offset, c->c_arena);
|
LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */
|
if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */
|
||||||
s = ast_for_body(c, CHILD(n, 5), &docstring);
|
s = ast_for_suite(c, CHILD(n, 5));
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
classname = NEW_IDENTIFIER(CHILD(n, 1));
|
classname = NEW_IDENTIFIER(CHILD(n, 1));
|
||||||
|
@ -3965,7 +3927,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (forbidden_name(c, classname, CHILD(n, 3), 0))
|
if (forbidden_name(c, classname, CHILD(n, 3), 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
return ClassDef(classname, NULL, NULL, s, decorator_seq, docstring,
|
return ClassDef(classname, NULL, NULL, s, decorator_seq,
|
||||||
LINENO(n), n->n_col_offset, c->c_arena);
|
LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3982,7 +3944,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
||||||
if (!call)
|
if (!call)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
s = ast_for_body(c, CHILD(n, 6), &docstring);
|
s = ast_for_suite(c, CHILD(n, 6));
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
classname = NEW_IDENTIFIER(CHILD(n, 1));
|
classname = NEW_IDENTIFIER(CHILD(n, 1));
|
||||||
|
@ -3992,8 +3954,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s,
|
return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s,
|
||||||
decorator_seq, docstring, LINENO(n), n->n_col_offset,
|
decorator_seq, LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
c->c_arena);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static stmt_ty
|
static stmt_ty
|
||||||
|
|
|
@ -467,12 +467,51 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int opti
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
isdocstring(stmt_ty s)
|
||||||
|
{
|
||||||
|
if (s->kind != Expr_kind)
|
||||||
|
return 0;
|
||||||
|
if (s->v.Expr.value->kind == Str_kind)
|
||||||
|
return 1;
|
||||||
|
if (s->v.Expr.value->kind == Constant_kind)
|
||||||
|
return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
astfold_body(asdl_seq *stmts, PyArena *ctx_, int optimize_)
|
||||||
|
{
|
||||||
|
if (!asdl_seq_LEN(stmts)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int docstring = isdocstring((stmt_ty)asdl_seq_GET(stmts, 0));
|
||||||
|
CALL_SEQ(astfold_stmt, stmt_ty, stmts);
|
||||||
|
if (docstring) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
|
||||||
|
if (isdocstring(st)) {
|
||||||
|
asdl_seq *values = _Py_asdl_seq_new(1, ctx_);
|
||||||
|
if (!values) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
asdl_seq_SET(values, 0, st->v.Expr.value);
|
||||||
|
expr_ty expr = _Py_JoinedStr(values, st->lineno, st->col_offset, ctx_);
|
||||||
|
if (!expr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
st->v.Expr.value = expr;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
astfold_mod(mod_ty node_, PyArena *ctx_, int optimize_)
|
astfold_mod(mod_ty node_, PyArena *ctx_, int optimize_)
|
||||||
{
|
{
|
||||||
switch (node_->kind) {
|
switch (node_->kind) {
|
||||||
case Module_kind:
|
case Module_kind:
|
||||||
CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Module.body);
|
CALL(astfold_body, asdl_seq, node_->v.Module.body);
|
||||||
break;
|
break;
|
||||||
case Interactive_kind:
|
case Interactive_kind:
|
||||||
CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Interactive.body);
|
CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Interactive.body);
|
||||||
|
@ -657,20 +696,20 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, int optimize_)
|
||||||
switch (node_->kind) {
|
switch (node_->kind) {
|
||||||
case FunctionDef_kind:
|
case FunctionDef_kind:
|
||||||
CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
|
CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
|
||||||
CALL_SEQ(astfold_stmt, stmt_ty, node_->v.FunctionDef.body);
|
CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body);
|
||||||
CALL_SEQ(astfold_expr, expr_ty, node_->v.FunctionDef.decorator_list);
|
CALL_SEQ(astfold_expr, expr_ty, node_->v.FunctionDef.decorator_list);
|
||||||
CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns);
|
CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns);
|
||||||
break;
|
break;
|
||||||
case AsyncFunctionDef_kind:
|
case AsyncFunctionDef_kind:
|
||||||
CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
|
CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
|
||||||
CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFunctionDef.body);
|
CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body);
|
||||||
CALL_SEQ(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.decorator_list);
|
CALL_SEQ(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.decorator_list);
|
||||||
CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns);
|
CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns);
|
||||||
break;
|
break;
|
||||||
case ClassDef_kind:
|
case ClassDef_kind:
|
||||||
CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.bases);
|
CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.bases);
|
||||||
CALL_SEQ(astfold_keyword, keyword_ty, node_->v.ClassDef.keywords);
|
CALL_SEQ(astfold_keyword, keyword_ty, node_->v.ClassDef.keywords);
|
||||||
CALL_SEQ(astfold_stmt, stmt_ty, node_->v.ClassDef.body);
|
CALL(astfold_body, asdl_seq, node_->v.ClassDef.body);
|
||||||
CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.decorator_list);
|
CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.decorator_list);
|
||||||
break;
|
break;
|
||||||
case Return_kind:
|
case Return_kind:
|
||||||
|
|
|
@ -1392,6 +1392,18 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compiler_isdocstring(stmt_ty s)
|
||||||
|
{
|
||||||
|
if (s->kind != Expr_kind)
|
||||||
|
return 0;
|
||||||
|
if (s->v.Expr.value->kind == Str_kind)
|
||||||
|
return 1;
|
||||||
|
if (s->v.Expr.value->kind == Constant_kind)
|
||||||
|
return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_const(expr_ty e)
|
is_const(expr_ty e)
|
||||||
{
|
{
|
||||||
|
@ -1587,27 +1599,37 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
|
||||||
and for annotations. */
|
and for annotations. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compiler_body(struct compiler *c, asdl_seq *stmts, string docstring)
|
compiler_body(struct compiler *c, asdl_seq *stmts)
|
||||||
{
|
{
|
||||||
|
int i = 0;
|
||||||
|
stmt_ty st;
|
||||||
|
|
||||||
/* Set current line number to the line number of first statement.
|
/* Set current line number to the line number of first statement.
|
||||||
This way line number for SETUP_ANNOTATIONS will always
|
This way line number for SETUP_ANNOTATIONS will always
|
||||||
coincide with the line number of first "real" statement in module.
|
coincide with the line number of first "real" statement in module.
|
||||||
If body is empy, then lineno will be set later in assemble. */
|
If body is empy, then lineno will be set later in assemble. */
|
||||||
if (c->u->u_scope_type == COMPILER_SCOPE_MODULE &&
|
if (c->u->u_scope_type == COMPILER_SCOPE_MODULE &&
|
||||||
!c->u->u_lineno && asdl_seq_LEN(stmts)) {
|
!c->u->u_lineno && asdl_seq_LEN(stmts)) {
|
||||||
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
|
st = (stmt_ty)asdl_seq_GET(stmts, 0);
|
||||||
c->u->u_lineno = st->lineno;
|
c->u->u_lineno = st->lineno;
|
||||||
}
|
}
|
||||||
/* Every annotated class and module should have __annotations__. */
|
/* Every annotated class and module should have __annotations__. */
|
||||||
if (find_ann(stmts)) {
|
if (find_ann(stmts)) {
|
||||||
ADDOP(c, SETUP_ANNOTATIONS);
|
ADDOP(c, SETUP_ANNOTATIONS);
|
||||||
}
|
}
|
||||||
|
if (!asdl_seq_LEN(stmts))
|
||||||
|
return 1;
|
||||||
|
st = (stmt_ty)asdl_seq_GET(stmts, 0);
|
||||||
/* if not -OO mode, set docstring */
|
/* if not -OO mode, set docstring */
|
||||||
if (c->c_optimize < 2 && docstring) {
|
if (compiler_isdocstring(st) && c->c_optimize < 2) {
|
||||||
ADDOP_LOAD_CONST(c, docstring);
|
/* don't generate docstrings if -OO */
|
||||||
ADDOP_NAME(c, STORE_NAME, __doc__, names);
|
i = 1;
|
||||||
|
VISIT(c, expr, st->v.Expr.value);
|
||||||
|
if (!compiler_nameop(c, __doc__, Store))
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
VISIT_SEQ(c, stmt, stmts);
|
for (; i < asdl_seq_LEN(stmts); i++)
|
||||||
|
VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1627,7 +1649,7 @@ compiler_mod(struct compiler *c, mod_ty mod)
|
||||||
return NULL;
|
return NULL;
|
||||||
switch (mod->kind) {
|
switch (mod->kind) {
|
||||||
case Module_kind:
|
case Module_kind:
|
||||||
if (!compiler_body(c, mod->v.Module.body, mod->v.Module.docstring)) {
|
if (!compiler_body(c, mod->v.Module.body)) {
|
||||||
compiler_exit_scope(c);
|
compiler_exit_scope(c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1957,13 +1979,15 @@ static int
|
||||||
compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
||||||
{
|
{
|
||||||
PyCodeObject *co;
|
PyCodeObject *co;
|
||||||
PyObject *qualname, *docstring = Py_None;
|
PyObject *qualname, *first_const = Py_None;
|
||||||
arguments_ty args;
|
arguments_ty args;
|
||||||
expr_ty returns;
|
expr_ty returns;
|
||||||
identifier name;
|
identifier name;
|
||||||
asdl_seq* decos;
|
asdl_seq* decos;
|
||||||
asdl_seq *body;
|
asdl_seq *body;
|
||||||
|
stmt_ty st;
|
||||||
Py_ssize_t i, funcflags;
|
Py_ssize_t i, funcflags;
|
||||||
|
int docstring;
|
||||||
int annotations;
|
int annotations;
|
||||||
int scope_type;
|
int scope_type;
|
||||||
|
|
||||||
|
@ -2010,16 +2034,21 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if not -OO mode, add docstring */
|
/* if not -OO mode, add docstring */
|
||||||
if (c->c_optimize < 2 && s->v.FunctionDef.docstring)
|
st = (stmt_ty)asdl_seq_GET(body, 0);
|
||||||
docstring = s->v.FunctionDef.docstring;
|
docstring = compiler_isdocstring(st);
|
||||||
if (compiler_add_const(c, docstring) < 0) {
|
if (docstring && c->c_optimize < 2) {
|
||||||
|
if (st->v.Expr.value->kind == Constant_kind)
|
||||||
|
first_const = st->v.Expr.value->v.Constant.value;
|
||||||
|
else
|
||||||
|
first_const = st->v.Expr.value->v.Str.s;
|
||||||
|
}
|
||||||
|
if (compiler_add_const(c, first_const) < 0) {
|
||||||
compiler_exit_scope(c);
|
compiler_exit_scope(c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->u->u_argcount = asdl_seq_LEN(args->args);
|
c->u->u_argcount = asdl_seq_LEN(args->args);
|
||||||
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
|
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
|
||||||
/* if there was a docstring, we need to skip the first statement */
|
|
||||||
VISIT_SEQ_IN_SCOPE(c, stmt, body);
|
VISIT_SEQ_IN_SCOPE(c, stmt, body);
|
||||||
co = assemble(c, 1);
|
co = assemble(c, 1);
|
||||||
qualname = c->u->u_qualname;
|
qualname = c->u->u_qualname;
|
||||||
|
@ -2101,7 +2130,7 @@ compiler_class(struct compiler *c, stmt_ty s)
|
||||||
}
|
}
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
/* compile the body proper */
|
/* compile the body proper */
|
||||||
if (!compiler_body(c, s->v.ClassDef.body, s->v.ClassDef.docstring)) {
|
if (!compiler_body(c, s->v.ClassDef.body)) {
|
||||||
compiler_exit_scope(c);
|
compiler_exit_scope(c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ static int
|
||||||
future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
||||||
{
|
{
|
||||||
int i, done = 0, prev_line = 0;
|
int i, done = 0, prev_line = 0;
|
||||||
|
stmt_ty first;
|
||||||
|
|
||||||
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
|
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -78,7 +79,15 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
||||||
but is preceded by a regular import.
|
but is preceded by a regular import.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
|
i = 0;
|
||||||
|
first = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||||
|
if (first->kind == Expr_kind
|
||||||
|
&& (first->v.Expr.value->kind == Str_kind
|
||||||
|
|| (first->v.Expr.value->kind == Constant_kind
|
||||||
|
&& PyUnicode_CheckExact(first->v.Expr.value->v.Constant.value))))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
for (; i < asdl_seq_LEN(mod->v.Module.body); i++) {
|
||||||
stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||||
|
|
||||||
if (done && s->lineno > prev_line)
|
if (done && s->lineno > prev_line)
|
||||||
|
|
3211
Python/importlib.h
3211
Python/importlib.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -71,8 +71,6 @@ class Unparser:
|
||||||
########################################################
|
########################################################
|
||||||
|
|
||||||
def _Module(self, tree):
|
def _Module(self, tree):
|
||||||
if tree.docstring is not None:
|
|
||||||
self.fill(repr(tree.docstring))
|
|
||||||
for stmt in tree.body:
|
for stmt in tree.body:
|
||||||
self.dispatch(stmt)
|
self.dispatch(stmt)
|
||||||
|
|
||||||
|
@ -237,8 +235,6 @@ class Unparser:
|
||||||
self.write(")")
|
self.write(")")
|
||||||
|
|
||||||
self.enter()
|
self.enter()
|
||||||
if t.docstring is not None:
|
|
||||||
self.fill(repr(t.docstring))
|
|
||||||
self.dispatch(t.body)
|
self.dispatch(t.body)
|
||||||
self.leave()
|
self.leave()
|
||||||
|
|
||||||
|
@ -261,8 +257,6 @@ class Unparser:
|
||||||
self.write(" -> ")
|
self.write(" -> ")
|
||||||
self.dispatch(t.returns)
|
self.dispatch(t.returns)
|
||||||
self.enter()
|
self.enter()
|
||||||
if t.docstring is not None:
|
|
||||||
self.fill(repr(t.docstring))
|
|
||||||
self.dispatch(t.body)
|
self.dispatch(t.body)
|
||||||
self.leave()
|
self.leave()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue