mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	gh-123958: apply docstring removal optimization in ast_opt instead of codegen (#123959)
This commit is contained in:
		
							parent
							
								
									2938c3dec9
								
							
						
					
					
						commit
						e07154fd1e
					
				
					 5 changed files with 47 additions and 23 deletions
				
			
		|  | @ -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 @@ def test_docstring(self): | ||||||
|             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 @@ def with_const_expression(): | ||||||
| 
 | 
 | ||||||
|                 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Irit Katriel
						Irit Katriel