3
3
4
4
#include "Python.h"
5
5
#include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals()
6
+ #include "pycore_code.h" // Hydration
6
7
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
7
8
#include "pycore_pyerrors.h" // _PyErr_Occurred()
8
9
#include "structmember.h" // PyMemberDef
@@ -31,20 +32,6 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
31
32
assert (qualname != NULL );
32
33
Py_INCREF (qualname );
33
34
34
- PyObject * consts = code_obj -> co_consts ;
35
- assert (consts == NULL || PyTuple_Check (consts ));
36
- PyObject * doc ;
37
- if (consts != NULL && PyTuple_Size (consts ) >= 1 ) {
38
- doc = PyTuple_GetItem (consts , 0 );
39
- if (!PyUnicode_Check (doc )) {
40
- doc = Py_None ;
41
- }
42
- }
43
- else {
44
- doc = Py_None ;
45
- }
46
- Py_INCREF (doc );
47
-
48
35
// __module__: Use globals['__name__'] if it exists, or NULL.
49
36
_Py_IDENTIFIER (__name__ );
50
37
PyObject * module = _PyDict_GetItemIdWithError (globals , & PyId___name__ );
@@ -75,7 +62,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
75
62
op -> func_defaults = NULL ; // No default positional arguments
76
63
op -> func_kwdefaults = NULL ; // No default keyword arguments
77
64
op -> func_closure = NULL ;
78
- op -> func_doc = doc ;
65
+ op -> func_doc = NULL ;
79
66
op -> func_dict = NULL ;
80
67
op -> func_weakreflist = NULL ;
81
68
op -> func_module = module ;
@@ -90,7 +77,6 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
90
77
Py_DECREF (code_obj );
91
78
Py_DECREF (name );
92
79
Py_DECREF (qualname );
93
- Py_DECREF (doc );
94
80
Py_XDECREF (module );
95
81
Py_XDECREF (builtins );
96
82
return NULL ;
@@ -279,7 +265,6 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
279
265
280
266
static PyMemberDef func_memberlist [] = {
281
267
{"__closure__" , T_OBJECT , OFF (func_closure ), READONLY },
282
- {"__doc__" , T_OBJECT , OFF (func_doc ), 0 },
283
268
{"__globals__" , T_OBJECT , OFF (func_globals ), READONLY },
284
269
{"__module__" , T_OBJECT , OFF (func_module ), 0 },
285
270
{"__builtins__" , T_OBJECT , OFF (func_builtins ), READONLY },
@@ -510,6 +495,37 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno
510
495
return 0 ;
511
496
}
512
497
498
+ static PyObject *
499
+ func_get_doc (PyFunctionObject * op , void * Py_UNUSED (ignored ))
500
+ {
501
+ PyObject * doc = op -> func_doc ;
502
+ if (doc == NULL ) {
503
+ PyCodeObject * code = (PyCodeObject * )op -> func_code ;
504
+ if (!_PyCode_IsHydrated (code )) {
505
+ if (_PyCode_Hydrate (code ) == NULL ) {
506
+ return NULL ;
507
+ }
508
+ }
509
+ if (PyTuple_CheckExact (code -> co_consts )
510
+ && PyTuple_GET_SIZE (code -> co_consts ) >= 1 ) {
511
+ doc = PyTuple_GET_ITEM (code -> co_consts , 0 );
512
+ }
513
+ }
514
+ if (doc == NULL ) {
515
+ doc = Py_None ;
516
+ }
517
+ Py_INCREF (doc );
518
+ return doc ;
519
+ }
520
+
521
+ static int
522
+ func_set_doc (PyFunctionObject * op , PyObject * value , void * Py_UNUSED (ignored ))
523
+ {
524
+ Py_INCREF (value );
525
+ Py_XSETREF (op -> func_doc , value );
526
+ return 0 ;
527
+ }
528
+
513
529
static PyGetSetDef func_getsetlist [] = {
514
530
{"__code__" , (getter )func_get_code , (setter )func_set_code },
515
531
{"__defaults__" , (getter )func_get_defaults ,
@@ -521,6 +537,7 @@ static PyGetSetDef func_getsetlist[] = {
521
537
{"__dict__" , PyObject_GenericGetDict , PyObject_GenericSetDict },
522
538
{"__name__" , (getter )func_get_name , (setter )func_set_name },
523
539
{"__qualname__" , (getter )func_get_qualname , (setter )func_set_qualname },
540
+ {"__doc__" , (getter )func_get_doc , (setter )func_set_doc },
524
541
{NULL } /* Sentinel */
525
542
};
526
543
0 commit comments