diff options
Diffstat (limited to 'Objects/moduleobject.c')
| -rw-r--r-- | Objects/moduleobject.c | 135 | 
1 files changed, 108 insertions, 27 deletions
| diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 533db46efa..2f2bd36b55 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -27,36 +27,45 @@ static PyTypeObject moduledef_type = {  PyObject * -PyModule_New(const char *name) +PyModule_NewObject(PyObject *name)  {      PyModuleObject *m; -    PyObject *nameobj;      m = PyObject_GC_New(PyModuleObject, &PyModule_Type);      if (m == NULL)          return NULL;      m->md_def = NULL;      m->md_state = NULL; -    nameobj = PyUnicode_FromString(name);      m->md_dict = PyDict_New(); -    if (m->md_dict == NULL || nameobj == NULL) +    if (m->md_dict == NULL)          goto fail; -    if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0) +    if (PyDict_SetItemString(m->md_dict, "__name__", name) != 0)          goto fail;      if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)          goto fail;      if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)          goto fail; -    Py_DECREF(nameobj);      PyObject_GC_Track(m);      return (PyObject *)m;   fail: -    Py_XDECREF(nameobj);      Py_DECREF(m);      return NULL;  }  PyObject * +PyModule_New(const char *name) +{ +    PyObject *nameobj, *module; +    nameobj = PyUnicode_FromString(name); +    if (nameobj == NULL) +        return NULL; +    module = PyModule_NewObject(nameobj); +    Py_DECREF(nameobj); +    return module; +} + + +PyObject *  PyModule_Create2(struct PyModuleDef* module, int module_api_version)  {      PyObject *d, *v, *n; @@ -175,24 +184,35 @@ PyModule_GetDict(PyObject *m)      return d;  } -const char * -PyModule_GetName(PyObject *m) +PyObject* +PyModule_GetNameObject(PyObject *m)  {      PyObject *d; -    PyObject *nameobj; +    PyObject *name;      if (!PyModule_Check(m)) {          PyErr_BadArgument();          return NULL;      }      d = ((PyModuleObject *)m)->md_dict;      if (d == NULL || -        (nameobj = PyDict_GetItemString(d, "__name__")) == NULL || -        !PyUnicode_Check(nameobj)) +        (name = PyDict_GetItemString(d, "__name__")) == NULL || +        !PyUnicode_Check(name))      {          PyErr_SetString(PyExc_SystemError, "nameless module");          return NULL;      } -    return _PyUnicode_AsString(nameobj); +    Py_INCREF(name); +    return name; +} + +const char * +PyModule_GetName(PyObject *m) +{ +    PyObject *name = PyModule_GetNameObject(m); +    if (name == NULL) +        return NULL; +    Py_DECREF(name);   /* module dict has still a reference */ +    return _PyUnicode_AsString(name);  }  PyObject* @@ -225,7 +245,7 @@ PyModule_GetFilename(PyObject *m)      if (fileobj == NULL)          return NULL;      utf8 = _PyUnicode_AsString(fileobj); -    Py_DECREF(fileobj); +    Py_DECREF(fileobj);   /* module dict has still a reference */      return utf8;  } @@ -271,8 +291,8 @@ _PyModule_Clear(PyObject *m)      pos = 0;      while (PyDict_Next(d, &pos, &key, &value)) {          if (value != Py_None && PyUnicode_Check(key)) { -            Py_UNICODE *u = PyUnicode_AS_UNICODE(key); -            if (u[0] == '_' && u[1] != '_') { +            if (PyUnicode_READ_CHAR(key, 0) == '_' && +                PyUnicode_READ_CHAR(key, 1) != '_') {                  if (Py_VerboseFlag > 1) {                      const char *s = _PyUnicode_AsString(key);                      if (s != NULL) @@ -289,9 +309,8 @@ _PyModule_Clear(PyObject *m)      pos = 0;      while (PyDict_Next(d, &pos, &key, &value)) {          if (value != Py_None && PyUnicode_Check(key)) { -            Py_UNICODE *u = PyUnicode_AS_UNICODE(key); -            if (u[0] != '_' -                || PyUnicode_CompareWithASCIIString(key, "__builtins__") != 0) +            if (PyUnicode_READ_CHAR(key, 0) != '_' || +                PyUnicode_CompareWithASCIIString(key, "__builtins__") != 0)              {                  if (Py_VerboseFlag > 1) {                      const char *s = _PyUnicode_AsString(key); @@ -353,21 +372,54 @@ module_dealloc(PyModuleObject *m)  static PyObject *  module_repr(PyModuleObject *m)  { -    const char *name; -    PyObject *filename, *repr; +    PyObject *name, *filename, *repr, *loader = NULL; -    name = PyModule_GetName((PyObject *)m); +    /* See if the module has an __loader__.  If it does, give the loader the +     * first shot at producing a repr for the module. +     */ +    if (m->md_dict != NULL) { +        loader = PyDict_GetItemString(m->md_dict, "__loader__"); +    } +    if (loader != NULL) { +        repr = PyObject_CallMethod(loader, "module_repr", "(O)", +                                   (PyObject *)m, NULL); +        if (repr == NULL) { +            PyErr_Clear(); +        } +        else { +            return repr; +        } +    } +    /* __loader__.module_repr(m) did not provide us with a repr.  Next, see if +     * the module has an __file__.  If it doesn't then use repr(__loader__) if +     * it exists, otherwise, just use module.__name__. +     */ +    name = PyModule_GetNameObject((PyObject *)m);      if (name == NULL) {          PyErr_Clear(); -        name = "?"; +        name = PyUnicode_FromStringAndSize("?", 1); +        if (name == NULL) +            return NULL;      }      filename = PyModule_GetFilenameObject((PyObject *)m);      if (filename == NULL) {          PyErr_Clear(); -        return PyUnicode_FromFormat("<module '%s' (built-in)>", name); +        /* There's no m.__file__, so if there was an __loader__, use that in +         * the repr, otherwise, the only thing you can use is m.__name__ +         */ +        if (loader == NULL) { +            repr = PyUnicode_FromFormat("<module %R>", name); +        } +        else { +            repr = PyUnicode_FromFormat("<module %R (%R)>", name, loader); +        } +    } +    /* Finally, use m.__file__ */ +    else { +        repr = PyUnicode_FromFormat("<module %R from %R>", name, filename); +        Py_DECREF(filename);      } -    repr = PyUnicode_FromFormat("<module '%s' from '%U'>", name, filename); -    Py_DECREF(filename); +    Py_DECREF(name);      return repr;  } @@ -395,6 +447,35 @@ module_clear(PyModuleObject *m)      return 0;  } +static PyObject * +module_dir(PyObject *self, PyObject *args) +{ +    _Py_IDENTIFIER(__dict__); +    PyObject *result = NULL; +    PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__); + +    if (dict != NULL) { +        if (PyDict_Check(dict)) +            result = PyDict_Keys(dict); +        else { +            const char *name = PyModule_GetName(self); +            if (name) +                PyErr_Format(PyExc_TypeError, +                             "%.200s.__dict__ is not a dictionary", +                             name); +        } +    } + +    Py_XDECREF(dict); +    return result; +} + +static PyMethodDef module_methods[] = { +    {"__dir__", module_dir, METH_NOARGS, +     PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")}, +    {0} +}; +  PyDoc_STRVAR(module_doc,  "module(name[, doc])\n\ @@ -431,7 +512,7 @@ PyTypeObject PyModule_Type = {      0,                                          /* tp_weaklistoffset */      0,                                          /* tp_iter */      0,                                          /* tp_iternext */ -    0,                                          /* tp_methods */ +    module_methods,                             /* tp_methods */      module_members,                             /* tp_members */      0,                                          /* tp_getset */      0,                                          /* tp_base */ | 
