From d968e27581e42874427979c87885997c59af5ba5 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 5 Nov 2008 22:48:33 +0000 Subject: [PATCH] fix #4211: the __path__ of a frozen package should be a list. Patch by Brett Cannon, review by Christian Heimes. --- Lib/test/test_frozen.py | 1 + Misc/NEWS | 3 +++ Python/import.c | 45 ++++++++++++++++------------------------- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/Lib/test/test_frozen.py b/Lib/test/test_frozen.py index 545941bedc7..ab7b52f5f5a 100644 --- a/Lib/test/test_frozen.py +++ b/Lib/test/test_frozen.py @@ -22,6 +22,7 @@ class FrozenTests(unittest.TestCase): self.assertEqual(len(dir(__phello__)), 7, dir(__phello__)) else: self.assertEqual(len(dir(__phello__)), 8, dir(__phello__)) + self.assertEquals(__phello__.__path__, [__phello__.__name__]) try: import __phello__.spam diff --git a/Misc/NEWS b/Misc/NEWS index e422b38055b..40acabd2d38 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -15,6 +15,9 @@ What's New in Python 3.0 beta 5 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 #3714: Fixed nntplib by using bytes where appropriate. diff --git a/Python/import.c b/Python/import.c index 9c077fe8a66..564ace88b3a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1293,37 +1293,16 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, Py_DECREF(meta_path); } - if (path != NULL && PyUnicode_Check(path)) { - /* The only type of submodule allowed inside a "frozen" - package are other frozen modules or packages. */ - 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 (find_frozen(fullname) != NULL) { + strcpy(buf, fullname); + return &fd_frozen; } + if (path == NULL) { if (is_builtin(name)) { strcpy(buf, name); return &fd_builtin; } - if ((find_frozen(name)) != NULL) { - strcpy(buf, name); - return &fd_frozen; - } - #ifdef MS_COREDLL fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen); if (fp != NULL) { @@ -1333,6 +1312,7 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, #endif path = PySys_GetObject("path"); } + if (path == NULL || !PyList_Check(path)) { PyErr_SetString(PyExc_ImportError, "sys.path must be a list of directory names"); @@ -1886,6 +1866,9 @@ find_frozen(char *name) { struct _frozen *p; + if (!name) + return NULL; + for (p = PyImport_FrozenModules; ; p++) { if (p->name == NULL) return NULL; @@ -1959,7 +1942,7 @@ PyImport_ImportFrozenModule(char *name) } if (ispackage) { /* Set __path__ to the package name */ - PyObject *d, *s; + PyObject *d, *s, *l; int err; m = PyImport_AddModule(name); if (m == NULL) @@ -1968,8 +1951,14 @@ PyImport_ImportFrozenModule(char *name) s = PyUnicode_InternFromString(name); if (s == NULL) goto err_return; - err = PyDict_SetItemString(d, "__path__", s); - Py_DECREF(s); + l = PyList_New(1); + 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) goto err_return; }