Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit de10c85

Browse files
committed
Manual merge of PEP 366 implementation from trunk (the automatic merge choked on the PyString->PyUnicode changes)
1 parent 79a082b commit de10c85

1 file changed

Lines changed: 86 additions & 26 deletions

File tree

Python/import.c

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,7 +2016,8 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
20162016
{
20172017
static PyObject *namestr = NULL;
20182018
static PyObject *pathstr = NULL;
2019-
PyObject *modname, *modpath, *modules, *parent;
2019+
static PyObject *pkgstr = NULL;
2020+
PyObject *pkgname, *modname, *modpath, *modules, *parent;
20202021

20212022
if (globals == NULL || !PyDict_Check(globals) || !level)
20222023
return Py_None;
@@ -2031,44 +2032,103 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
20312032
if (pathstr == NULL)
20322033
return NULL;
20332034
}
2035+
if (pkgstr == NULL) {
2036+
pkgstr = PyUnicode_InternFromString("__package__");
2037+
if (pkgstr == NULL)
2038+
return NULL;
2039+
}
20342040

20352041
*buf = '\0';
20362042
*p_buflen = 0;
2037-
modname = PyDict_GetItem(globals, namestr);
2038-
if (modname == NULL || !PyUnicode_Check(modname))
2039-
return Py_None;
2043+
pkgname = PyDict_GetItem(globals, pkgstr);
20402044

2041-
modpath = PyDict_GetItem(globals, pathstr);
2042-
if (modpath != NULL) {
2043-
Py_ssize_t len = PyUnicode_GET_SIZE(modname);
2044-
if (len > MAXPATHLEN) {
2045+
if ((pkgname != NULL) && (pkgname != Py_None)) {
2046+
/* __package__ is set, so use it */
2047+
Py_ssize_t len;
2048+
if (!PyUnicode_Check(pkgname)) {
20452049
PyErr_SetString(PyExc_ValueError,
2046-
"Module name too long");
2050+
"__package__ set to non-string");
20472051
return NULL;
20482052
}
2049-
strcpy(buf, PyUnicode_AsString(modname));
2050-
}
2051-
else {
2052-
char *start = PyUnicode_AsString(modname);
2053-
char *lastdot = strrchr(start, '.');
2054-
size_t len;
2055-
if (lastdot == NULL && level > 0) {
2053+
len = PyUnicode_GET_SIZE(pkgname);
2054+
if (len == 0) {
2055+
if (level > 0) {
2056+
PyErr_SetString(PyExc_ValueError,
2057+
"Attempted relative import in non-package");
2058+
return NULL;
2059+
}
2060+
return Py_None;
2061+
}
2062+
if (len > MAXPATHLEN) {
20562063
PyErr_SetString(PyExc_ValueError,
2057-
"Attempted relative import in non-package");
2064+
"Package name too long");
20582065
return NULL;
20592066
}
2060-
if (lastdot == NULL)
2067+
strcpy(buf, PyUnicode_AsString(pkgname));
2068+
} else {
2069+
/* __package__ not set, so figure it out and set it */
2070+
modname = PyDict_GetItem(globals, namestr);
2071+
if (modname == NULL || !PyUnicode_Check(modname))
20612072
return Py_None;
2062-
len = lastdot - start;
2063-
if (len >= MAXPATHLEN) {
2064-
PyErr_SetString(PyExc_ValueError,
2065-
"Module name too long");
2066-
return NULL;
2073+
2074+
modpath = PyDict_GetItem(globals, pathstr);
2075+
if (modpath != NULL) {
2076+
/* __path__ is set, so modname is already the package name */
2077+
Py_ssize_t len = PyUnicode_GET_SIZE(modname);
2078+
int error;
2079+
if (len > MAXPATHLEN) {
2080+
PyErr_SetString(PyExc_ValueError,
2081+
"Module name too long");
2082+
return NULL;
2083+
}
2084+
strcpy(buf, PyUnicode_AsString(modname));
2085+
error = PyDict_SetItem(globals, pkgstr, modname);
2086+
if (error) {
2087+
PyErr_SetString(PyExc_ValueError,
2088+
"Could not set __package__");
2089+
return NULL;
2090+
}
2091+
} else {
2092+
/* Normal module, so work out the package name if any */
2093+
char *start = PyUnicode_AsString(modname);
2094+
char *lastdot = strrchr(start, '.');
2095+
size_t len;
2096+
int error;
2097+
if (lastdot == NULL && level > 0) {
2098+
PyErr_SetString(PyExc_ValueError,
2099+
"Attempted relative import in non-package");
2100+
return NULL;
2101+
}
2102+
if (lastdot == NULL) {
2103+
error = PyDict_SetItem(globals, pkgstr, Py_None);
2104+
if (error) {
2105+
PyErr_SetString(PyExc_ValueError,
2106+
"Could not set __package__");
2107+
return NULL;
2108+
}
2109+
return Py_None;
2110+
}
2111+
len = lastdot - start;
2112+
if (len >= MAXPATHLEN) {
2113+
PyErr_SetString(PyExc_ValueError,
2114+
"Module name too long");
2115+
return NULL;
2116+
}
2117+
strncpy(buf, start, len);
2118+
buf[len] = '\0';
2119+
pkgname = PyUnicode_FromString(buf);
2120+
if (pkgname == NULL) {
2121+
return NULL;
2122+
}
2123+
error = PyDict_SetItem(globals, pkgstr, pkgname);
2124+
Py_DECREF(pkgname);
2125+
if (error) {
2126+
PyErr_SetString(PyExc_ValueError,
2127+
"Could not set __package__");
2128+
return NULL;
2129+
}
20672130
}
2068-
strncpy(buf, start, len);
2069-
buf[len] = '\0';
20702131
}
2071-
20722132
while (--level > 0) {
20732133
char *dot = strrchr(buf, '.');
20742134
if (dot == NULL) {

0 commit comments

Comments
 (0)