diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-05-29 09:04:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-29 09:04:55 (GMT) |
commit | 73cbe7a01a22d02dbe1ec841e8779c775cad3d08 (patch) | |
tree | 0c39a8adb1cebdfc95cc991223c6c278fb13100a /Python/ast.c | |
parent | 2179022d94937d7b0600b0dc192ca6fa5f53d830 (diff) | |
download | cpython-73cbe7a01a22d02dbe1ec841e8779c775cad3d08.zip cpython-73cbe7a01a22d02dbe1ec841e8779c775cad3d08.tar.gz cpython-73cbe7a01a22d02dbe1ec841e8779c775cad3d08.tar.bz2 |
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>
Diffstat (limited to 'Python/ast.c')
-rw-r--r-- | Python/ast.c | 87 |
1 files changed, 24 insertions, 63 deletions
diff --git a/Python/ast.c b/Python/ast.c index 03a489a..43bd786 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -367,12 +367,9 @@ validate_assignlist(asdl_seq *targets, expr_context_ty ctx) } 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 0; - } - return validate_stmts(body); + return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); } static int @@ -381,15 +378,13 @@ validate_stmt(stmt_ty stmt) int i; switch (stmt->kind) { case FunctionDef_kind: - return validate_body(stmt->v.FunctionDef.body, "FunctionDef", - stmt->v.FunctionDef.docstring != NULL) && + return validate_body(stmt->v.FunctionDef.body, "FunctionDef") && validate_arguments(stmt->v.FunctionDef.args) && validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) && (!stmt->v.FunctionDef.returns || validate_expr(stmt->v.FunctionDef.returns, Load)); case ClassDef_kind: - return validate_body(stmt->v.ClassDef.body, "ClassDef", - stmt->v.ClassDef.docstring != NULL) && + return validate_body(stmt->v.ClassDef.body, "ClassDef") && validate_exprs(stmt->v.ClassDef.bases, Load, 0) && validate_keywords(stmt->v.ClassDef.keywords) && validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0); @@ -417,20 +412,20 @@ validate_stmt(stmt_ty stmt) case For_kind: return validate_expr(stmt->v.For.target, Store) && 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); case AsyncFor_kind: return validate_expr(stmt->v.AsyncFor.target, Store) && 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); case While_kind: 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); case If_kind: 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); case With_kind: 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))) return 0; } - return validate_body(stmt->v.With.body, "With", 0); + return validate_body(stmt->v.With.body, "With"); case AsyncWith_kind: if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith")) return 0; @@ -451,7 +446,7 @@ validate_stmt(stmt_ty stmt) (item->optional_vars && !validate_expr(item->optional_vars, Store))) return 0; } - return validate_body(stmt->v.AsyncWith.body, "AsyncWith", 0); + return validate_body(stmt->v.AsyncWith.body, "AsyncWith"); case Raise_kind: if (stmt->v.Raise.exc) { return validate_expr(stmt->v.Raise.exc, Load) && @@ -463,7 +458,7 @@ validate_stmt(stmt_ty stmt) } return 1; case Try_kind: - if (!validate_body(stmt->v.Try.body, "Try", 0)) + if (!validate_body(stmt->v.Try.body, "Try")) return 0; if (!asdl_seq_LEN(stmt->v.Try.handlers) && !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); if ((handler->v.ExceptHandler.type && !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 (!asdl_seq_LEN(stmt->v.Try.finalbody) || @@ -504,8 +499,7 @@ validate_stmt(stmt_ty stmt) case Expr_kind: return validate_expr(stmt->v.Expr.value, Load); case AsyncFunctionDef_kind: - return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef", - stmt->v.AsyncFunctionDef.docstring != NULL) && + return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && validate_arguments(stmt->v.AsyncFunctionDef.args) && validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && (!stmt->v.AsyncFunctionDef.returns || @@ -600,9 +594,7 @@ struct compiling { static asdl_seq *seq_for_testlist(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 asdl_seq *ast_for_body(struct compiling *c, const node *n, - string *docstring); -static string docstring_from_stmts(asdl_seq *stmts); +static asdl_seq *ast_for_suite(struct compiling *c, const node *n); static asdl_seq *ast_for_exprlist(struct compiling *, const node *, expr_context_ty); 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; case eval_input: { expr_ty testlist_ast; @@ -1585,7 +1577,6 @@ ast_for_funcdef_impl(struct compiling *c, const node *n, arguments_ty args; asdl_seq *body; expr_ty returns = NULL; - string docstring; int name_i = 1; REQ(n, funcdef); @@ -1604,18 +1595,16 @@ ast_for_funcdef_impl(struct compiling *c, const node *n, return NULL; 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) return NULL; if (is_async) return AsyncFunctionDef(name, args, body, decorator_seq, returns, - docstring, LINENO(n), - n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, c->c_arena); else return FunctionDef(name, args, body, decorator_seq, returns, - docstring, LINENO(n), - n->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, c->c_arena); } static stmt_ty @@ -3528,32 +3517,6 @@ ast_for_suite(struct compiling *c, const node *n) 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 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 */ PyObject *classname; asdl_seq *s; - string docstring; expr_ty call; REQ(n, classdef); 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) return NULL; 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; if (forbidden_name(c, classname, CHILD(n, 3), 0)) 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); } 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) return NULL; 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; if (forbidden_name(c, classname, CHILD(n, 3), 0)) 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); } @@ -3982,7 +3944,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) if (!call) return NULL; } - s = ast_for_body(c, CHILD(n, 6), &docstring); + s = ast_for_suite(c, CHILD(n, 6)); if (!s) return NULL; 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 ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s, - decorator_seq, docstring, LINENO(n), n->n_col_offset, - c->c_arena); + decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); } static stmt_ty |