LCOV - code coverage report
Current view: top level - Objects - moduleobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 45 106 42.5 %
Date: 2017-04-19 Functions: 5 9 55.6 %

          Line data    Source code
       1             : 
       2             : /* Module object implementation */
       3             : 
       4             : #include "Python.h"
       5             : #include "structmember.h"
       6             : 
       7             : typedef struct {
       8             :     PyObject_HEAD
       9             :     PyObject *md_dict;
      10             : } PyModuleObject;
      11             : 
      12             : static PyMemberDef module_members[] = {
      13             :     {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
      14             :     {0}
      15             : };
      16             : 
      17             : PyObject *
      18         363 : PyModule_New(const char *name)
      19             : {
      20             :     PyModuleObject *m;
      21             :     PyObject *nameobj;
      22         363 :     m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
      23         363 :     if (m == NULL)
      24           0 :         return NULL;
      25         363 :     nameobj = PyString_FromString(name);
      26         363 :     m->md_dict = PyDict_New();
      27         363 :     if (m->md_dict == NULL || nameobj == NULL)
      28             :         goto fail;
      29         363 :     if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
      30           0 :         goto fail;
      31         363 :     if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
      32           0 :         goto fail;
      33         363 :     if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)
      34           0 :         goto fail;
      35         363 :     Py_DECREF(nameobj);
      36         363 :     PyObject_GC_Track(m);
      37         363 :     return (PyObject *)m;
      38             : 
      39             :  fail:
      40           0 :     Py_XDECREF(nameobj);
      41           0 :     Py_DECREF(m);
      42           0 :     return NULL;
      43             : }
      44             : 
      45             : PyObject *
      46        1383 : PyModule_GetDict(PyObject *m)
      47             : {
      48             :     PyObject *d;
      49        1383 :     if (!PyModule_Check(m)) {
      50           0 :         PyErr_BadInternalCall();
      51           0 :         return NULL;
      52             :     }
      53        1383 :     d = ((PyModuleObject *)m) -> md_dict;
      54        1383 :     if (d == NULL)
      55           0 :         ((PyModuleObject *)m) -> md_dict = d = PyDict_New();
      56        1383 :     return d;
      57             : }
      58             : 
      59             : char *
      60           0 : PyModule_GetName(PyObject *m)
      61             : {
      62             :     PyObject *d;
      63             :     PyObject *nameobj;
      64           0 :     if (!PyModule_Check(m)) {
      65           0 :         PyErr_BadArgument();
      66           0 :         return NULL;
      67             :     }
      68           0 :     d = ((PyModuleObject *)m)->md_dict;
      69           0 :     if (d == NULL ||
      70           0 :         (nameobj = PyDict_GetItemString(d, "__name__")) == NULL ||
      71           0 :         !PyString_Check(nameobj))
      72             :     {
      73           0 :         PyErr_SetString(PyExc_SystemError, "nameless module");
      74           0 :         return NULL;
      75             :     }
      76           0 :     return PyString_AsString(nameobj);
      77             : }
      78             : 
      79             : char *
      80           0 : PyModule_GetFilename(PyObject *m)
      81             : {
      82             :     PyObject *d;
      83             :     PyObject *fileobj;
      84           0 :     if (!PyModule_Check(m)) {
      85           0 :         PyErr_BadArgument();
      86           0 :         return NULL;
      87             :     }
      88           0 :     d = ((PyModuleObject *)m)->md_dict;
      89           0 :     if (d == NULL ||
      90           0 :         (fileobj = PyDict_GetItemString(d, "__file__")) == NULL ||
      91           0 :         !PyString_Check(fileobj))
      92             :     {
      93           0 :         PyErr_SetString(PyExc_SystemError, "module filename missing");
      94           0 :         return NULL;
      95             :     }
      96           0 :     return PyString_AsString(fileobj);
      97             : }
      98             : 
      99             : void
     100         720 : _PyModule_Clear(PyObject *m)
     101             : {
     102             :     /* To make the execution order of destructors for global
     103             :        objects a bit more predictable, we first zap all objects
     104             :        whose name starts with a single underscore, before we clear
     105             :        the entire dictionary.  We zap them by replacing them with
     106             :        None, rather than deleting them from the dictionary, to
     107             :        avoid rehashing the dictionary (to some extent). */
     108             : 
     109             :     Py_ssize_t pos;
     110             :     PyObject *key, *value;
     111             :     PyObject *d;
     112             : 
     113         720 :     d = ((PyModuleObject *)m)->md_dict;
     114         720 :     if (d == NULL)
     115         720 :         return;
     116             : 
     117             :     /* First, clear only names starting with a single underscore */
     118         720 :     pos = 0;
     119       26868 :     while (PyDict_Next(d, &pos, &key, &value)) {
     120       25428 :         if (value != Py_None && PyString_Check(key)) {
     121       13104 :             char *s = PyString_AsString(key);
     122       13104 :             if (s[0] == '_' && s[1] != '_') {
     123        1035 :                 if (Py_VerboseFlag > 1)
     124           0 :                     PySys_WriteStderr("#   clear[1] %s\n", s);
     125        1035 :                 if (PyDict_SetItem(d, key, Py_None) != 0)
     126           0 :                     PyErr_Clear();
     127             :             }
     128             :         }
     129             :     }
     130             : 
     131             :     /* Next, clear all names except for __builtins__ */
     132         720 :     pos = 0;
     133       26868 :     while (PyDict_Next(d, &pos, &key, &value)) {
     134       25428 :         if (value != Py_None && PyString_Check(key)) {
     135       12069 :             char *s = PyString_AsString(key);
     136       12069 :             if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
     137       11538 :                 if (Py_VerboseFlag > 1)
     138           0 :                     PySys_WriteStderr("#   clear[2] %s\n", s);
     139       11538 :                 if (PyDict_SetItem(d, key, Py_None) != 0)
     140           0 :                     PyErr_Clear();
     141             :             }
     142             :         }
     143             :     }
     144             : 
     145             :     /* Note: we leave __builtins__ in place, so that destructors
     146             :        of non-global objects defined in this module can still use
     147             :        builtins, in particularly 'None'. */
     148             : 
     149             : }
     150             : 
     151             : /* Methods */
     152             : 
     153             : static int
     154           0 : module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
     155             : {
     156             :     static char *kwlist[] = {"name", "doc", NULL};
     157           0 :     PyObject *dict, *name = Py_None, *doc = Py_None;
     158           0 :     if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
     159             :                                      kwlist, &name, &doc))
     160           0 :         return -1;
     161           0 :     dict = m->md_dict;
     162           0 :     if (dict == NULL) {
     163           0 :         dict = PyDict_New();
     164           0 :         if (dict == NULL)
     165           0 :             return -1;
     166           0 :         m->md_dict = dict;
     167             :     }
     168           0 :     if (PyDict_SetItemString(dict, "__name__", name) < 0)
     169           0 :         return -1;
     170           0 :     if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
     171           0 :         return -1;
     172           0 :     return 0;
     173             : }
     174             : 
     175             : static void
     176         354 : module_dealloc(PyModuleObject *m)
     177             : {
     178         354 :     PyObject_GC_UnTrack(m);
     179         354 :     if (m->md_dict != NULL) {
     180         354 :         _PyModule_Clear((PyObject *)m);
     181         354 :         Py_DECREF(m->md_dict);
     182             :     }
     183         354 :     Py_TYPE(m)->tp_free((PyObject *)m);
     184         354 : }
     185             : 
     186             : static PyObject *
     187           0 : module_repr(PyModuleObject *m)
     188             : {
     189             :     char *name;
     190             :     char *filename;
     191             : 
     192           0 :     name = PyModule_GetName((PyObject *)m);
     193           0 :     if (name == NULL) {
     194           0 :         PyErr_Clear();
     195           0 :         name = "?";
     196             :     }
     197           0 :     filename = PyModule_GetFilename((PyObject *)m);
     198           0 :     if (filename == NULL) {
     199           0 :         PyErr_Clear();
     200           0 :         return PyString_FromFormat("<module '%s' (built-in)>", name);
     201             :     }
     202           0 :     return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
     203             : }
     204             : 
     205             : /* We only need a traverse function, no clear function: If the module
     206             :    is in a cycle, md_dict will be cleared as well, which will break
     207             :    the cycle. */
     208             : static int
     209        2088 : module_traverse(PyModuleObject *m, visitproc visit, void *arg)
     210             : {
     211        2088 :     Py_VISIT(m->md_dict);
     212        2088 :     return 0;
     213             : }
     214             : 
     215             : PyDoc_STRVAR(module_doc,
     216             : "module(name[, doc])\n\
     217             : \n\
     218             : Create a module object.\n\
     219             : The name must be a string; the optional doc argument can have any type.");
     220             : 
     221             : PyTypeObject PyModule_Type = {
     222             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     223             :     "module",                                   /* tp_name */
     224             :     sizeof(PyModuleObject),                     /* tp_size */
     225             :     0,                                          /* tp_itemsize */
     226             :     (destructor)module_dealloc,                 /* tp_dealloc */
     227             :     0,                                          /* tp_print */
     228             :     0,                                          /* tp_getattr */
     229             :     0,                                          /* tp_setattr */
     230             :     0,                                          /* tp_compare */
     231             :     (reprfunc)module_repr,                      /* tp_repr */
     232             :     0,                                          /* tp_as_number */
     233             :     0,                                          /* tp_as_sequence */
     234             :     0,                                          /* tp_as_mapping */
     235             :     0,                                          /* tp_hash */
     236             :     0,                                          /* tp_call */
     237             :     0,                                          /* tp_str */
     238             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     239             :     PyObject_GenericSetAttr,                    /* tp_setattro */
     240             :     0,                                          /* tp_as_buffer */
     241             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     242             :         Py_TPFLAGS_BASETYPE,                    /* tp_flags */
     243             :     module_doc,                                 /* tp_doc */
     244             :     (traverseproc)module_traverse,              /* tp_traverse */
     245             :     0,                                          /* tp_clear */
     246             :     0,                                          /* tp_richcompare */
     247             :     0,                                          /* tp_weaklistoffset */
     248             :     0,                                          /* tp_iter */
     249             :     0,                                          /* tp_iternext */
     250             :     0,                                          /* tp_methods */
     251             :     module_members,                             /* tp_members */
     252             :     0,                                          /* tp_getset */
     253             :     0,                                          /* tp_base */
     254             :     0,                                          /* tp_dict */
     255             :     0,                                          /* tp_descr_get */
     256             :     0,                                          /* tp_descr_set */
     257             :     offsetof(PyModuleObject, md_dict),          /* tp_dictoffset */
     258             :     (initproc)module_init,                      /* tp_init */
     259             :     PyType_GenericAlloc,                        /* tp_alloc */
     260             :     PyType_GenericNew,                          /* tp_new */
     261             :     PyObject_GC_Del,                            /* tp_free */
     262             : };

Generated by: LCOV version 1.10