11/* Lazy object implementation */
22
33#include "Python.h"
4- #include "pycore_import.h"
5- #include "pycore_lazyimportobject.h"
6- #include "pycore_frame.h"
74#include "pycore_ceval.h"
5+ #include "pycore_frame.h"
6+ #include "pycore_import.h"
87#include "pycore_interpframe.h"
8+ #include "pycore_lazyimportobject.h"
9+ #include "pycore_modsupport.h"
10+
11+ #define PyLazyImportObject_CAST (op ) ((PyLazyImportObject *)(op))
912
1013PyObject *
1114_PyLazyImport_New (PyObject * builtins , PyObject * from , PyObject * attr )
@@ -46,8 +49,9 @@ _PyLazyImport_New(PyObject *builtins, PyObject *from, PyObject *attr)
4649}
4750
4851static int
49- lazy_import_traverse (PyLazyImportObject * m , visitproc visit , void * arg )
52+ lazy_import_traverse (PyObject * op , visitproc visit , void * arg )
5053{
54+ PyLazyImportObject * m = PyLazyImportObject_CAST (op );
5155 Py_VISIT (m -> lz_builtins );
5256 Py_VISIT (m -> lz_from );
5357 Py_VISIT (m -> lz_attr );
@@ -56,8 +60,9 @@ lazy_import_traverse(PyLazyImportObject *m, visitproc visit, void *arg)
5660}
5761
5862static int
59- lazy_import_clear (PyLazyImportObject * m )
63+ lazy_import_clear (PyObject * op )
6064{
65+ PyLazyImportObject * m = PyLazyImportObject_CAST (op );
6166 Py_CLEAR (m -> lz_builtins );
6267 Py_CLEAR (m -> lz_from );
6368 Py_CLEAR (m -> lz_attr );
@@ -66,11 +71,11 @@ lazy_import_clear(PyLazyImportObject *m)
6671}
6772
6873static void
69- lazy_import_dealloc (PyLazyImportObject * m )
74+ lazy_import_dealloc (PyObject * op )
7075{
71- _PyObject_GC_UNTRACK (m );
72- lazy_import_clear (m );
73- Py_TYPE (m )-> tp_free (( PyObject * ) m );
76+ _PyObject_GC_UNTRACK (op );
77+ ( void ) lazy_import_clear (op );
78+ Py_TYPE (op )-> tp_free (op );
7479}
7580
7681static PyObject *
@@ -79,60 +84,69 @@ lazy_import_name(PyLazyImportObject *m)
7984 if (m -> lz_attr != NULL ) {
8085 if (PyUnicode_Check (m -> lz_attr )) {
8186 return PyUnicode_FromFormat ("%U.%U" , m -> lz_from , m -> lz_attr );
82- } else {
87+ }
88+ else {
8389 return PyUnicode_FromFormat ("%U..." , m -> lz_from );
8490 }
8591 }
86- Py_INCREF (m -> lz_from );
87- return m -> lz_from ;
92+ return Py_NewRef (m -> lz_from );
8893}
8994
9095static PyObject *
91- lazy_import_repr (PyLazyImportObject * m )
96+ lazy_import_repr (PyObject * op )
9297{
98+ PyLazyImportObject * m = PyLazyImportObject_CAST (op );
9399 PyObject * name = lazy_import_name (m );
94100 if (name == NULL ) {
95101 return NULL ;
96102 }
97- PyObject * res = PyUnicode_FromFormat ("<lazy_import '%U'>" , name );
103+ PyObject * res = PyUnicode_FromFormat ("<%T '%U'>" , op , name );
98104 Py_DECREF (name );
99105 return res ;
100106}
101107
102108static PyObject *
103109lazy_import_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
104110{
105- if (PyTuple_GET_SIZE (args ) != 2 && PyTuple_GET_SIZE (args ) != 3 ) {
106- PyErr_SetString (PyExc_ValueError , "lazy_import expected 2-3 arguments" );
111+ PyTypeObject * base_tp = & PyLazyImport_Type ;
112+ if (
113+ (type == base_tp || type -> tp_init == base_tp -> tp_init )
114+ && !_PyArg_NoKeywords ("lazy_import" , kwds )
115+ ) {
107116 return NULL ;
108117 }
109118
110- PyObject * builtins = PyTuple_GET_ITEM (args , 0 );
111- PyObject * from = PyTuple_GET_ITEM (args , 1 );
112- PyObject * attr = NULL ;
113- if (PyTuple_GET_SIZE (args ) == 3 ) {
114- attr = PyTuple_GET_ITEM (args , 2 );
119+ Py_ssize_t nargs = PyTuple_GET_SIZE (args );
120+ if (!_PyArg_CheckPositional ("lazy_import" , nargs , 2 , 3 )) {
121+ return NULL ;
115122 }
116123
124+ PyObject * builtins = PyTuple_GET_ITEM (args , 0 );
125+ PyObject * from = PyTuple_GET_ITEM (args , 1 );
126+ PyObject * attr = nargs == 3 ? PyTuple_GET_ITEM (args , 2 ) : NULL ;
117127 return _PyLazyImport_New (builtins , from , attr );
118128}
119129
120130PyObject *
121- _PyLazyImport_GetName (PyObject * lazy_import )
131+ _PyLazyImport_GetName (PyObject * op )
122132{
133+ PyLazyImportObject * lazy_import = PyLazyImportObject_CAST (op );
123134 assert (PyLazyImport_CheckExact (lazy_import ));
124- return lazy_import_name (( PyLazyImportObject * ) lazy_import );
135+ return lazy_import_name (lazy_import );
125136}
126137
127138static PyObject *
128- lazy_resolve (PyObject * self , PyObject * args )
139+ lazy_import_resolve (PyObject * self , PyObject * args )
129140{
130141 return _PyImport_LoadLazyImportTstate (PyThreadState_GET (), self );
131142}
132143
133- static PyMethodDef lazy_methods [] = {
134- {"resolve" , lazy_resolve , METH_NOARGS , PyDoc_STR ("resolves the lazy import and returns the actual object" )},
135- {0 }
144+ static PyMethodDef lazy_import_methods [] = {
145+ {
146+ "resolve" , lazy_import_resolve , METH_NOARGS ,
147+ PyDoc_STR ("resolves the lazy import and returns the actual object" )
148+ },
149+ {NULL , NULL }
136150};
137151
138152
@@ -147,43 +161,16 @@ PyDoc_STRVAR(lazy_import_doc,
147161
148162PyTypeObject PyLazyImport_Type = {
149163 PyVarObject_HEAD_INIT (& PyType_Type , 0 )
150- "lazy_import" , /* tp_name */
151- sizeof (PyLazyImportObject ), /* tp_basicsize */
152- 0 , /* tp_itemsize */
153- (destructor )lazy_import_dealloc , /* tp_dealloc */
154- 0 , /* tp_print */
155- 0 , /* tp_getattr */
156- 0 , /* tp_setattr */
157- 0 , /* tp_reserved */
158- (reprfunc )lazy_import_repr , /* tp_repr */
159- 0 , /* tp_as_number */
160- 0 , /* tp_as_sequence */
161- 0 , /* tp_as_mapping */
162- 0 , /* tp_hash */
163- 0 , /* tp_call */
164- 0 , /* tp_str */
165- 0 , /* tp_getattro */
166- 0 , /* tp_setattro */
167- 0 , /* tp_as_buffer */
168- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
169- Py_TPFLAGS_BASETYPE , /* tp_flags */
170- lazy_import_doc , /* tp_doc */
171- (traverseproc )lazy_import_traverse , /* tp_traverse */
172- (inquiry )lazy_import_clear , /* tp_clear */
173- 0 , /* tp_richcompare */
174- 0 , /* tp_weaklistoffset */
175- 0 , /* tp_iter */
176- 0 , /* tp_iternext */
177- lazy_methods , /* tp_methods */
178- 0 , /* tp_members */
179- 0 , /* tp_getset */
180- 0 , /* tp_base */
181- 0 , /* tp_dict */
182- 0 , /* tp_descr_get */
183- 0 , /* tp_descr_set */
184- 0 , /* tp_dictoffset */
185- 0 , /* tp_init */
186- PyType_GenericAlloc , /* tp_alloc */
187- lazy_import_new , /* tp_new */
188- PyObject_GC_Del , /* tp_free */
164+ .tp_name = "lazy_import" ,
165+ .tp_basicsize = sizeof (PyLazyImportObject ),
166+ .tp_dealloc = lazy_import_dealloc ,
167+ .tp_repr = lazy_import_repr ,
168+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE ,
169+ .tp_doc = lazy_import_doc ,
170+ .tp_traverse = lazy_import_traverse ,
171+ .tp_clear = lazy_import_clear ,
172+ .tp_methods = lazy_import_methods ,
173+ .tp_alloc = PyType_GenericAlloc ,
174+ .tp_new = lazy_import_new ,
175+ .tp_free = PyObject_GC_Del ,
189176};
0 commit comments