diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2007-12-03 12:55:17 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2007-12-03 12:55:17 (GMT) |
commit | ef01d822aaea11ae25f78cb0be32865a5df07620 (patch) | |
tree | 0fbbaa653cb033490019809a9eb8b3c3ac942c74 /Python/import.c | |
parent | f19b95112669db32556c157c04f064d319c11f09 (diff) | |
download | cpython-ef01d822aaea11ae25f78cb0be32865a5df07620.zip cpython-ef01d822aaea11ae25f78cb0be32865a5df07620.tar.gz cpython-ef01d822aaea11ae25f78cb0be32865a5df07620.tar.bz2 |
Implement PEP 366
Diffstat (limited to 'Python/import.c')
-rw-r--r-- | Python/import.c | 112 |
1 files changed, 86 insertions, 26 deletions
diff --git a/Python/import.c b/Python/import.c index 59a51bc..bf2799d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2106,7 +2106,8 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level) { static PyObject *namestr = NULL; static PyObject *pathstr = NULL; - PyObject *modname, *modpath, *modules, *parent; + static PyObject *pkgstr = NULL; + PyObject *pkgname, *modname, *modpath, *modules, *parent; if (globals == NULL || !PyDict_Check(globals) || !level) return Py_None; @@ -2121,44 +2122,103 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level) if (pathstr == NULL) return NULL; } + if (pkgstr == NULL) { + pkgstr = PyString_InternFromString("__package__"); + if (pkgstr == NULL) + return NULL; + } *buf = '\0'; *p_buflen = 0; - modname = PyDict_GetItem(globals, namestr); - if (modname == NULL || !PyString_Check(modname)) - return Py_None; + pkgname = PyDict_GetItem(globals, pkgstr); - modpath = PyDict_GetItem(globals, pathstr); - if (modpath != NULL) { - Py_ssize_t len = PyString_GET_SIZE(modname); - if (len > MAXPATHLEN) { + if ((pkgname != NULL) && (pkgname != Py_None)) { + /* __package__ is set, so use it */ + Py_ssize_t len; + if (!PyString_Check(pkgname)) { PyErr_SetString(PyExc_ValueError, - "Module name too long"); + "__package__ set to non-string"); return NULL; } - strcpy(buf, PyString_AS_STRING(modname)); - } - else { - char *start = PyString_AS_STRING(modname); - char *lastdot = strrchr(start, '.'); - size_t len; - if (lastdot == NULL && level > 0) { + len = PyString_GET_SIZE(pkgname); + if (len == 0) { + if (level > 0) { + PyErr_SetString(PyExc_ValueError, + "Attempted relative import in non-package"); + return NULL; + } + return Py_None; + } + if (len > MAXPATHLEN) { PyErr_SetString(PyExc_ValueError, - "Attempted relative import in non-package"); + "Package name too long"); return NULL; } - if (lastdot == NULL) + strcpy(buf, PyString_AS_STRING(pkgname)); + } else { + /* __package__ not set, so figure it out and set it */ + modname = PyDict_GetItem(globals, namestr); + if (modname == NULL || !PyString_Check(modname)) return Py_None; - len = lastdot - start; - if (len >= MAXPATHLEN) { - PyErr_SetString(PyExc_ValueError, - "Module name too long"); - return NULL; + + modpath = PyDict_GetItem(globals, pathstr); + if (modpath != NULL) { + /* __path__ is set, so modname is already the package name */ + Py_ssize_t len = PyString_GET_SIZE(modname); + int error; + if (len > MAXPATHLEN) { + PyErr_SetString(PyExc_ValueError, + "Module name too long"); + return NULL; + } + strcpy(buf, PyString_AS_STRING(modname)); + error = PyDict_SetItem(globals, pkgstr, modname); + if (error) { + PyErr_SetString(PyExc_ValueError, + "Could not set __package__"); + return NULL; + } + } else { + /* Normal module, so work out the package name if any */ + char *start = PyString_AS_STRING(modname); + char *lastdot = strrchr(start, '.'); + size_t len; + int error; + if (lastdot == NULL && level > 0) { + PyErr_SetString(PyExc_ValueError, + "Attempted relative import in non-package"); + return NULL; + } + if (lastdot == NULL) { + error = PyDict_SetItem(globals, pkgstr, Py_None); + if (error) { + PyErr_SetString(PyExc_ValueError, + "Could not set __package__"); + return NULL; + } + return Py_None; + } + len = lastdot - start; + if (len >= MAXPATHLEN) { + PyErr_SetString(PyExc_ValueError, + "Module name too long"); + return NULL; + } + strncpy(buf, start, len); + buf[len] = '\0'; + pkgname = PyString_FromString(buf); + if (pkgname == NULL) { + return NULL; + } + error = PyDict_SetItem(globals, pkgstr, pkgname); + Py_DECREF(pkgname); + if (error) { + PyErr_SetString(PyExc_ValueError, + "Could not set __package__"); + return NULL; + } } - strncpy(buf, start, len); - buf[len] = '\0'; } - while (--level > 0) { char *dot = strrchr(buf, '.'); if (dot == NULL) { |