Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 143ce5c

Browse files
bpo-33691: Add _PyAST_GetDocString(). (GH-7236)
1 parent e9537ad commit 143ce5c

5 files changed

Lines changed: 48 additions & 58 deletions

File tree

Include/ast.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ PyAPI_FUNC(mod_ty) PyAST_FromNodeObject(
2121
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
2222
PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty);
2323

24+
/* Return the borrowed reference to the first literal string in the
25+
sequence of statemnts or NULL if it doesn't start from a literal string.
26+
Doesn't set exception. */
27+
PyAPI_FUNC(PyObject *) _PyAST_GetDocString(asdl_seq *);
28+
2429
#endif /* !Py_LIMITED_API */
2530

2631
#ifdef __cplusplus

Python/ast.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5260,3 +5260,23 @@ parsestrplus(struct compiling *c, const node *n)
52605260
FstringParser_Dealloc(&state);
52615261
return NULL;
52625262
}
5263+
5264+
PyObject *
5265+
_PyAST_GetDocString(asdl_seq *body)
5266+
{
5267+
if (!asdl_seq_LEN(body)) {
5268+
return NULL;
5269+
}
5270+
stmt_ty st = (stmt_ty)asdl_seq_GET(body, 0);
5271+
if (st->kind != Expr_kind) {
5272+
return NULL;
5273+
}
5274+
expr_ty e = st->v.Expr.value;
5275+
if (e->kind == Str_kind) {
5276+
return e->v.Str.s;
5277+
}
5278+
if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
5279+
return e->v.Constant.value;
5280+
}
5281+
return NULL;
5282+
}

Python/ast_opt.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* AST Optimizer */
22
#include "Python.h"
33
#include "Python-ast.h"
4+
#include "node.h"
5+
#include "ast.h"
46

57

68
/* TODO: is_const and get_const_value are copied from Python/compile.c.
@@ -467,37 +469,19 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int opti
467469
} \
468470
}
469471

470-
static int
471-
isdocstring(stmt_ty s)
472-
{
473-
if (s->kind != Expr_kind)
474-
return 0;
475-
if (s->v.Expr.value->kind == Str_kind)
476-
return 1;
477-
if (s->v.Expr.value->kind == Constant_kind)
478-
return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value);
479-
return 0;
480-
}
481-
482472
static int
483473
astfold_body(asdl_seq *stmts, PyArena *ctx_, int optimize_)
484474
{
485-
if (!asdl_seq_LEN(stmts)) {
486-
return 1;
487-
}
488-
int docstring = isdocstring((stmt_ty)asdl_seq_GET(stmts, 0));
475+
int docstring = _PyAST_GetDocString(stmts) != NULL;
489476
CALL_SEQ(astfold_stmt, stmt_ty, stmts);
490-
if (docstring) {
491-
return 1;
492-
}
493-
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
494-
if (isdocstring(st)) {
477+
if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
478+
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
495479
asdl_seq *values = _Py_asdl_seq_new(1, ctx_);
496480
if (!values) {
497481
return 0;
498482
}
499483
asdl_seq_SET(values, 0, st->v.Expr.value);
500-
expr_ty expr = _Py_JoinedStr(values, st->lineno, st->col_offset, ctx_);
484+
expr_ty expr = JoinedStr(values, st->lineno, st->col_offset, ctx_);
501485
if (!expr) {
502486
return 0;
503487
}

Python/compile.c

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,18 +1392,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
13921392
} \
13931393
}
13941394

1395-
static int
1396-
compiler_isdocstring(stmt_ty s)
1397-
{
1398-
if (s->kind != Expr_kind)
1399-
return 0;
1400-
if (s->v.Expr.value->kind == Str_kind)
1401-
return 1;
1402-
if (s->v.Expr.value->kind == Constant_kind)
1403-
return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value);
1404-
return 0;
1405-
}
1406-
14071395
static int
14081396
is_const(expr_ty e)
14091397
{
@@ -1603,6 +1591,7 @@ compiler_body(struct compiler *c, asdl_seq *stmts)
16031591
{
16041592
int i = 0;
16051593
stmt_ty st;
1594+
PyObject *docstring;
16061595

16071596
/* Set current line number to the line number of first statement.
16081597
This way line number for SETUP_ANNOTATIONS will always
@@ -1619,14 +1608,17 @@ compiler_body(struct compiler *c, asdl_seq *stmts)
16191608
}
16201609
if (!asdl_seq_LEN(stmts))
16211610
return 1;
1622-
st = (stmt_ty)asdl_seq_GET(stmts, 0);
16231611
/* if not -OO mode, set docstring */
1624-
if (compiler_isdocstring(st) && c->c_optimize < 2) {
1625-
/* don't generate docstrings if -OO */
1626-
i = 1;
1627-
VISIT(c, expr, st->v.Expr.value);
1628-
if (!compiler_nameop(c, __doc__, Store))
1629-
return 0;
1612+
if (c->c_optimize < 2) {
1613+
docstring = _PyAST_GetDocString(stmts);
1614+
if (docstring) {
1615+
i = 1;
1616+
st = (stmt_ty)asdl_seq_GET(stmts, 0);
1617+
assert(st->kind == Expr_kind);
1618+
VISIT(c, expr, st->v.Expr.value);
1619+
if (!compiler_nameop(c, __doc__, Store))
1620+
return 0;
1621+
}
16301622
}
16311623
for (; i < asdl_seq_LEN(stmts); i++)
16321624
VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
@@ -1979,15 +1971,13 @@ static int
19791971
compiler_function(struct compiler *c, stmt_ty s, int is_async)
19801972
{
19811973
PyCodeObject *co;
1982-
PyObject *qualname, *first_const = Py_None;
1974+
PyObject *qualname, *docstring = NULL;
19831975
arguments_ty args;
19841976
expr_ty returns;
19851977
identifier name;
19861978
asdl_seq* decos;
19871979
asdl_seq *body;
1988-
stmt_ty st;
19891980
Py_ssize_t i, funcflags;
1990-
int docstring;
19911981
int annotations;
19921982
int scope_type;
19931983

@@ -2034,15 +2024,10 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
20342024
}
20352025

20362026
/* if not -OO mode, add docstring */
2037-
st = (stmt_ty)asdl_seq_GET(body, 0);
2038-
docstring = compiler_isdocstring(st);
2039-
if (docstring && c->c_optimize < 2) {
2040-
if (st->v.Expr.value->kind == Constant_kind)
2041-
first_const = st->v.Expr.value->v.Constant.value;
2042-
else
2043-
first_const = st->v.Expr.value->v.Str.s;
2027+
if (c->c_optimize < 2) {
2028+
docstring = _PyAST_GetDocString(body);
20442029
}
2045-
if (compiler_add_const(c, first_const) < 0) {
2030+
if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) {
20462031
compiler_exit_scope(c);
20472032
return 0;
20482033
}

Python/future.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "graminit.h"
66
#include "code.h"
77
#include "symtable.h"
8+
#include "ast.h"
89

910
#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
1011
#define ERR_LATE_FUTURE \
@@ -63,7 +64,6 @@ static int
6364
future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
6465
{
6566
int i, done = 0, prev_line = 0;
66-
stmt_ty first;
6767

6868
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
6969
return 1;
@@ -80,11 +80,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
8080
*/
8181

8282
i = 0;
83-
first = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
84-
if (first->kind == Expr_kind
85-
&& (first->v.Expr.value->kind == Str_kind
86-
|| (first->v.Expr.value->kind == Constant_kind
87-
&& PyUnicode_CheckExact(first->v.Expr.value->v.Constant.value))))
83+
if (_PyAST_GetDocString(mod->v.Module.body) != NULL)
8884
i++;
8985

9086
for (; i < asdl_seq_LEN(mod->v.Module.body); i++) {

0 commit comments

Comments
 (0)