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

Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1536,9 +1536,9 @@ Other bits in :attr:`~codeobject.co_flags` are reserved for internal use.

.. index:: single: documentation string

If a code object represents a function, the first item in
:attr:`~codeobject.co_consts` is
the documentation string of the function, or ``None`` if undefined.
If a code object represents a function and has a docstring,
the first item in :attr:`~codeobject.co_consts` is
the documentation string of the function.
Comment thread
xuantengh marked this conversation as resolved.
Outdated

Methods on code objects
~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
3 changes: 3 additions & 0 deletions Include/cpython/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ struct PyCodeObject _PyCode_DEF(1);

#define CO_NO_MONITORING_EVENTS 0x2000000

/* Whether the first element in co_consts is doc string */
#define CO_HAS_DOCSTRING 0x4000000

/* This should be defined if a future statement modifies the syntax.
For example, when a keyword is added.
*/
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_symtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ typedef struct _symtable_entry {
unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */
unsigned ste_can_see_class_scope : 1; /* true if this block can see names bound in an
enclosing class scope */
unsigned ste_has_docstring : 1; /* true if docstring present */
int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */
_Py_SourceLocation ste_loc; /* source location of block */
struct _symtable_entry *ste_annotation_block; /* symbol table entry for this entry's annotations */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add a new attribute in :attr:`~codeobject.co_flags` to indicate whether the
first item in :attr:`~codeobject.co_consts` is the docstring. If a code
object has no docstring, ``None`` will **NOT** be inserted.
11 changes: 8 additions & 3 deletions Python/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,10 @@ _PyCodegen_Body(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interac
assert(st->kind == Expr_kind);
location loc = LOC(st->v.Expr.value);
ADDOP_LOAD_CONST(c, loc, cleandoc);

PySTEntryObject *ste = SYMTABLE_ENTRY(c);
ste->ste_has_docstring = 1;
Comment thread
xuantengh marked this conversation as resolved.
Outdated

Py_DECREF(cleandoc);
RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
}
Expand Down Expand Up @@ -1225,21 +1229,22 @@ 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);
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
if (docstring) {
first_instr = 1;
docstring = _PyCompile_CleanDoc(docstring);
if (docstring == NULL) {
_PyCompile_ExitScope(c);
return ERROR;
}
Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
ste->ste_has_docstring = 1;
RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
Comment thread
xuantengh marked this conversation as resolved.
}
Py_ssize_t idx = _PyCompile_AddConst(c, docstring ? docstring : Py_None);
Py_XDECREF(docstring);
RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);

NEW_JUMP_TARGET_LABEL(c, start);
USE_LABEL(c, start);
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
if (add_stopiteration_handler) {
/* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
Expand Down
2 changes: 2 additions & 0 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,8 @@ compute_code_flags(compiler *c)
flags |= CO_VARARGS;
if (ste->ste_varkeywords)
flags |= CO_VARKEYWORDS;
if (ste->ste_has_docstring)
flags |= CO_HAS_DOCSTRING;
}

if (ste->ste_coroutine && !ste->ste_generator) {
Expand Down
2 changes: 2 additions & 0 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
ste->ste_needs_classdict = 0;
ste->ste_annotation_block = NULL;

ste->ste_has_docstring = 0;

ste->ste_symbols = PyDict_New();
ste->ste_varnames = PyList_New(0);
ste->ste_children = PyList_New(0);
Expand Down