Commits

Benjamin Peterson committed aa6e649

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

Patch by Brett Cannon, review by Christian Heimes.

  • Participants
  • Parent commits 5b4cb8c

Comments (0)

Files changed (3)

File Lib/test/test_frozen.py

             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
 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.

File Python/import.c

 		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) {
 #endif
 		path = PySys_GetObject("path");
 	}
+
 	if (path == NULL || !PyList_Check(path)) {
 		PyErr_SetString(PyExc_ImportError,
 				"sys.path must be a list of directory names");
 {
 	struct _frozen *p;
 
+	if (!name)
+		return NULL;
+
 	for (p = PyImport_FrozenModules; ; p++) {
 		if (p->name == NULL)
 			return NULL;
 	}
 	if (ispackage) {
 		/* Set __path__ to the package name */
-		PyObject *d, *s;
+		PyObject *d, *s, *l;
 		int err;
 		m = PyImport_AddModule(name);
 		if (m == NULL)
 		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;
 	}