From de4ebfe5597d503af097cd51ec51cc70fa79d250 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 30 Aug 2009 19:53:48 +0000 Subject: When the globals argument to importlib.__import__() contained any value for __package__, it was used. This was incorrect since it could be set to None to represent the fact that a proper value was unknown. Now None will trigger the calculation for __package__. Discovered when running importlib against test_importhooks. --- Lib/importlib/_bootstrap.py | 8 ++++---- Lib/importlib/test/import_/test___package__.py | 20 +++++++++++++------- Misc/NEWS | 3 +++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 063f603..bd62c36 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -922,10 +922,10 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0): if level == 0: module = _gcd_import(name) else: - # __package__ is not guaranteed to be defined. - try: - package = globals['__package__'] - except KeyError: + # __package__ is not guaranteed to be defined or could be set to None + # to represent that it's proper value is unknown + package = globals.get('__package__') + if package is None: package = globals['__name__'] if '__path__' not in globals: package = package.rpartition('.')[0] diff --git a/Lib/importlib/test/import_/test___package__.py b/Lib/importlib/test/import_/test___package__.py index 4eb1f85..02679ef 100644 --- a/Lib/importlib/test/import_/test___package__.py +++ b/Lib/importlib/test/import_/test___package__.py @@ -19,8 +19,9 @@ class Using__package__(unittest.TestCase): base = package.rsplit('.', level)[0] return '{0}.{1}'.format(base, name) - But since there is no guarantee that __package__ has been set, there has to - be a way to calculate the attribute's value [__name__]:: + But since there is no guarantee that __package__ has been set (or not been + set to None [None]), there has to be a way to calculate the attribute's value + [__name__]:: def calc_package(caller_name, has___path__): if has__path__: @@ -43,17 +44,22 @@ class Using__package__(unittest.TestCase): fromlist=['attr'], level=2) self.assertEquals(module.__name__, 'pkg') - def test_using___name__(self): + def test_using___name__(self, package_as_None=False): # [__name__] + globals_ = {'__name__': 'pkg.fake', '__path__': []} + if package_as_None: + globals_['__package__'] = None with util.mock_modules('pkg.__init__', 'pkg.fake') as importer: with util.import_state(meta_path=[importer]): import_util.import_('pkg.fake') - module = import_util.import_('', - globals={'__name__': 'pkg.fake', - '__path__': []}, - fromlist=['attr'], level=2) + module = import_util.import_('', globals= globals_, + fromlist=['attr'], level=2) self.assertEquals(module.__name__, 'pkg') + def test_None_as___package__(self): + # [None] + self.test_using___name__(package_as_None=True) + def test_bad__package__(self): globals = {'__package__': ''} with self.assertRaises(SystemError): diff --git a/Misc/NEWS b/Misc/NEWS index 6f73e73..608e9a8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -68,6 +68,9 @@ C-API Library ------- +- When the globals past to importlib.__import__() has __package__ set to None, + fall back to computing what __package__ should be instead of giving up. + - Raise a TypeError when the name of a module to be imported for importlib.__import__ is not a string (was raising an AttributeError before). -- cgit v0.12