Manual merge of PEP 366 implementation from trunk (the automatic merge choked on the PyString->PyUnicode changes)

This commit is contained in:
Nick Coghlan 2007-12-04 12:22:52 +00:00
parent 79a082b715
commit de10c85314
1 changed files with 88 additions and 28 deletions

View File

@ -2016,7 +2016,8 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
{ {
static PyObject *namestr = NULL; static PyObject *namestr = NULL;
static PyObject *pathstr = 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) if (globals == NULL || !PyDict_Check(globals) || !level)
return Py_None; return Py_None;
@ -2031,34 +2032,82 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
if (pathstr == NULL) if (pathstr == NULL)
return NULL; return NULL;
} }
if (pkgstr == NULL) {
pkgstr = PyUnicode_InternFromString("__package__");
if (pkgstr == NULL)
return NULL;
}
*buf = '\0'; *buf = '\0';
*p_buflen = 0; *p_buflen = 0;
pkgname = PyDict_GetItem(globals, pkgstr);
if ((pkgname != NULL) && (pkgname != Py_None)) {
/* __package__ is set, so use it */
Py_ssize_t len;
if (!PyUnicode_Check(pkgname)) {
PyErr_SetString(PyExc_ValueError,
"__package__ set to non-string");
return NULL;
}
len = PyUnicode_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,
"Package name too long");
return NULL;
}
strcpy(buf, PyUnicode_AsString(pkgname));
} else {
/* __package__ not set, so figure it out and set it */
modname = PyDict_GetItem(globals, namestr); modname = PyDict_GetItem(globals, namestr);
if (modname == NULL || !PyUnicode_Check(modname)) if (modname == NULL || !PyUnicode_Check(modname))
return Py_None; return Py_None;
modpath = PyDict_GetItem(globals, pathstr); modpath = PyDict_GetItem(globals, pathstr);
if (modpath != NULL) { if (modpath != NULL) {
/* __path__ is set, so modname is already the package name */
Py_ssize_t len = PyUnicode_GET_SIZE(modname); Py_ssize_t len = PyUnicode_GET_SIZE(modname);
int error;
if (len > MAXPATHLEN) { if (len > MAXPATHLEN) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"Module name too long"); "Module name too long");
return NULL; return NULL;
} }
strcpy(buf, PyUnicode_AsString(modname)); strcpy(buf, PyUnicode_AsString(modname));
error = PyDict_SetItem(globals, pkgstr, modname);
if (error) {
PyErr_SetString(PyExc_ValueError,
"Could not set __package__");
return NULL;
} }
else { } else {
/* Normal module, so work out the package name if any */
char *start = PyUnicode_AsString(modname); char *start = PyUnicode_AsString(modname);
char *lastdot = strrchr(start, '.'); char *lastdot = strrchr(start, '.');
size_t len; size_t len;
int error;
if (lastdot == NULL && level > 0) { if (lastdot == NULL && level > 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"Attempted relative import in non-package"); "Attempted relative import in non-package");
return NULL; return NULL;
} }
if (lastdot == 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; return Py_None;
}
len = lastdot - start; len = lastdot - start;
if (len >= MAXPATHLEN) { if (len >= MAXPATHLEN) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
@ -2067,8 +2116,19 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
} }
strncpy(buf, start, len); strncpy(buf, start, len);
buf[len] = '\0'; buf[len] = '\0';
pkgname = PyUnicode_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;
}
}
} }
while (--level > 0) { while (--level > 0) {
char *dot = strrchr(buf, '.'); char *dot = strrchr(buf, '.');
if (dot == NULL) { if (dot == NULL) {