Issue #12599: Be more strict in accepting None vs. a false-like object

in importlib.

Thanks to PJE for pointing out the issue and Nick Coghlan for filing
the bug.
This commit is contained in:
Brett Cannon 2012-04-17 21:41:35 -04:00
parent 64befe939c
commit 7bd329d800
5 changed files with 1240 additions and 1212 deletions

View File

@ -217,7 +217,7 @@ def module_for_loader(fxn):
"""
def module_for_loader_wrapper(self, fullname, *args, **kwargs):
module = sys.modules.get(fullname)
is_reload = bool(module)
is_reload = module is not None
if not is_reload:
# This must be done before open() is called as the 'io' module
# implicitly imports 'locale' and would otherwise trigger an
@ -711,7 +711,7 @@ class PathFinder:
If 'hooks' is false then use sys.path_hooks.
"""
if not hooks:
if hooks is None:
hooks = sys.path_hooks
for hook in hooks:
try:
@ -753,7 +753,7 @@ class PathFinder:
def find_module(cls, fullname, path=None):
"""Find the module on sys.path or 'path' based on sys.path_hooks and
sys.path_importer_cache."""
if not path:
if path is None:
path = sys.path
for entry in path:
try:

View File

@ -42,6 +42,15 @@ class FinderTests(unittest.TestCase):
loader = machinery.PathFinder.find_module(module, [path])
self.assertTrue(loader is importer)
def test_empty_list(self):
# An empty list should not count as asking for sys.path.
module = 'module'
path = '<test path>'
importer = util.mock_modules(module)
with util.import_state(path_importer_cache={path: importer},
path=[path]):
self.assertIsNone(machinery.PathFinder.find_module('module', []))
def test_path_hooks(self):
# Test that sys.path_hooks is used.
# Test that sys.path_importer_cache is set.

View File

@ -65,8 +65,22 @@ class ModuleForLoaderTests(unittest.TestCase):
self.assertEqual(wrapped.__name__, fxn.__name__)
self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
class SetPackageTests(unittest.TestCase):
def test_false_module(self):
# If for some odd reason a module is considered false, still return it
# from sys.modules.
class FalseModule(types.ModuleType):
def __bool__(self): return False
name = 'mod'
module = FalseModule(name)
with test_util.uncache(name):
self.assertFalse(module)
sys.modules[name] = module
given = self.return_module(name)
self.assertTrue(given is module)
class SetPackageTests(unittest.TestCase):
"""Tests for importlib.util.set_package."""

View File

@ -10,6 +10,10 @@ What's New in Python 3.3.0 Alpha 3?
Core and Builtins
-----------------
- Issue #12599: Be more strict in accepting None compared to a false-like
object for importlib.util.module_for_loader and
importlib.machinery.PathFinder.
- Issue #14592: Attempting a relative import w/o __package__ or __name__ set in
globals raises a KeyError.

File diff suppressed because it is too large Load Diff