@@ -435,13 +435,37 @@ stmt_seq_remove_item(asdl_stmt_seq *stmts, Py_ssize_t idx)
435435 return 1 ;
436436}
437437
438+ static int
439+ remove_docstring (asdl_stmt_seq * stmts , Py_ssize_t idx , PyArena * ctx_ )
440+ {
441+ // In case there's just the docstring in the body, replace it with `pass`
442+ // keyword, so body won't be empty.
443+ if (asdl_seq_LEN (stmts ) == 1 ) {
444+ stmt_ty docstring = (stmt_ty )asdl_seq_GET (stmts , 0 );
445+ stmt_ty pass = _PyAST_Pass (
446+ docstring -> lineno , docstring -> col_offset ,
447+ // we know that `pass` always takes 4 chars and a single line,
448+ // while docstring can span on multiple lines
449+ docstring -> lineno , docstring -> col_offset + 4 ,
450+ ctx_
451+ );
452+ if (pass == NULL ) {
453+ return 0 ;
454+ }
455+ asdl_seq_SET (stmts , 0 , pass );
456+ return 1 ;
457+ }
458+ // In case there are more than 1 body items, just remove the docstring.
459+ return stmt_seq_remove_item (stmts , idx );
460+ }
461+
438462static int
439463astfold_body (asdl_stmt_seq * stmts , PyArena * ctx_ , _PyASTPreprocessState * state )
440464{
441465 int docstring = _PyAST_GetDocString (stmts ) != NULL ;
442466 if (docstring && (state -> optimize >= 2 )) {
443467 /* remove the docstring */
444- if (!stmt_seq_remove_item (stmts , 0 )) {
468+ if (!remove_docstring (stmts , 0 , ctx_ )) {
445469 return 0 ;
446470 }
447471 docstring = 0 ;
0 commit comments