Commit d968e275 authored by Benjamin Peterson's avatar Benjamin Peterson

fix #4211: the __path__ of a frozen package should be a list.

Patch by Brett Cannon, review by Christian Heimes.
parent 65676e40
...@@ -22,6 +22,7 @@ class FrozenTests(unittest.TestCase): ...@@ -22,6 +22,7 @@ class FrozenTests(unittest.TestCase):
self.assertEqual(len(dir(__phello__)), 7, dir(__phello__)) self.assertEqual(len(dir(__phello__)), 7, dir(__phello__))
else: else:
self.assertEqual(len(dir(__phello__)), 8, dir(__phello__)) self.assertEqual(len(dir(__phello__)), 8, dir(__phello__))
self.assertEquals(__phello__.__path__, [__phello__.__name__])
try: try:
import __phello__.spam import __phello__.spam
......
...@@ -15,6 +15,9 @@ What's New in Python 3.0 beta 5 ...@@ -15,6 +15,9 @@ What's New in Python 3.0 beta 5
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #4211: The __path__ attribute of frozen packages is now a list instead
of a string as required by PEP 302.
- Issue #3727: Fixed poplib - Issue #3727: Fixed poplib
- Issue #3714: Fixed nntplib by using bytes where appropriate. - Issue #3714: Fixed nntplib by using bytes where appropriate.
......
...@@ -1293,37 +1293,16 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, ...@@ -1293,37 +1293,16 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
Py_DECREF(meta_path); Py_DECREF(meta_path);
} }
if (path != NULL && PyUnicode_Check(path)) { if (find_frozen(fullname) != NULL) {
/* The only type of submodule allowed inside a "frozen" strcpy(buf, fullname);
package are other frozen modules or packages. */ return &fd_frozen;
char *p = _PyUnicode_AsString(path);
if (strlen(p) + 1 + strlen(name) >= (size_t)buflen) {
PyErr_SetString(PyExc_ImportError,
"full frozen module name too long");
return NULL;
}
strcpy(buf, p);
strcat(buf, ".");
strcat(buf, name);
strcpy(name, buf);
if (find_frozen(name) != NULL) {
strcpy(buf, name);
return &fd_frozen;
}
PyErr_Format(PyExc_ImportError,
"No frozen submodule named %.200s", name);
return NULL;
} }
if (path == NULL) { if (path == NULL) {
if (is_builtin(name)) { if (is_builtin(name)) {
strcpy(buf, name); strcpy(buf, name);
return &fd_builtin; return &fd_builtin;
} }
if ((find_frozen(name)) != NULL) {
strcpy(buf, name);
return &fd_frozen;
}
#ifdef MS_COREDLL #ifdef MS_COREDLL
fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen); fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
if (fp != NULL) { if (fp != NULL) {
...@@ -1333,6 +1312,7 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, ...@@ -1333,6 +1312,7 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
#endif #endif
path = PySys_GetObject("path"); path = PySys_GetObject("path");
} }
if (path == NULL || !PyList_Check(path)) { if (path == NULL || !PyList_Check(path)) {
PyErr_SetString(PyExc_ImportError, PyErr_SetString(PyExc_ImportError,
"sys.path must be a list of directory names"); "sys.path must be a list of directory names");
...@@ -1886,6 +1866,9 @@ find_frozen(char *name) ...@@ -1886,6 +1866,9 @@ find_frozen(char *name)
{ {
struct _frozen *p; struct _frozen *p;
if (!name)
return NULL;
for (p = PyImport_FrozenModules; ; p++) { for (p = PyImport_FrozenModules; ; p++) {
if (p->name == NULL) if (p->name == NULL)
return NULL; return NULL;
...@@ -1959,7 +1942,7 @@ PyImport_ImportFrozenModule(char *name) ...@@ -1959,7 +1942,7 @@ PyImport_ImportFrozenModule(char *name)
} }
if (ispackage) { if (ispackage) {
/* Set __path__ to the package name */ /* Set __path__ to the package name */
PyObject *d, *s; PyObject *d, *s, *l;
int err; int err;
m = PyImport_AddModule(name); m = PyImport_AddModule(name);
if (m == NULL) if (m == NULL)
...@@ -1968,8 +1951,14 @@ PyImport_ImportFrozenModule(char *name) ...@@ -1968,8 +1951,14 @@ PyImport_ImportFrozenModule(char *name)
s = PyUnicode_InternFromString(name); s = PyUnicode_InternFromString(name);
if (s == NULL) if (s == NULL)
goto err_return; goto err_return;
err = PyDict_SetItemString(d, "__path__", s); l = PyList_New(1);
Py_DECREF(s); if (l == NULL) {
Py_DECREF(s);
goto err_return;
}
PyList_SET_ITEM(l, 0, s);
err = PyDict_SetItemString(d, "__path__", l);
Py_DECREF(l);
if (err != 0) if (err != 0)
goto err_return; goto err_return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment