Branch data Line data Source code
1 : :
2 : : /* Module object implementation */
3 : :
4 : : #include "Python.h"
5 : : #include "pycore_call.h" // _PyObject_CallNoArgs()
6 : : #include "pycore_interp.h" // PyInterpreterState.importlib
7 : : #include "pycore_object.h" // _PyType_AllocNoTrack
8 : : #include "pycore_pystate.h" // _PyInterpreterState_GET()
9 : : #include "pycore_moduleobject.h" // _PyModule_GetDef()
10 : : #include "structmember.h" // PyMemberDef
11 : :
12 : : static Py_ssize_t max_module_number;
13 : :
14 : : static PyMemberDef module_members[] = {
15 : : {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
16 : : {0}
17 : : };
18 : :
19 : :
20 : : PyTypeObject PyModuleDef_Type = {
21 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
22 : : "moduledef", /* tp_name */
23 : : sizeof(PyModuleDef), /* tp_basicsize */
24 : : 0, /* tp_itemsize */
25 : : };
26 : :
27 : :
28 : : int
29 : 40 : _PyModule_IsExtension(PyObject *obj)
30 : : {
31 [ - + ]: 40 : if (!PyModule_Check(obj)) {
32 : 0 : return 0;
33 : : }
34 : 40 : PyModuleObject *module = (PyModuleObject*)obj;
35 : :
36 : 40 : PyModuleDef *def = module->md_def;
37 [ + + + - ]: 40 : return (def != NULL && def->m_methods != NULL);
38 : : }
39 : :
40 : :
41 : : PyObject*
42 : 171123 : PyModuleDef_Init(PyModuleDef* def)
43 : : {
44 : : assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY);
45 [ + + ]: 171123 : if (def->m_base.m_index == 0) {
46 : 89108 : max_module_number++;
47 : 89108 : Py_SET_REFCNT(def, 1);
48 : 89108 : Py_SET_TYPE(def, &PyModuleDef_Type);
49 : 89108 : def->m_base.m_index = max_module_number;
50 : : }
51 : 171123 : return (PyObject*)def;
52 : : }
53 : :
54 : : static int
55 : 309201 : module_init_dict(PyModuleObject *mod, PyObject *md_dict,
56 : : PyObject *name, PyObject *doc)
57 : : {
58 : : assert(md_dict != NULL);
59 [ + + ]: 309201 : if (doc == NULL)
60 : 98582 : doc = Py_None;
61 : :
62 [ - + ]: 309201 : if (PyDict_SetItem(md_dict, &_Py_ID(__name__), name) != 0)
63 : 0 : return -1;
64 [ - + ]: 309201 : if (PyDict_SetItem(md_dict, &_Py_ID(__doc__), doc) != 0)
65 : 0 : return -1;
66 [ - + ]: 309201 : if (PyDict_SetItem(md_dict, &_Py_ID(__package__), Py_None) != 0)
67 : 0 : return -1;
68 [ - + ]: 309201 : if (PyDict_SetItem(md_dict, &_Py_ID(__loader__), Py_None) != 0)
69 : 0 : return -1;
70 [ - + ]: 309201 : if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0)
71 : 0 : return -1;
72 [ + - ]: 309201 : if (PyUnicode_CheckExact(name)) {
73 : 309201 : Py_INCREF(name);
74 : 309201 : Py_XSETREF(mod->md_name, name);
75 : : }
76 : :
77 : 309201 : return 0;
78 : : }
79 : :
80 : : static PyModuleObject *
81 : 309203 : new_module_notrack(PyTypeObject *mt)
82 : : {
83 : : PyModuleObject *m;
84 : 309203 : m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0);
85 [ - + ]: 309203 : if (m == NULL)
86 : 0 : return NULL;
87 : 309203 : m->md_def = NULL;
88 : 309203 : m->md_state = NULL;
89 : 309203 : m->md_weaklist = NULL;
90 : 309203 : m->md_name = NULL;
91 : 309203 : m->md_dict = PyDict_New();
92 [ + - ]: 309203 : if (m->md_dict != NULL) {
93 : 309203 : return m;
94 : : }
95 : 0 : Py_DECREF(m);
96 : 0 : return NULL;
97 : : }
98 : :
99 : : static PyObject *
100 : 210621 : new_module(PyTypeObject *mt, PyObject *args, PyObject *kws)
101 : : {
102 : 210621 : PyObject *m = (PyObject *)new_module_notrack(mt);
103 [ + - ]: 210621 : if (m != NULL) {
104 : 210621 : PyObject_GC_Track(m);
105 : : }
106 : 210621 : return m;
107 : : }
108 : :
109 : : PyObject *
110 : 98582 : PyModule_NewObject(PyObject *name)
111 : : {
112 : 98582 : PyModuleObject *m = new_module_notrack(&PyModule_Type);
113 [ - + ]: 98582 : if (m == NULL)
114 : 0 : return NULL;
115 [ - + ]: 98582 : if (module_init_dict(m, m->md_dict, name, NULL) != 0)
116 : 0 : goto fail;
117 : 98582 : PyObject_GC_Track(m);
118 : 98582 : return (PyObject *)m;
119 : :
120 : 0 : fail:
121 : 0 : Py_DECREF(m);
122 : 0 : return NULL;
123 : : }
124 : :
125 : : PyObject *
126 : 13369 : PyModule_New(const char *name)
127 : : {
128 : : PyObject *nameobj, *module;
129 : 13369 : nameobj = PyUnicode_FromString(name);
130 [ - + ]: 13369 : if (nameobj == NULL)
131 : 0 : return NULL;
132 : 13369 : module = PyModule_NewObject(nameobj);
133 : 13369 : Py_DECREF(nameobj);
134 : 13369 : return module;
135 : : }
136 : :
137 : : /* Check API/ABI version
138 : : * Issues a warning on mismatch, which is usually not fatal.
139 : : * Returns 0 if an exception is raised.
140 : : */
141 : : static int
142 : 92203 : check_api_version(const char *name, int module_api_version)
143 : : {
144 [ - + - - ]: 92203 : if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) {
145 : : int err;
146 : 0 : err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
147 : : "Python C API version mismatch for module %.100s: "
148 : : "This Python has API version %d, module %.100s has version %d.",
149 : : name,
150 : : PYTHON_API_VERSION, name, module_api_version);
151 [ # # ]: 0 : if (err)
152 : 0 : return 0;
153 : : }
154 : 92203 : return 1;
155 : : }
156 : :
157 : : static int
158 : 88147 : _add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
159 : : {
160 : : PyObject *func;
161 : : PyMethodDef *fdef;
162 : :
163 [ + + ]: 1999405 : for (fdef = functions; fdef->ml_name != NULL; fdef++) {
164 [ + - ]: 1911258 : if ((fdef->ml_flags & METH_CLASS) ||
165 [ - + ]: 1911258 : (fdef->ml_flags & METH_STATIC)) {
166 : 0 : PyErr_SetString(PyExc_ValueError,
167 : : "module functions cannot set"
168 : : " METH_CLASS or METH_STATIC");
169 : 0 : return -1;
170 : : }
171 : 1911258 : func = PyCFunction_NewEx(fdef, (PyObject*)module, name);
172 [ - + ]: 1911258 : if (func == NULL) {
173 : 0 : return -1;
174 : : }
175 [ - + ]: 1911258 : if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) {
176 : 0 : Py_DECREF(func);
177 : 0 : return -1;
178 : : }
179 : 1911258 : Py_DECREF(func);
180 : : }
181 : :
182 : 88147 : return 0;
183 : : }
184 : :
185 : : PyObject *
186 : 7009 : PyModule_Create2(PyModuleDef* module, int module_api_version)
187 : : {
188 [ - + ]: 7009 : if (!_PyImport_IsInitialized(_PyInterpreterState_GET())) {
189 : 0 : PyErr_SetString(PyExc_SystemError,
190 : : "Python import machinery not initialized");
191 : 0 : return NULL;
192 : : }
193 : 7009 : return _PyModule_CreateInitialized(module, module_api_version);
194 : : }
195 : :
196 : : PyObject *
197 : 13285 : _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
198 : : {
199 : : const char* name;
200 : : PyModuleObject *m;
201 : :
202 [ - + ]: 13285 : if (!PyModuleDef_Init(module))
203 : 0 : return NULL;
204 : 13285 : name = module->m_name;
205 [ - + ]: 13285 : if (!check_api_version(name, module_api_version)) {
206 : 0 : return NULL;
207 : : }
208 [ - + ]: 13285 : if (module->m_slots) {
209 : 0 : PyErr_Format(
210 : : PyExc_SystemError,
211 : : "module %s: PyModule_Create is incompatible with m_slots", name);
212 : 0 : return NULL;
213 : : }
214 : : /* Make sure name is fully qualified.
215 : :
216 : : This is a bit of a hack: when the shared library is loaded,
217 : : the module name is "package.module", but the module calls
218 : : PyModule_Create*() with just "module" for the name. The shared
219 : : library loader squirrels away the true name of the module in
220 : : _Py_PackageContext, and PyModule_Create*() will substitute this
221 : : (if the name actually matches).
222 : : */
223 [ + + ]: 13285 : if (_Py_PackageContext != NULL) {
224 : 3846 : const char *p = strrchr(_Py_PackageContext, '.');
225 [ - + - - ]: 3846 : if (p != NULL && strcmp(module->m_name, p+1) == 0) {
226 : 0 : name = _Py_PackageContext;
227 : 0 : _Py_PackageContext = NULL;
228 : : }
229 : : }
230 [ - + ]: 13285 : if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
231 : 0 : return NULL;
232 : :
233 [ + + ]: 13285 : if (module->m_size > 0) {
234 : 3996 : m->md_state = PyMem_Malloc(module->m_size);
235 [ - + ]: 3996 : if (!m->md_state) {
236 : : PyErr_NoMemory();
237 : 0 : Py_DECREF(m);
238 : 0 : return NULL;
239 : : }
240 : 3996 : memset(m->md_state, 0, module->m_size);
241 : : }
242 : :
243 [ + + ]: 13285 : if (module->m_methods != NULL) {
244 [ - + ]: 13280 : if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
245 : 0 : Py_DECREF(m);
246 : 0 : return NULL;
247 : : }
248 : : }
249 [ + + ]: 13285 : if (module->m_doc != NULL) {
250 [ - + ]: 12013 : if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) {
251 : 0 : Py_DECREF(m);
252 : 0 : return NULL;
253 : : }
254 : : }
255 : 13285 : m->md_def = module;
256 : 13285 : return (PyObject*)m;
257 : : }
258 : :
259 : : PyObject *
260 : 78918 : PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version)
261 : : {
262 : : PyModuleDef_Slot* cur_slot;
263 : 78918 : PyObject *(*create)(PyObject *, PyModuleDef*) = NULL;
264 : : PyObject *nameobj;
265 : 78918 : PyObject *m = NULL;
266 : 78918 : int has_execution_slots = 0;
267 : : const char *name;
268 : : int ret;
269 : :
270 : 78918 : PyModuleDef_Init(def);
271 : :
272 : 78918 : nameobj = PyObject_GetAttrString(spec, "name");
273 [ - + ]: 78918 : if (nameobj == NULL) {
274 : 0 : return NULL;
275 : : }
276 : 78918 : name = PyUnicode_AsUTF8(nameobj);
277 [ - + ]: 78918 : if (name == NULL) {
278 : 0 : goto error;
279 : : }
280 : :
281 [ - + ]: 78918 : if (!check_api_version(name, module_api_version)) {
282 : 0 : goto error;
283 : : }
284 : :
285 [ + + ]: 78918 : if (def->m_size < 0) {
286 : 2 : PyErr_Format(
287 : : PyExc_SystemError,
288 : : "module %s: m_size may not be negative for multi-phase initialization",
289 : : name);
290 : 2 : goto error;
291 : : }
292 : :
293 [ + + + + ]: 153942 : for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
294 [ + + ]: 75030 : if (cur_slot->slot == Py_mod_create) {
295 [ - + ]: 14 : if (create) {
296 : 0 : PyErr_Format(
297 : : PyExc_SystemError,
298 : : "module %s has multiple create slots",
299 : : name);
300 : 0 : goto error;
301 : : }
302 : 14 : create = cur_slot->value;
303 [ + + + + ]: 75016 : } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) {
304 : 4 : PyErr_Format(
305 : : PyExc_SystemError,
306 : : "module %s uses unknown slot ID %i",
307 : : name, cur_slot->slot);
308 : 4 : goto error;
309 : : } else {
310 : 75012 : has_execution_slots = 1;
311 : : }
312 : : }
313 : :
314 [ + + ]: 78912 : if (create) {
315 : 14 : m = create(spec, def);
316 [ + + ]: 14 : if (m == NULL) {
317 [ + + ]: 8 : if (!PyErr_Occurred()) {
318 : 2 : PyErr_Format(
319 : : PyExc_SystemError,
320 : : "creation of module %s failed without setting an exception",
321 : : name);
322 : : }
323 : 8 : goto error;
324 : : } else {
325 [ + + ]: 6 : if (PyErr_Occurred()) {
326 : 2 : PyErr_Format(PyExc_SystemError,
327 : : "creation of module %s raised unreported exception",
328 : : name);
329 : 2 : goto error;
330 : : }
331 : : }
332 : : } else {
333 : 78898 : m = PyModule_NewObject(nameobj);
334 [ - + ]: 78898 : if (m == NULL) {
335 : 0 : goto error;
336 : : }
337 : : }
338 : :
339 [ + + ]: 78902 : if (PyModule_Check(m)) {
340 : 78898 : ((PyModuleObject*)m)->md_state = NULL;
341 : 78898 : ((PyModuleObject*)m)->md_def = def;
342 : : } else {
343 [ + - + - : 4 : if (def->m_size > 0 || def->m_traverse || def->m_clear || def->m_free) {
+ - - + ]
344 : 0 : PyErr_Format(
345 : : PyExc_SystemError,
346 : : "module %s is not a module object, but requests module state",
347 : : name);
348 : 0 : goto error;
349 : : }
350 [ - + ]: 4 : if (has_execution_slots) {
351 : 0 : PyErr_Format(
352 : : PyExc_SystemError,
353 : : "module %s specifies execution slots, but did not create "
354 : : "a ModuleType instance",
355 : : name);
356 : 0 : goto error;
357 : : }
358 : : }
359 : :
360 [ + + ]: 78902 : if (def->m_methods != NULL) {
361 : 73697 : ret = _add_methods_to_object(m, nameobj, def->m_methods);
362 [ - + ]: 73697 : if (ret != 0) {
363 : 0 : goto error;
364 : : }
365 : : }
366 : :
367 [ + + ]: 78902 : if (def->m_doc != NULL) {
368 : 67013 : ret = PyModule_SetDocString(m, def->m_doc);
369 [ - + ]: 67013 : if (ret != 0) {
370 : 0 : goto error;
371 : : }
372 : : }
373 : :
374 : 78902 : Py_DECREF(nameobj);
375 : 78902 : return m;
376 : :
377 : 16 : error:
378 : 16 : Py_DECREF(nameobj);
379 : 16 : Py_XDECREF(m);
380 : 16 : return NULL;
381 : : }
382 : :
383 : : int
384 : 81916 : PyModule_ExecDef(PyObject *module, PyModuleDef *def)
385 : : {
386 : : PyModuleDef_Slot *cur_slot;
387 : : const char *name;
388 : : int ret;
389 : :
390 : 81916 : name = PyModule_GetName(module);
391 [ - + ]: 81916 : if (name == NULL) {
392 : 0 : return -1;
393 : : }
394 : :
395 [ + + ]: 81916 : if (def->m_size >= 0) {
396 : 78940 : PyModuleObject *md = (PyModuleObject*)module;
397 [ + - ]: 78940 : if (md->md_state == NULL) {
398 : : /* Always set a state pointer; this serves as a marker to skip
399 : : * multiple initialization (importlib.reload() is no-op) */
400 : 78940 : md->md_state = PyMem_Malloc(def->m_size);
401 [ - + ]: 78940 : if (!md->md_state) {
402 : : PyErr_NoMemory();
403 : 0 : return -1;
404 : : }
405 : 78940 : memset(md->md_state, 0, def->m_size);
406 : : }
407 : : }
408 : :
409 [ + + ]: 81916 : if (def->m_slots == NULL) {
410 : 6795 : return 0;
411 : : }
412 : :
413 [ + - + + ]: 150125 : for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
414 [ - + - ]: 75010 : switch (cur_slot->slot) {
415 : 0 : case Py_mod_create:
416 : : /* handled in PyModule_FromDefAndSpec2 */
417 : 0 : break;
418 : 75010 : case Py_mod_exec:
419 : 75010 : ret = ((int (*)(PyObject *))cur_slot->value)(module);
420 [ + + ]: 75010 : if (ret != 0) {
421 [ + + ]: 4 : if (!PyErr_Occurred()) {
422 : 2 : PyErr_Format(
423 : : PyExc_SystemError,
424 : : "execution of module %s failed without setting an exception",
425 : : name);
426 : : }
427 : 4 : return -1;
428 : : }
429 [ + + ]: 75006 : if (PyErr_Occurred()) {
430 : 2 : PyErr_Format(
431 : : PyExc_SystemError,
432 : : "execution of module %s raised unreported exception",
433 : : name);
434 : 2 : return -1;
435 : : }
436 : 75004 : break;
437 : 0 : default:
438 : 0 : PyErr_Format(
439 : : PyExc_SystemError,
440 : : "module %s initialized with unknown slot %i",
441 : : name, cur_slot->slot);
442 : 0 : return -1;
443 : : }
444 : : }
445 : 75115 : return 0;
446 : : }
447 : :
448 : : int
449 : 14450 : PyModule_AddFunctions(PyObject *m, PyMethodDef *functions)
450 : : {
451 : : int res;
452 : 14450 : PyObject *name = PyModule_GetNameObject(m);
453 [ - + ]: 14450 : if (name == NULL) {
454 : 0 : return -1;
455 : : }
456 : :
457 : 14450 : res = _add_methods_to_object(m, name, functions);
458 : 14450 : Py_DECREF(name);
459 : 14450 : return res;
460 : : }
461 : :
462 : : int
463 : 79026 : PyModule_SetDocString(PyObject *m, const char *doc)
464 : : {
465 : : PyObject *v;
466 : :
467 : 79026 : v = PyUnicode_FromString(doc);
468 [ + - - + ]: 79026 : if (v == NULL || PyObject_SetAttr(m, &_Py_ID(__doc__), v) != 0) {
469 : 0 : Py_XDECREF(v);
470 : 0 : return -1;
471 : : }
472 : 79026 : Py_DECREF(v);
473 : 79026 : return 0;
474 : : }
475 : :
476 : : PyObject *
477 : 2349402 : PyModule_GetDict(PyObject *m)
478 : : {
479 [ - + ]: 2349402 : if (!PyModule_Check(m)) {
480 : 0 : PyErr_BadInternalCall();
481 : 0 : return NULL;
482 : : }
483 : 2349402 : return _PyModule_GetDict(m);
484 : : }
485 : :
486 : : PyObject*
487 : 96366 : PyModule_GetNameObject(PyObject *m)
488 : : {
489 : : PyObject *d;
490 : : PyObject *name;
491 [ - + ]: 96366 : if (!PyModule_Check(m)) {
492 : 0 : PyErr_BadArgument();
493 : 0 : return NULL;
494 : : }
495 : 96366 : d = ((PyModuleObject *)m)->md_dict;
496 [ + - + - : 192732 : if (d == NULL || !PyDict_Check(d) ||
+ - ]
497 [ - + ]: 192732 : (name = PyDict_GetItemWithError(d, &_Py_ID(__name__))) == NULL ||
498 : 96366 : !PyUnicode_Check(name))
499 : : {
500 [ # # ]: 0 : if (!PyErr_Occurred()) {
501 : 0 : PyErr_SetString(PyExc_SystemError, "nameless module");
502 : : }
503 : 0 : return NULL;
504 : : }
505 : 96366 : Py_INCREF(name);
506 : 96366 : return name;
507 : : }
508 : :
509 : : const char *
510 : 81916 : PyModule_GetName(PyObject *m)
511 : : {
512 : 81916 : PyObject *name = PyModule_GetNameObject(m);
513 [ - + ]: 81916 : if (name == NULL) {
514 : 0 : return NULL;
515 : : }
516 : : assert(Py_REFCNT(name) >= 2);
517 : 81916 : Py_DECREF(name); /* module dict has still a reference */
518 : 81916 : return PyUnicode_AsUTF8(name);
519 : : }
520 : :
521 : : PyObject*
522 : 4763 : PyModule_GetFilenameObject(PyObject *m)
523 : : {
524 : : PyObject *d;
525 : : PyObject *fileobj;
526 [ + + ]: 4763 : if (!PyModule_Check(m)) {
527 : 1 : PyErr_BadArgument();
528 : 1 : return NULL;
529 : : }
530 : 4762 : d = ((PyModuleObject *)m)->md_dict;
531 [ + - + + ]: 9524 : if (d == NULL ||
532 [ - + ]: 6391 : (fileobj = PyDict_GetItemWithError(d, &_Py_ID(__file__))) == NULL ||
533 : 1629 : !PyUnicode_Check(fileobj))
534 : : {
535 [ + - ]: 3133 : if (!PyErr_Occurred()) {
536 : 3133 : PyErr_SetString(PyExc_SystemError, "module filename missing");
537 : : }
538 : 3133 : return NULL;
539 : : }
540 : 1629 : Py_INCREF(fileobj);
541 : 1629 : return fileobj;
542 : : }
543 : :
544 : : const char *
545 : 0 : PyModule_GetFilename(PyObject *m)
546 : : {
547 : : PyObject *fileobj;
548 : : const char *utf8;
549 : 0 : fileobj = PyModule_GetFilenameObject(m);
550 [ # # ]: 0 : if (fileobj == NULL)
551 : 0 : return NULL;
552 : 0 : utf8 = PyUnicode_AsUTF8(fileobj);
553 : 0 : Py_DECREF(fileobj); /* module dict has still a reference */
554 : 0 : return utf8;
555 : : }
556 : :
557 : : PyModuleDef*
558 : 119615 : PyModule_GetDef(PyObject* m)
559 : : {
560 [ - + ]: 119615 : if (!PyModule_Check(m)) {
561 : 0 : PyErr_BadArgument();
562 : 0 : return NULL;
563 : : }
564 : 119615 : return _PyModule_GetDef(m);
565 : : }
566 : :
567 : : void*
568 : 742384 : PyModule_GetState(PyObject* m)
569 : : {
570 [ - + ]: 742384 : if (!PyModule_Check(m)) {
571 : 0 : PyErr_BadArgument();
572 : 0 : return NULL;
573 : : }
574 : 742384 : return _PyModule_GetState(m);
575 : : }
576 : :
577 : : void
578 : 132661 : _PyModule_Clear(PyObject *m)
579 : : {
580 : 132661 : PyObject *d = ((PyModuleObject *)m)->md_dict;
581 [ + - ]: 132661 : if (d != NULL)
582 : 132661 : _PyModule_ClearDict(d);
583 : 132661 : }
584 : :
585 : : void
586 : 138911 : _PyModule_ClearDict(PyObject *d)
587 : : {
588 : : /* To make the execution order of destructors for global
589 : : objects a bit more predictable, we first zap all objects
590 : : whose name starts with a single underscore, before we clear
591 : : the entire dictionary. We zap them by replacing them with
592 : : None, rather than deleting them from the dictionary, to
593 : : avoid rehashing the dictionary (to some extent). */
594 : :
595 : : Py_ssize_t pos;
596 : : PyObject *key, *value;
597 : :
598 : 138911 : int verbose = _Py_GetConfig()->verbose;
599 : :
600 : : /* First, clear only names starting with a single underscore */
601 : 138911 : pos = 0;
602 [ + + ]: 8854018 : while (PyDict_Next(d, &pos, &key, &value)) {
603 [ + + - + ]: 8576196 : if (value != Py_None && PyUnicode_Check(key)) {
604 [ + + + + ]: 10097736 : if (PyUnicode_READ_CHAR(key, 0) == '_' &&
605 : 1867896 : PyUnicode_READ_CHAR(key, 1) != '_') {
606 [ + + ]: 920908 : if (verbose > 1) {
607 : 438 : const char *s = PyUnicode_AsUTF8(key);
608 [ + - ]: 438 : if (s != NULL)
609 : 438 : PySys_WriteStderr("# clear[1] %s\n", s);
610 : : else
611 : 0 : PyErr_Clear();
612 : : }
613 [ + - ]: 920908 : if (PyDict_SetItem(d, key, Py_None) != 0) {
614 : 0 : PyErr_WriteUnraisable(NULL);
615 : : }
616 : : }
617 : : }
618 : : }
619 : :
620 : : /* Next, clear all names except for __builtins__ */
621 : 138911 : pos = 0;
622 [ + + ]: 8854019 : while (PyDict_Next(d, &pos, &key, &value)) {
623 [ + + - + ]: 8576197 : if (value != Py_None && PyUnicode_Check(key)) {
624 [ + + + + ]: 8255922 : if (PyUnicode_READ_CHAR(key, 0) != '_' ||
625 : 946989 : !_PyUnicode_EqualToASCIIString(key, "__builtins__"))
626 : : {
627 [ + + ]: 7235720 : if (verbose > 1) {
628 : 3669 : const char *s = PyUnicode_AsUTF8(key);
629 [ + - ]: 3669 : if (s != NULL)
630 : 3669 : PySys_WriteStderr("# clear[2] %s\n", s);
631 : : else
632 : 0 : PyErr_Clear();
633 : : }
634 [ - + ]: 7235720 : if (PyDict_SetItem(d, key, Py_None) != 0) {
635 : 0 : PyErr_WriteUnraisable(NULL);
636 : : }
637 : : }
638 : : }
639 : : }
640 : :
641 : : /* Note: we leave __builtins__ in place, so that destructors
642 : : of non-global objects defined in this module can still use
643 : : builtins, in particularly 'None'. */
644 : :
645 : 138911 : }
646 : :
647 : : /*[clinic input]
648 : : class module "PyModuleObject *" "&PyModule_Type"
649 : : [clinic start generated code]*/
650 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3e35d4f708ecb6af]*/
651 : :
652 : : #include "clinic/moduleobject.c.h"
653 : :
654 : : /* Methods */
655 : :
656 : : /*[clinic input]
657 : : module.__init__
658 : : name: unicode
659 : : doc: object = None
660 : :
661 : : Create a module object.
662 : :
663 : : The name must be a string; the optional doc argument can have any type.
664 : : [clinic start generated code]*/
665 : :
666 : : static int
667 : 210619 : module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc)
668 : : /*[clinic end generated code: output=e7e721c26ce7aad7 input=57f9e177401e5e1e]*/
669 : : {
670 : 210619 : PyObject *dict = self->md_dict;
671 [ - + ]: 210619 : if (dict == NULL) {
672 : 0 : dict = PyDict_New();
673 [ # # ]: 0 : if (dict == NULL)
674 : 0 : return -1;
675 : 0 : self->md_dict = dict;
676 : : }
677 [ - + ]: 210619 : if (module_init_dict(self, dict, name, doc) < 0)
678 : 0 : return -1;
679 : 210619 : return 0;
680 : : }
681 : :
682 : : static void
683 : 305569 : module_dealloc(PyModuleObject *m)
684 : : {
685 : 305569 : int verbose = _Py_GetConfig()->verbose;
686 : :
687 : 305569 : PyObject_GC_UnTrack(m);
688 [ + + + - ]: 305569 : if (verbose && m->md_name) {
689 : 614 : PySys_FormatStderr("# destroy %U\n", m->md_name);
690 : : }
691 [ + + ]: 305569 : if (m->md_weaklist != NULL)
692 : 87149 : PyObject_ClearWeakRefs((PyObject *) m);
693 : : /* bpo-39824: Don't call m_free() if m_size > 0 and md_state=NULL */
694 [ + + + + ]: 305569 : if (m->md_def && m->md_def->m_free
695 [ + + + - ]: 42038 : && (m->md_def->m_size <= 0 || m->md_state != NULL))
696 : : {
697 : 42038 : m->md_def->m_free(m);
698 : : }
699 : 305569 : Py_XDECREF(m->md_dict);
700 : 305569 : Py_XDECREF(m->md_name);
701 [ + + ]: 305569 : if (m->md_state != NULL)
702 : 82042 : PyMem_Free(m->md_state);
703 : 305569 : Py_TYPE(m)->tp_free((PyObject *)m);
704 : 305569 : }
705 : :
706 : : static PyObject *
707 : 7057 : module_repr(PyModuleObject *m)
708 : : {
709 : 7057 : PyInterpreterState *interp = _PyInterpreterState_GET();
710 : :
711 : 7057 : return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m);
712 : : }
713 : :
714 : : /* Check if the "_initializing" attribute of the module spec is set to true.
715 : : Clear the exception and return 0 if spec is NULL.
716 : : */
717 : : int
718 : 3839373 : _PyModuleSpec_IsInitializing(PyObject *spec)
719 : : {
720 [ + + ]: 3839373 : if (spec != NULL) {
721 : 3839299 : PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_initializing));
722 [ + + ]: 3839299 : if (value != NULL) {
723 : 2811608 : int initializing = PyObject_IsTrue(value);
724 : 2811608 : Py_DECREF(value);
725 [ + - ]: 2811608 : if (initializing >= 0) {
726 : 2811608 : return initializing;
727 : : }
728 : : }
729 : : }
730 : 1027765 : PyErr_Clear();
731 : 1027765 : return 0;
732 : : }
733 : :
734 : : /* Check if the submodule name is in the "_uninitialized_submodules" attribute
735 : : of the module spec.
736 : : */
737 : : int
738 : 1868335 : _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
739 : : {
740 [ + + ]: 1868335 : if (spec == NULL) {
741 : 31 : return 0;
742 : : }
743 : :
744 : 1868304 : PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_uninitialized_submodules));
745 [ + + ]: 1868304 : if (value == NULL) {
746 : 38186 : return 0;
747 : : }
748 : :
749 : 1830118 : int is_uninitialized = PySequence_Contains(value, name);
750 : 1830118 : Py_DECREF(value);
751 [ - + ]: 1830118 : if (is_uninitialized == -1) {
752 : 0 : return 0;
753 : : }
754 : 1830118 : return is_uninitialized;
755 : : }
756 : :
757 : : static PyObject*
758 : 21586038 : module_getattro(PyModuleObject *m, PyObject *name)
759 : : {
760 : : PyObject *attr, *mod_name, *getattr;
761 : 21586038 : attr = PyObject_GenericGetAttr((PyObject *)m, name);
762 [ + + + + ]: 21586038 : if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) {
763 : 19692789 : return attr;
764 : : }
765 : 1893249 : PyErr_Clear();
766 : : assert(m->md_dict != NULL);
767 : 1893249 : getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__));
768 [ + + ]: 1893249 : if (getattr) {
769 : 5213 : return PyObject_CallOneArg(getattr, name);
770 : : }
771 [ - + ]: 1888036 : if (PyErr_Occurred()) {
772 : 0 : return NULL;
773 : : }
774 : 1888036 : mod_name = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__name__));
775 [ + + + + ]: 1888036 : if (mod_name && PyUnicode_Check(mod_name)) {
776 : 1887999 : Py_INCREF(mod_name);
777 : 1887999 : PyObject *spec = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__spec__));
778 [ + + - + ]: 1887999 : if (spec == NULL && PyErr_Occurred()) {
779 : 0 : Py_DECREF(mod_name);
780 : 0 : return NULL;
781 : : }
782 : 1887999 : Py_XINCREF(spec);
783 [ + + ]: 1887999 : if (_PyModuleSpec_IsInitializing(spec)) {
784 : 19664 : PyErr_Format(PyExc_AttributeError,
785 : : "partially initialized "
786 : : "module '%U' has no attribute '%U' "
787 : : "(most likely due to a circular import)",
788 : : mod_name, name);
789 : : }
790 [ + + ]: 1868335 : else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
791 : 14 : PyErr_Format(PyExc_AttributeError,
792 : : "cannot access submodule '%U' of module '%U' "
793 : : "(most likely due to a circular import)",
794 : : name, mod_name);
795 : : }
796 : : else {
797 : 1868321 : PyErr_Format(PyExc_AttributeError,
798 : : "module '%U' has no attribute '%U'",
799 : : mod_name, name);
800 : : }
801 : 1887999 : Py_XDECREF(spec);
802 : 1887999 : Py_DECREF(mod_name);
803 : 1887999 : return NULL;
804 : : }
805 [ - + ]: 37 : else if (PyErr_Occurred()) {
806 : 0 : return NULL;
807 : : }
808 : 37 : PyErr_Format(PyExc_AttributeError,
809 : : "module has no attribute '%U'", name);
810 : 37 : return NULL;
811 : : }
812 : :
813 : : static int
814 : 8012087 : module_traverse(PyModuleObject *m, visitproc visit, void *arg)
815 : : {
816 : : /* bpo-39824: Don't call m_traverse() if m_size > 0 and md_state=NULL */
817 [ + + + + ]: 8012087 : if (m->md_def && m->md_def->m_traverse
818 [ + + + + ]: 1001020 : && (m->md_def->m_size <= 0 || m->md_state != NULL))
819 : : {
820 : 994822 : int res = m->md_def->m_traverse((PyObject*)m, visit, arg);
821 [ - + ]: 994822 : if (res)
822 : 0 : return res;
823 : : }
824 [ + - + + ]: 8012087 : Py_VISIT(m->md_dict);
825 : 8012050 : return 0;
826 : : }
827 : :
828 : : static int
829 : 114648 : module_clear(PyModuleObject *m)
830 : : {
831 : : /* bpo-39824: Don't call m_clear() if m_size > 0 and md_state=NULL */
832 [ + + + + ]: 114648 : if (m->md_def && m->md_def->m_clear
833 [ + - + - ]: 31670 : && (m->md_def->m_size <= 0 || m->md_state != NULL))
834 : : {
835 : 31670 : int res = m->md_def->m_clear((PyObject*)m);
836 [ - + ]: 31670 : if (PyErr_Occurred()) {
837 : 0 : PySys_FormatStderr("Exception ignored in m_clear of module%s%V\n",
838 [ # # ]: 0 : m->md_name ? " " : "",
839 : : m->md_name, "");
840 : 0 : PyErr_WriteUnraisable(NULL);
841 : : }
842 [ - + ]: 31670 : if (res)
843 : 0 : return res;
844 : : }
845 [ + - ]: 114648 : Py_CLEAR(m->md_dict);
846 : 114648 : return 0;
847 : : }
848 : :
849 : : static PyObject *
850 : 6288 : module_dir(PyObject *self, PyObject *args)
851 : : {
852 : 6288 : PyObject *result = NULL;
853 : 6288 : PyObject *dict = PyObject_GetAttr(self, &_Py_ID(__dict__));
854 : :
855 [ + - ]: 6288 : if (dict != NULL) {
856 [ + + ]: 6288 : if (PyDict_Check(dict)) {
857 : 6286 : PyObject *dirfunc = PyDict_GetItemWithError(dict, &_Py_ID(__dir__));
858 [ + + ]: 6286 : if (dirfunc) {
859 : 9 : result = _PyObject_CallNoArgs(dirfunc);
860 : : }
861 [ + - ]: 6277 : else if (!PyErr_Occurred()) {
862 : 6277 : result = PyDict_Keys(dict);
863 : : }
864 : : }
865 : : else {
866 : 2 : PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
867 : : }
868 : : }
869 : :
870 : 6288 : Py_XDECREF(dict);
871 : 6288 : return result;
872 : : }
873 : :
874 : : static PyMethodDef module_methods[] = {
875 : : {"__dir__", module_dir, METH_NOARGS,
876 : : PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")},
877 : : {0}
878 : : };
879 : :
880 : : static PyObject *
881 : 69 : module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
882 : : {
883 : 69 : PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
884 : :
885 [ + - - + ]: 69 : if ((dict == NULL) || !PyDict_Check(dict)) {
886 : 0 : PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
887 : 0 : Py_XDECREF(dict);
888 : 0 : return NULL;
889 : : }
890 : :
891 : : PyObject *annotations;
892 : : /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */
893 [ + + ]: 69 : if (PyDict_Contains(dict, &_Py_ID(__annotations__))) {
894 : 61 : annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
895 : : /*
896 : : ** _PyDict_GetItemIdWithError could still fail,
897 : : ** for instance with a well-timed Ctrl-C or a MemoryError.
898 : : ** so let's be totally safe.
899 : : */
900 [ + - ]: 61 : if (annotations) {
901 : 61 : Py_INCREF(annotations);
902 : : }
903 : : } else {
904 : 8 : annotations = PyDict_New();
905 [ + - ]: 8 : if (annotations) {
906 : 8 : int result = PyDict_SetItem(
907 : : dict, &_Py_ID(__annotations__), annotations);
908 [ - + ]: 8 : if (result) {
909 [ # # ]: 0 : Py_CLEAR(annotations);
910 : : }
911 : : }
912 : : }
913 : 69 : Py_DECREF(dict);
914 : 69 : return annotations;
915 : : }
916 : :
917 : : static int
918 : 12 : module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignored))
919 : : {
920 : 12 : int ret = -1;
921 : 12 : PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
922 : :
923 [ + - - + ]: 12 : if ((dict == NULL) || !PyDict_Check(dict)) {
924 : 0 : PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
925 : 0 : goto exit;
926 : : }
927 : :
928 [ + + ]: 12 : if (value != NULL) {
929 : : /* set */
930 : 5 : ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
931 : 5 : goto exit;
932 : : }
933 : :
934 : : /* delete */
935 [ + + ]: 7 : if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) {
936 : 1 : PyErr_Format(PyExc_AttributeError, "__annotations__");
937 : 1 : goto exit;
938 : : }
939 : :
940 : 6 : ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
941 : :
942 : 12 : exit:
943 : 12 : Py_XDECREF(dict);
944 : 12 : return ret;
945 : : }
946 : :
947 : :
948 : : static PyGetSetDef module_getsets[] = {
949 : : {"__annotations__", (getter)module_get_annotations, (setter)module_set_annotations},
950 : : {NULL}
951 : : };
952 : :
953 : : PyTypeObject PyModule_Type = {
954 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
955 : : "module", /* tp_name */
956 : : sizeof(PyModuleObject), /* tp_basicsize */
957 : : 0, /* tp_itemsize */
958 : : (destructor)module_dealloc, /* tp_dealloc */
959 : : 0, /* tp_vectorcall_offset */
960 : : 0, /* tp_getattr */
961 : : 0, /* tp_setattr */
962 : : 0, /* tp_as_async */
963 : : (reprfunc)module_repr, /* tp_repr */
964 : : 0, /* tp_as_number */
965 : : 0, /* tp_as_sequence */
966 : : 0, /* tp_as_mapping */
967 : : 0, /* tp_hash */
968 : : 0, /* tp_call */
969 : : 0, /* tp_str */
970 : : (getattrofunc)module_getattro, /* tp_getattro */
971 : : PyObject_GenericSetAttr, /* tp_setattro */
972 : : 0, /* tp_as_buffer */
973 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
974 : : Py_TPFLAGS_BASETYPE, /* tp_flags */
975 : : module___init____doc__, /* tp_doc */
976 : : (traverseproc)module_traverse, /* tp_traverse */
977 : : (inquiry)module_clear, /* tp_clear */
978 : : 0, /* tp_richcompare */
979 : : offsetof(PyModuleObject, md_weaklist), /* tp_weaklistoffset */
980 : : 0, /* tp_iter */
981 : : 0, /* tp_iternext */
982 : : module_methods, /* tp_methods */
983 : : module_members, /* tp_members */
984 : : module_getsets, /* tp_getset */
985 : : 0, /* tp_base */
986 : : 0, /* tp_dict */
987 : : 0, /* tp_descr_get */
988 : : 0, /* tp_descr_set */
989 : : offsetof(PyModuleObject, md_dict), /* tp_dictoffset */
990 : : module___init__, /* tp_init */
991 : : 0, /* tp_alloc */
992 : : new_module, /* tp_new */
993 : : PyObject_GC_Del, /* tp_free */
994 : : };
|