[Python-checkins] cpython: Issue #19712: Update test.test_importlib.import_ to test/use PEP 451

brett.cannon python-checkins at python.org
Fri Dec 6 18:07:34 CET 2013


http://hg.python.org/cpython/rev/543c76769c14
changeset:   87794:543c76769c14
user:        Brett Cannon <brett at python.org>
date:        Fri Dec 06 12:07:25 2013 -0500
summary:
  Issue #19712: Update test.test_importlib.import_ to test/use PEP 451
where appropriate.

files:
  Lib/test/test_importlib/import_/test___package__.py      |  31 ++++-
  Lib/test/test_importlib/import_/test_caching.py          |  18 ++-
  Lib/test/test_importlib/import_/test_fromlist.py         |   2 +-
  Lib/test/test_importlib/import_/test_meta_path.py        |  50 +++++----
  Lib/test/test_importlib/import_/test_packages.py         |  14 +-
  Lib/test/test_importlib/import_/test_path.py             |  10 +-
  Lib/test/test_importlib/import_/test_relative_imports.py |   2 +-
  Lib/test/test_importlib/util.py                          |  48 ++++++++-
  8 files changed, 114 insertions(+), 61 deletions(-)


diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py
--- a/Lib/test/test_importlib/import_/test___package__.py
+++ b/Lib/test/test_importlib/import_/test___package__.py
@@ -36,7 +36,7 @@
 
     def test_using___package__(self):
         # [__package__]
-        with util.mock_modules('pkg.__init__', 'pkg.fake') as importer:
+        with self.mock_modules('pkg.__init__', 'pkg.fake') as importer:
             with util.import_state(meta_path=[importer]):
                 self.__import__('pkg.fake')
                 module = self.__import__('',
@@ -49,7 +49,7 @@
         globals_ = {'__name__': 'pkg.fake', '__path__': []}
         if package_as_None:
             globals_['__package__'] = None
-        with util.mock_modules('pkg.__init__', 'pkg.fake') as importer:
+        with self.mock_modules('pkg.__init__', 'pkg.fake') as importer:
             with util.import_state(meta_path=[importer]):
                 self.__import__('pkg.fake')
                 module = self.__import__('', globals= globals_,
@@ -70,11 +70,20 @@
         with self.assertRaises(TypeError):
             self.__import__('', globals, {}, ['relimport'], 1)
 
-Frozen_UsingPackage, Source_UsingPackage = util.test_both(
-        Using__package__, __import__=import_util.__import__)
+class Using__package__PEP302(Using__package__):
+    mock_modules = util.mock_modules
 
+Frozen_UsingPackagePEP302, Source_UsingPackagePEP302 = util.test_both(
+        Using__package__PEP302, __import__=import_util.__import__)
 
-class Setting__package__(unittest.TestCase):
+class Using__package__PEP302(Using__package__):
+    mock_modules = util.mock_spec
+
+Frozen_UsingPackagePEP451, Source_UsingPackagePEP451 = util.test_both(
+        Using__package__PEP302, __import__=import_util.__import__)
+
+
+class Setting__package__:
 
     """Because __package__ is a new feature, it is not always set by a loader.
     Import will set it as needed to help with the transition to relying on
@@ -90,7 +99,7 @@
 
     # [top-level]
     def test_top_level(self):
-        with util.mock_modules('top_level') as mock:
+        with self.mock_modules('top_level') as mock:
             with util.import_state(meta_path=[mock]):
                 del mock['top_level'].__package__
                 module = self.__import__('top_level')
@@ -98,7 +107,7 @@
 
     # [package]
     def test_package(self):
-        with util.mock_modules('pkg.__init__') as mock:
+        with self.mock_modules('pkg.__init__') as mock:
             with util.import_state(meta_path=[mock]):
                 del mock['pkg'].__package__
                 module = self.__import__('pkg')
@@ -106,13 +115,19 @@
 
     # [submodule]
     def test_submodule(self):
-        with util.mock_modules('pkg.__init__', 'pkg.mod') as mock:
+        with self.mock_modules('pkg.__init__', 'pkg.mod') as mock:
             with util.import_state(meta_path=[mock]):
                 del mock['pkg.mod'].__package__
                 pkg = self.__import__('pkg.mod')
                 module = getattr(pkg, 'mod')
                 self.assertEqual(module.__package__, 'pkg')
 
+class Setting__package__PEP302(Setting__package__, unittest.TestCase):
+    mock_modules = util.mock_modules
+
+class Setting__package__PEP451(Setting__package__, unittest.TestCase):
+    mock_modules = util.mock_spec
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_importlib/import_/test_caching.py b/Lib/test/test_importlib/import_/test_caching.py
--- a/Lib/test/test_importlib/import_/test_caching.py
+++ b/Lib/test/test_importlib/import_/test_caching.py
@@ -39,6 +39,16 @@
                 self.__import__(name)
             self.assertEqual(cm.exception.name, name)
 
+Frozen_UseCache, Source_UseCache = util.test_both(
+        UseCache, __import__=import_util.__import__)
+
+
+class ImportlibUseCache(UseCache, unittest.TestCase):
+
+    # Pertinent only to PEP 302; exec_module() doesn't return a module.
+
+    __import__ = import_util.__import__[1]
+
     def create_mock(self, *names, return_=None):
         mock = util.mock_modules(*names)
         original_load = mock.load_module
@@ -48,14 +58,6 @@
         mock.load_module = MethodType(load_module, mock)
         return mock
 
-Frozen_UseCache, Source_UseCache = util.test_both(
-        UseCache, __import__=import_util.__import__)
-
-
-class ImportlibUseCache(UseCache, unittest.TestCase):
-
-    __import__ = import_util.__import__[1]
-
     # __import__ inconsistent between loaders and built-in import when it comes
     #   to when to use the module in sys.modules and when not to.
     def test_using_cache_after_loader(self):
diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py
--- a/Lib/test/test_importlib/import_/test_fromlist.py
+++ b/Lib/test/test_importlib/import_/test_fromlist.py
@@ -17,7 +17,7 @@
 
     def test_return_from_import(self):
         # [import return]
-        with util.mock_modules('pkg.__init__', 'pkg.module') as importer:
+        with util.mock_spec('pkg.__init__', 'pkg.module') as importer:
             with util.import_state(meta_path=[importer]):
                 module = self.__import__('pkg.module')
                 self.assertEqual(module.__name__, 'pkg')
diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py
--- a/Lib/test/test_importlib/import_/test_meta_path.py
+++ b/Lib/test/test_importlib/import_/test_meta_path.py
@@ -18,23 +18,18 @@
     def test_first_called(self):
         # [first called]
         mod = 'top_level'
-        first = util.mock_modules(mod)
-        second = util.mock_modules(mod)
-        with util.mock_modules(mod) as first, util.mock_modules(mod) as second:
-            first.modules[mod] = 42
-            second.modules[mod] = -13
+        with util.mock_spec(mod) as first, util.mock_spec(mod) as second:
             with util.import_state(meta_path=[first, second]):
-                self.assertEqual(self.__import__(mod), 42)
+                self.assertIs(self.__import__(mod), first.modules[mod])
 
     def test_continuing(self):
         # [continuing]
         mod_name = 'for_real'
-        with util.mock_modules('nonexistent') as first, \
-             util.mock_modules(mod_name) as second:
-            first.find_module = lambda self, fullname, path=None: None
-            second.modules[mod_name] = 42
+        with util.mock_spec('nonexistent') as first, \
+             util.mock_spec(mod_name) as second:
+            first.find_spec = lambda self, fullname, path=None, parent=None: None
             with util.import_state(meta_path=[first, second]):
-                self.assertEqual(self.__import__(mod_name), 42)
+                self.assertIs(self.__import__(mod_name), second.modules[mod_name])
 
     def test_empty(self):
         # Raise an ImportWarning if sys.meta_path is empty.
@@ -61,29 +56,27 @@
     [no path]. Otherwise, the value for __path__ is passed in for the 'path'
     argument [path set]."""
 
-    def log(self, fxn):
+    def log_finder(self, importer):
+        fxn = getattr(importer, self.finder_name)
         log = []
         def wrapper(self, *args, **kwargs):
             log.append([args, kwargs])
             return fxn(*args, **kwargs)
         return log, wrapper
 
-
     def test_no_path(self):
         # [no path]
         mod_name = 'top_level'
         assert '.' not in mod_name
-        with util.mock_modules(mod_name) as importer:
-            log, wrapped_call = self.log(importer.find_module)
-            importer.find_module = MethodType(wrapped_call, importer)
+        with self.mock_modules(mod_name) as importer:
+            log, wrapped_call = self.log_finder(importer)
+            setattr(importer, self.finder_name, MethodType(wrapped_call, importer))
             with util.import_state(meta_path=[importer]):
                 self.__import__(mod_name)
                 assert len(log) == 1
                 args = log[0][0]
                 kwargs = log[0][1]
                 # Assuming all arguments are positional.
-                self.assertEqual(len(args), 2)
-                self.assertEqual(len(kwargs), 0)
                 self.assertEqual(args[0], mod_name)
                 self.assertIsNone(args[1])
 
@@ -93,10 +86,10 @@
         mod_name = pkg_name + '.module'
         path = [42]
         assert '.' in mod_name
-        with util.mock_modules(pkg_name+'.__init__', mod_name) as importer:
+        with self.mock_modules(pkg_name+'.__init__', mod_name) as importer:
             importer.modules[pkg_name].__path__ = path
-            log, wrapped_call = self.log(importer.find_module)
-            importer.find_module = MethodType(wrapped_call, importer)
+            log, wrapped_call = self.log_finder(importer)
+            setattr(importer, self.finder_name, MethodType(wrapped_call, importer))
             with util.import_state(meta_path=[importer]):
                 self.__import__(mod_name)
                 assert len(log) == 2
@@ -107,8 +100,19 @@
                 self.assertEqual(args[0], mod_name)
                 self.assertIs(args[1], path)
 
-Frozen_CallSignature, Source_CallSignature = util.test_both(
-        CallSignature, __import__=import_util.__import__)
+class CallSignaturePEP302(CallSignature):
+    mock_modules = util.mock_modules
+    finder_name = 'find_module'
+
+Frozen_CallSignaturePEP302, Source_CallSignaturePEP302 = util.test_both(
+        CallSignaturePEP302, __import__=import_util.__import__)
+
+class CallSignaturePEP451(CallSignature):
+    mock_modules = util.mock_spec
+    finder_name = 'find_spec'
+
+Frozen_CallSignaturePEP451, Source_CallSignaturePEP451 = util.test_both(
+        CallSignaturePEP451, __import__=import_util.__import__)
 
 
 if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test_packages.py b/Lib/test/test_importlib/import_/test_packages.py
--- a/Lib/test/test_importlib/import_/test_packages.py
+++ b/Lib/test/test_importlib/import_/test_packages.py
@@ -11,13 +11,13 @@
     """Importing a submodule should import the parent modules."""
 
     def test_import_parent(self):
-        with util.mock_modules('pkg.__init__', 'pkg.module') as mock:
+        with util.mock_spec('pkg.__init__', 'pkg.module') as mock:
             with util.import_state(meta_path=[mock]):
                 module = self.__import__('pkg.module')
                 self.assertIn('pkg', sys.modules)
 
     def test_bad_parent(self):
-        with util.mock_modules('pkg.module') as mock:
+        with util.mock_spec('pkg.module') as mock:
             with util.import_state(meta_path=[mock]):
                 with self.assertRaises(ImportError) as cm:
                     self.__import__('pkg.module')
@@ -27,7 +27,7 @@
         def __init__():
             import pkg.module
             1/0
-        mock = util.mock_modules('pkg.__init__', 'pkg.module',
+        mock = util.mock_spec('pkg.__init__', 'pkg.module',
                                  module_code={'pkg': __init__})
         with mock:
             with util.import_state(meta_path=[mock]):
@@ -44,7 +44,7 @@
         def __init__():
             from . import module
             1/0
-        mock = util.mock_modules('pkg.__init__', 'pkg.module',
+        mock = util.mock_spec('pkg.__init__', 'pkg.module',
                                  module_code={'pkg': __init__})
         with mock:
             with util.import_state(meta_path=[mock]):
@@ -63,7 +63,7 @@
         def __init__():
             from ..subpkg import module
             1/0
-        mock = util.mock_modules('pkg.__init__', 'pkg.subpkg.__init__',
+        mock = util.mock_spec('pkg.__init__', 'pkg.subpkg.__init__',
                                  'pkg.subpkg.module',
                                  module_code={'pkg.subpkg': __init__})
         with mock:
@@ -93,9 +93,9 @@
         subname = name + '.b'
         def module_injection():
             sys.modules[subname] = 'total bunk'
-        mock_modules = util.mock_modules('mod',
+        mock_spec = util.mock_spec('mod',
                                          module_code={'mod': module_injection})
-        with mock_modules as mock:
+        with mock_spec as mock:
             with util.import_state(meta_path=[mock]):
                 try:
                     submodule = self.__import__(subname)
diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py
--- a/Lib/test/test_importlib/import_/test_path.py
+++ b/Lib/test/test_importlib/import_/test_path.py
@@ -27,7 +27,7 @@
         # Implicitly tests that sys.path_importer_cache is used.
         module = '<test module>'
         path = '<test path>'
-        importer = util.mock_modules(module)
+        importer = util.mock_spec(module)
         with util.import_state(path_importer_cache={path: importer},
                                path=[path]):
             loader = self.machinery.PathFinder.find_module(module)
@@ -38,7 +38,7 @@
         # Implicitly tests that sys.path_importer_cache is used.
         module = '<test module>'
         path = '<test path>'
-        importer = util.mock_modules(module)
+        importer = util.mock_spec(module)
         with util.import_state(path_importer_cache={path: importer}):
             loader = self.machinery.PathFinder.find_module(module, [path])
             self.assertIs(loader, importer)
@@ -47,7 +47,7 @@
         # An empty list should not count as asking for sys.path.
         module = 'module'
         path = '<test path>'
-        importer = util.mock_modules(module)
+        importer = util.mock_spec(module)
         with util.import_state(path_importer_cache={path: importer},
                                path=[path]):
             self.assertIsNone(self.machinery.PathFinder.find_module('module', []))
@@ -57,7 +57,7 @@
         # Test that sys.path_importer_cache is set.
         module = '<test module>'
         path = '<test path>'
-        importer = util.mock_modules(module)
+        importer = util.mock_spec(module)
         hook = import_util.mock_path_hook(path, importer=importer)
         with util.import_state(path_hooks=[hook]):
             loader = self.machinery.PathFinder.find_module(module, [path])
@@ -82,7 +82,7 @@
         # The empty string should create a finder using the cwd.
         path = ''
         module = '<test module>'
-        importer = util.mock_modules(module)
+        importer = util.mock_spec(module)
         hook = import_util.mock_path_hook(os.getcwd(), importer=importer)
         with util.import_state(path=[path], path_hooks=[hook]):
             loader = self.machinery.PathFinder.find_module(module)
diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py
--- a/Lib/test/test_importlib/import_/test_relative_imports.py
+++ b/Lib/test/test_importlib/import_/test_relative_imports.py
@@ -64,7 +64,7 @@
                 uncache_names.append(name)
             else:
                 uncache_names.append(name[:-len('.__init__')])
-        with util.mock_modules(*create) as importer:
+        with util.mock_spec(*create) as importer:
             with util.import_state(meta_path=[importer]):
                 for global_ in globals_:
                     with util.uncache(*uncache_names):
diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -1,4 +1,5 @@
 from contextlib import contextmanager
+from importlib import util
 import os.path
 from test import support
 import unittest
@@ -101,9 +102,9 @@
             setattr(sys, attr, value)
 
 
-class mock_modules:
+class _ImporterMock:
 
-    """A mock importer/loader."""
+    """Base class to help with creating importer mocks."""
 
     def __init__(self, *names, module_code={}):
         self.modules = {}
@@ -133,6 +134,19 @@
     def __getitem__(self, name):
         return self.modules[name]
 
+    def __enter__(self):
+        self._uncache = uncache(*self.modules.keys())
+        self._uncache.__enter__()
+        return self
+
+    def __exit__(self, *exc_info):
+        self._uncache.__exit__(None, None, None)
+
+
+class mock_modules(_ImporterMock):
+
+    """Importer mock using PEP 302 APIs."""
+
     def find_module(self, fullname, path=None):
         if fullname not in self.modules:
             return None
@@ -152,10 +166,28 @@
                     raise
             return self.modules[fullname]
 
-    def __enter__(self):
-        self._uncache = uncache(*self.modules.keys())
-        self._uncache.__enter__()
-        return self
+class mock_spec(_ImporterMock):
 
-    def __exit__(self, *exc_info):
-        self._uncache.__exit__(None, None, None)
+    """Importer mock using PEP 451 APIs."""
+
+    def find_spec(self, fullname, path=None, parent=None):
+        try:
+            module = self.modules[fullname]
+        except KeyError:
+            return None
+        is_package = hasattr(module, '__path__')
+        spec = util.spec_from_file_location(
+                fullname, module.__file__, loader=self,
+                submodule_search_locations=getattr(module, '__path__', None))
+        return spec
+
+    def create_module(self, spec):
+        if spec.name not in self.modules:
+            raise ImportError
+        return self.modules[spec.name]
+
+    def exec_module(self, module):
+        try:
+            self.module_code[module.__spec__.name]()
+        except KeyError:
+            pass

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list