Issue #18065: For frozen packages set __path__ to [].

Previously __path__ was set to [__name__], but that could lead to bad
results if someone managed to circumvent the frozen importer and
somehow ended up with a finder that thought __name__ was a legit
directory/location.
This commit is contained in:
Brett Cannon 2013-05-31 23:18:39 -04:00
parent 0e75c06886
commit 3e0651b5fa
4 changed files with 16 additions and 5 deletions

View File

@ -259,3 +259,10 @@ that may require changes to your code.
``__package__`` unconditionally to properly support reloading. If this is not ``__package__`` unconditionally to properly support reloading. If this is not
desired then you will need to set these attributes manually. You can use desired then you will need to set these attributes manually. You can use
:func:`importlib.util.module_to_load` for module management. :func:`importlib.util.module_to_load` for module management.
* Import now resets relevant attributes (e.g. ``__name__``, ``__loader__``,
``__package__``, ``__file__``, ``__cached__``) unconditionally when reloading.
* Frozen packages no longer set ``__path__`` to a list containg the package name
but an empty list instead. Determing if a module is a package should be done
using ``hasattr(module, '__path__')``.

View File

@ -24,7 +24,7 @@ class LoaderTests(abc.LoaderTests):
module = machinery.FrozenImporter.load_module('__phello__') module = machinery.FrozenImporter.load_module('__phello__')
check = {'__name__': '__phello__', check = {'__name__': '__phello__',
'__package__': '__phello__', '__package__': '__phello__',
'__path__': ['__phello__'], '__path__': [],
'__loader__': machinery.FrozenImporter, '__loader__': machinery.FrozenImporter,
} }
for attr, value in check.items(): for attr, value in check.items():

View File

@ -10,6 +10,12 @@ What's New in Python 3.4.0 Alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #18065: Don't set __path__ to the package name for frozen packages.
- Issue #18088: When reloading a module, unconditionally reset all relevant
attributes on the module (e.g. __name__, __loader__, __package__, __file__,
__cached__).
- Issue #17937: Try harder to collect cyclic garbage at shutdown. - Issue #17937: Try harder to collect cyclic garbage at shutdown.
- Issue #12370: Prevent class bodies from interfering with the __class__ - Issue #12370: Prevent class bodies from interfering with the __class__

View File

@ -1107,19 +1107,17 @@ PyImport_ImportFrozenModuleObject(PyObject *name)
goto err_return; goto err_return;
} }
if (ispackage) { if (ispackage) {
/* Set __path__ to the package name */ /* Set __path__ to the empty list */
PyObject *d, *l; PyObject *d, *l;
int err; int err;
m = PyImport_AddModuleObject(name); m = PyImport_AddModuleObject(name);
if (m == NULL) if (m == NULL)
goto err_return; goto err_return;
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
l = PyList_New(1); l = PyList_New(0);
if (l == NULL) { if (l == NULL) {
goto err_return; goto err_return;
} }
Py_INCREF(name);
PyList_SET_ITEM(l, 0, name);
err = PyDict_SetItemString(d, "__path__", l); err = PyDict_SetItemString(d, "__path__", l);
Py_DECREF(l); Py_DECREF(l);
if (err != 0) if (err != 0)