mirror of https://github.com/python/cpython
gh-123958: apply docstring removal optimization in ast_opt instead of codegen (#123959)
This commit is contained in:
parent
2938c3dec9
commit
e07154fd1e
|
@ -123,9 +123,11 @@ ast
|
||||||
(Contributed by Batuhan Taskaya and Jeremy Hylton in :issue:`15987`.)
|
(Contributed by Batuhan Taskaya and Jeremy Hylton in :issue:`15987`.)
|
||||||
|
|
||||||
* Add support for :func:`copy.replace` for AST nodes.
|
* Add support for :func:`copy.replace` for AST nodes.
|
||||||
|
|
||||||
(Contributed by Bénédikt Tran in :gh:`121141`.)
|
(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
|
ctypes
|
||||||
------
|
------
|
||||||
|
|
|
@ -876,6 +876,10 @@ class TestSpecifics(unittest.TestCase):
|
||||||
def with_docstring():
|
def with_docstring():
|
||||||
"docstring"
|
"docstring"
|
||||||
|
|
||||||
|
def two_strings():
|
||||||
|
"docstring"
|
||||||
|
"not docstring"
|
||||||
|
|
||||||
def with_fstring():
|
def with_fstring():
|
||||||
f"not docstring"
|
f"not docstring"
|
||||||
|
|
||||||
|
@ -891,8 +895,10 @@ class TestSpecifics(unittest.TestCase):
|
||||||
|
|
||||||
if opt < 2:
|
if opt < 2:
|
||||||
self.assertEqual(ns['with_docstring'].__doc__, "docstring")
|
self.assertEqual(ns['with_docstring'].__doc__, "docstring")
|
||||||
|
self.assertEqual(ns['two_strings'].__doc__, "docstring")
|
||||||
else:
|
else:
|
||||||
self.assertIsNone(ns['with_docstring'].__doc__)
|
self.assertIsNone(ns['with_docstring'].__doc__)
|
||||||
|
self.assertIsNone(ns['two_strings'].__doc__)
|
||||||
self.assertIsNone(ns['with_fstring'].__doc__)
|
self.assertIsNone(ns['with_fstring'].__doc__)
|
||||||
self.assertIsNone(ns['with_const_expression'].__doc__)
|
self.assertIsNone(ns['with_const_expression'].__doc__)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
docstrings are now removed from the optimized AST in optimization level 2.
|
|
@ -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
|
static int
|
||||||
astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
|
astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
|
||||||
{
|
{
|
||||||
int docstring = _PyAST_GetDocString(stmts) != NULL;
|
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);
|
CALL_SEQ(astfold_stmt, stmt, stmts);
|
||||||
if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
|
if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
|
||||||
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
|
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
|
||||||
|
|
|
@ -763,19 +763,18 @@ _PyCodegen_Body(compiler *c, location loc, asdl_stmt_seq *stmts)
|
||||||
PyObject *docstring = _PyAST_GetDocString(stmts);
|
PyObject *docstring = _PyAST_GetDocString(stmts);
|
||||||
if (docstring) {
|
if (docstring) {
|
||||||
first_instr = 1;
|
first_instr = 1;
|
||||||
/* if not -OO mode, set docstring */
|
/* set docstring */
|
||||||
if (OPTIMIZATION_LEVEL(c) < 2) {
|
assert(OPTIMIZATION_LEVEL(c) < 2);
|
||||||
PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
|
PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
|
||||||
if (cleandoc == NULL) {
|
if (cleandoc == NULL) {
|
||||||
return ERROR;
|
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));
|
|
||||||
}
|
}
|
||||||
|
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++) {
|
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
|
||||||
|
@ -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;
|
Py_ssize_t first_instr = 0;
|
||||||
PyObject *docstring = _PyAST_GetDocString(body);
|
PyObject *docstring = _PyAST_GetDocString(body);
|
||||||
|
assert(OPTIMIZATION_LEVEL(c) < 2 || docstring == NULL);
|
||||||
if (docstring) {
|
if (docstring) {
|
||||||
first_instr = 1;
|
first_instr = 1;
|
||||||
/* if not -OO mode, add docstring */
|
docstring = _PyCompile_CleanDoc(docstring);
|
||||||
if (OPTIMIZATION_LEVEL(c) < 2) {
|
if (docstring == NULL) {
|
||||||
docstring = _PyCompile_CleanDoc(docstring);
|
_PyCompile_ExitScope(c);
|
||||||
if (docstring == NULL) {
|
return ERROR;
|
||||||
_PyCompile_ExitScope(c);
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
docstring = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_ssize_t idx = _PyCompile_AddConst(c, docstring ? docstring : Py_None);
|
Py_ssize_t idx = _PyCompile_AddConst(c, docstring ? docstring : Py_None);
|
||||||
|
|
Loading…
Reference in New Issue