diff options
author | Brett Cannon <brett@python.org> | 2012-06-16 00:00:53 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2012-06-16 00:00:53 (GMT) |
commit | ea0b8239401123fa7f41c74f6fc9ded1cf74088a (patch) | |
tree | 6d5afa0b55c1c5e1e39770d062b25d81a231535b | |
parent | 0450c9ed52deccd087c56b4da36f02c800c604a5 (diff) | |
download | cpython-ea0b8239401123fa7f41c74f6fc9ded1cf74088a.zip cpython-ea0b8239401123fa7f41c74f6fc9ded1cf74088a.tar.gz cpython-ea0b8239401123fa7f41c74f6fc9ded1cf74088a.tar.bz2 |
Issue #14938: importlib.abc.SourceLoader.is_package() now takes the
module name into consideration when determining whether a module is a
package or not. This prevents importing a module's __init__ module
directly and having it considered a package, which can lead to
duplicate sub-modules.
Thanks to Ronan Lamy for reporting the bug.
-rw-r--r-- | Doc/library/importlib.rst | 6 | ||||
-rw-r--r-- | Lib/importlib/_bootstrap.py | 4 | ||||
-rw-r--r-- | Lib/importlib/test/source/test_abc_loader.py | 5 | ||||
-rw-r--r-- | Misc/NEWS | 4 |
4 files changed, 14 insertions, 5 deletions
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 35a99bf..9dc6ed1 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -351,8 +351,10 @@ are also provided to help in implementing the core ABCs. .. method:: is_package(self, fullname) Concrete implementation of :meth:`InspectLoader.is_package`. A module - is determined to be a package if its file path is a file named - ``__init__`` when the file extension is removed. + is determined to be a package if its file path (as provided by + :meth:`ExecutionLoader.get_filename`) is a file named + ``__init__`` when the file extension is removed **and** the module name + itself does not end in ``__init__``. .. class:: PyLoader diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 6656db3..117c0f6 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -578,7 +578,9 @@ class _LoaderBasics: """Concrete implementation of InspectLoader.is_package by checking if the path returned by get_filename has a filename of '__init__.py'.""" filename = _path_split(self.get_filename(fullname))[1] - return filename.rsplit('.', 1)[0] == '__init__' + filename_base = filename.rsplit('.', 1)[0] + tail_name = fullname.rpartition('.')[2] + return filename_base == '__init__' and tail_name != '__init__' def _bytes_from_bytecode(self, fullname, data, bytecode_path, source_stats): """Return the marshalled bytes from bytecode, verifying the magic diff --git a/Lib/importlib/test/source/test_abc_loader.py b/Lib/importlib/test/source/test_abc_loader.py index b1b1204..fc98b93 100644 --- a/Lib/importlib/test/source/test_abc_loader.py +++ b/Lib/importlib/test/source/test_abc_loader.py @@ -602,10 +602,11 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness): def test_is_package(self): # Properly detect when loading a package. - self.setUp(is_package=True) - self.assertTrue(self.loader.is_package(self.name)) self.setUp(is_package=False) self.assertFalse(self.loader.is_package(self.name)) + self.setUp(is_package=True) + self.assertTrue(self.loader.is_package(self.name)) + self.assertFalse(self.loader.is_package(self.name + '.__init__')) def test_get_code(self): # Verify the code object is created. @@ -24,6 +24,10 @@ Core and Builtins Library ------- +- Issue #14938: importlib.abc.SourceLoader.is_package() will not consider a + module whose name ends in '__init__' a package (e.g. importing pkg.__init__ + directly should be considered a module, not a package). + - Issue #14982: Document that pkgutil's iteration functions require the non-standard iter_modules() method to be defined by an importer (something the importlib importers do not define). |