Skip to content

Commit

Permalink
pythongh-123958: apply docstring removal optimization in ast_opt inst…
Browse files Browse the repository at this point in the history
…ead of codegen (python#123959)
  • Loading branch information
iritkatriel authored Sep 11, 2024
1 parent 2938c3d commit e07154f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 23 deletions.
4 changes: 3 additions & 1 deletion Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,11 @@ ast
(Contributed by Batuhan Taskaya and Jeremy Hylton in :issue:`15987`.)

* Add support for :func:`copy.replace` for AST nodes.

(Contributed by Bénédikt Tran in :gh:`121141`.)

* Docstrings are now removed from an optimized AST in optimization level 2.
(Contributed by Irit Katriel in :gh:`123958`.)


ctypes
------
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,10 @@ def test_docstring(self):
def with_docstring():
"docstring"
def two_strings():
"docstring"
"not docstring"
def with_fstring():
f"not docstring"
Expand All @@ -891,8 +895,10 @@ def with_const_expression():

if opt < 2:
self.assertEqual(ns['with_docstring'].__doc__, "docstring")
self.assertEqual(ns['two_strings'].__doc__, "docstring")
else:
self.assertIsNone(ns['with_docstring'].__doc__)
self.assertIsNone(ns['two_strings'].__doc__)
self.assertIsNone(ns['with_fstring'].__doc__)
self.assertIsNone(ns['with_const_expression'].__doc__)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docstrings are now removed from the optimized AST in optimization level 2.
21 changes: 21 additions & 0 deletions Python/ast_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,31 @@ static int astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimize
}


static int
stmt_seq_remove_item(asdl_stmt_seq *stmts, Py_ssize_t idx)
{
if (idx >= asdl_seq_LEN(stmts)) {
return 0;
}
for (Py_ssize_t i = idx; i < asdl_seq_LEN(stmts) - 1; i++) {
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, i+1);
asdl_seq_SET(stmts, i, st);
}
stmts->size--;
return 1;
}

static int
astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
{
int docstring = _PyAST_GetDocString(stmts) != NULL;
if (docstring && (state->optimize >= 2)) {
/* remove the docstring */
if (!stmt_seq_remove_item(stmts, 0)) {
return 0;
}
docstring = 0;
}
CALL_SEQ(astfold_stmt, stmt, stmts);
if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
Expand Down
38 changes: 16 additions & 22 deletions Python/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,19 +763,18 @@ _PyCodegen_Body(compiler *c, location loc, asdl_stmt_seq *stmts)
PyObject *docstring = _PyAST_GetDocString(stmts);
if (docstring) {
first_instr = 1;
/* if not -OO mode, set docstring */
if (OPTIMIZATION_LEVEL(c) < 2) {
PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
if (cleandoc == NULL) {
return ERROR;
}
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
assert(st->kind == Expr_kind);
location loc = LOC(st->v.Expr.value);
ADDOP_LOAD_CONST(c, loc, cleandoc);
Py_DECREF(cleandoc);
RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
/* set docstring */
assert(OPTIMIZATION_LEVEL(c) < 2);
PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
if (cleandoc == NULL) {
return ERROR;
}
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
assert(st->kind == Expr_kind);
location loc = LOC(st->v.Expr.value);
ADDOP_LOAD_CONST(c, loc, cleandoc);
Py_DECREF(cleandoc);
RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
}
}
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
Expand Down Expand Up @@ -1230,18 +1229,13 @@ codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags

Py_ssize_t first_instr = 0;
PyObject *docstring = _PyAST_GetDocString(body);
assert(OPTIMIZATION_LEVEL(c) < 2 || docstring == NULL);
if (docstring) {
first_instr = 1;
/* if not -OO mode, add docstring */
if (OPTIMIZATION_LEVEL(c) < 2) {
docstring = _PyCompile_CleanDoc(docstring);
if (docstring == NULL) {
_PyCompile_ExitScope(c);
return ERROR;
}
}
else {
docstring = NULL;
docstring = _PyCompile_CleanDoc(docstring);
if (docstring == NULL) {
_PyCompile_ExitScope(c);
return ERROR;
}
}
Py_ssize_t idx = _PyCompile_AddConst(c, docstring ? docstring : Py_None);
Expand Down

0 comments on commit e07154f

Please sign in to comment.