summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/importlib/NOTES3
-rw-r--r--Lib/importlib/test/source/test_case_sensitivity.py4
-rw-r--r--Lib/importlib/test/source/test_finder.py11
-rw-r--r--Lib/importlib/test/source/test_loader.py41
-rw-r--r--Lib/importlib/test/source/test_path_hook.py4
-rw-r--r--Lib/importlib/test/source/test_source_encoding.py5
-rw-r--r--Lib/importlib/test/source/util.py88
-rw-r--r--Lib/importlib/test/support.py80
8 files changed, 123 insertions, 113 deletions
diff --git a/Lib/importlib/NOTES b/Lib/importlib/NOTES
index 02eecf9..8351f1e 100644
--- a/Lib/importlib/NOTES
+++ b/Lib/importlib/NOTES
@@ -3,9 +3,6 @@ to do
* Reorganize support code.
- + Separate general support code and importer-specific (e.g. source) support
- code.
- - Create support modules for each subdirectory (as needed).
+ Add a file loader mock that returns monotonically increasing mtime.
- Use in source/test_reload.
- Use in source/test_load_module_mixed.
diff --git a/Lib/importlib/test/source/test_case_sensitivity.py b/Lib/importlib/test/source/test_case_sensitivity.py
index 6649f37..955d6ec 100644
--- a/Lib/importlib/test/source/test_case_sensitivity.py
+++ b/Lib/importlib/test/source/test_case_sensitivity.py
@@ -1,6 +1,7 @@
"""Test case-sensitivity (PEP 235)."""
import importlib
from .. import support
+from . import util as source_util
import os
import sys
from test import support as test_support
@@ -25,7 +26,8 @@ class CaseSensitivityTest(unittest.TestCase):
"""Look for a module with matching and non-matching sensitivity."""
sensitive_pkg = 'sensitive.{0}'.format(self.name)
insensitive_pkg = 'insensitive.{0}'.format(self.name.lower())
- with support.create_modules(insensitive_pkg, sensitive_pkg) as mapping:
+ context = source_util.create_modules(insensitive_pkg, sensitive_pkg)
+ with context as mapping:
sensitive_path = os.path.join(mapping['.root'], 'sensitive')
insensitive_path = os.path.join(mapping['.root'], 'insensitive')
return self.find(sensitive_path), self.find(insensitive_path)
diff --git a/Lib/importlib/test/source/test_finder.py b/Lib/importlib/test/source/test_finder.py
index 63cb436..a84d914 100644
--- a/Lib/importlib/test/source/test_finder.py
+++ b/Lib/importlib/test/source/test_finder.py
@@ -1,6 +1,7 @@
import importlib
from .. import abc
from .. import support
+from . import util as source_util
import os
import py_compile
import unittest
@@ -45,7 +46,7 @@ class FinderTests(abc.FinderTests):
"""
if create is None:
create = {test}
- with support.create_modules(*create) as mapping:
+ with source_util.create_modules(*create) as mapping:
if compile_:
for name in compile_:
py_compile.compile(mapping[name])
@@ -76,14 +77,14 @@ class FinderTests(abc.FinderTests):
# [sub module]
def test_module_in_package(self):
- with support.create_modules('pkg.__init__', 'pkg.sub') as mapping:
+ with source_util.create_modules('pkg.__init__', 'pkg.sub') as mapping:
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
loader = self.import_(pkg_dir, 'pkg.sub')
self.assert_(hasattr(loader, 'load_module'))
# [sub package]
def test_package_in_package(self):
- context = support.create_modules('pkg.__init__', 'pkg.sub.__init__')
+ context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__')
with context as mapping:
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
loader = self.import_(pkg_dir, 'pkg.sub')
@@ -91,7 +92,7 @@ class FinderTests(abc.FinderTests):
# [sub empty]
def test_empty_sub_directory(self):
- context = support.create_modules('pkg.__init__', 'pkg.sub.__init__')
+ context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__')
with warnings.catch_warnings():
warnings.simplefilter("error", ImportWarning)
with context as mapping:
@@ -109,7 +110,7 @@ class FinderTests(abc.FinderTests):
def test_failure(self):
- with support.create_modules('blah') as mapping:
+ with source_util.create_modules('blah') as mapping:
nothing = self.import_(mapping['.root'], 'sdfsadsadf')
self.assert_(nothing is None)
diff --git a/Lib/importlib/test/source/test_loader.py b/Lib/importlib/test/source/test_loader.py
index c59dd2c..67930fc 100644
--- a/Lib/importlib/test/source/test_loader.py
+++ b/Lib/importlib/test/source/test_loader.py
@@ -1,6 +1,7 @@
import importlib
from .. import abc
from .. import support
+from . import util as source_util
import imp
import os
@@ -18,7 +19,7 @@ class SimpleTest(unittest.TestCase):
# [basic]
def test_module(self):
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
module = loader.load_module('_temp')
self.assert_('_temp' in sys.modules)
@@ -28,7 +29,7 @@ class SimpleTest(unittest.TestCase):
self.assertEqual(getattr(module, attr), value)
def test_package(self):
- with support.create_modules('_pkg.__init__') as mapping:
+ with source_util.create_modules('_pkg.__init__') as mapping:
loader = importlib._PyFileLoader('_pkg', mapping['_pkg.__init__'],
True)
module = loader.load_module('_pkg')
@@ -41,7 +42,7 @@ class SimpleTest(unittest.TestCase):
def test_lacking_parent(self):
- with support.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
+ with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
loader = importlib._PyFileLoader('_pkg.mod', mapping['_pkg.mod'],
False)
module = loader.load_module('_pkg.mod')
@@ -56,7 +57,7 @@ class SimpleTest(unittest.TestCase):
return lambda name: fxn(name) + 1
def test_module_reuse(self):
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
module = loader.load_module('_temp')
module_id = id(module)
@@ -81,7 +82,7 @@ class SimpleTest(unittest.TestCase):
attributes = ('__file__', '__path__', '__package__')
value = '<test>'
name = '_temp'
- with support.create_modules(name) as mapping:
+ with source_util.create_modules(name) as mapping:
orig_module = imp.new_module(name)
for attr in attributes:
setattr(orig_module, attr, value)
@@ -94,7 +95,7 @@ class SimpleTest(unittest.TestCase):
# [syntax error]
def test_bad_syntax(self):
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
with open(mapping['_temp'], 'w') as file:
file.write('=')
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
@@ -109,12 +110,12 @@ class DontWriteBytecodeTest(unittest.TestCase):
def tearDown(self):
sys.dont_write_bytecode = False
- @support.writes_bytecode
+ @source_util.writes_bytecode
def run_test(self, assertion):
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
loader.load_module('_temp')
- bytecode_path = support.bytecode_path(mapping['_temp'])
+ bytecode_path = source_util.bytecode_path(mapping['_temp'])
assertion(bytecode_path)
def test_bytecode_written(self):
@@ -137,10 +138,10 @@ class BadDataTest(unittest.TestCase):
# [bad magic]
def test_bad_magic(self):
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
py_compile.compile(mapping['_temp'])
os.unlink(mapping['_temp'])
- bytecode_path = support.bytecode_path(mapping['_temp'])
+ bytecode_path = source_util.bytecode_path(mapping['_temp'])
with open(bytecode_path, 'r+b') as file:
file.seek(0)
file.write(b'\x00\x00\x00\x00')
@@ -164,7 +165,7 @@ class SourceBytecodeInteraction(unittest.TestCase):
def run_test(self, test, *create, pkg=False):
create += (test,)
- with support.create_modules(*create) as mapping:
+ with source_util.create_modules(*create) as mapping:
for name in create:
py_compile.compile(mapping[name])
if pkg:
@@ -217,11 +218,11 @@ class BadBytecodeTest(unittest.TestCase):
self.assert_(module_name in sys.modules)
# [bad magic]
- @support.writes_bytecode
+ @source_util.writes_bytecode
def test_bad_magic(self):
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
py_compile.compile(mapping['_temp'])
- bytecode_path = support.bytecode_path(mapping['_temp'])
+ bytecode_path = source_util.bytecode_path(mapping['_temp'])
with open(bytecode_path, 'r+b') as bytecode_file:
bytecode_file.seek(0)
bytecode_file.write(b'\x00\x00\x00\x00')
@@ -230,12 +231,12 @@ class BadBytecodeTest(unittest.TestCase):
self.assertEqual(bytecode_file.read(4), imp.get_magic())
# [bad timestamp]
- @support.writes_bytecode
+ @source_util.writes_bytecode
def test_bad_bytecode(self):
zeros = b'\x00\x00\x00\x00'
- with support.create_modules('_temp') as mapping:
+ with source_util.create_modules('_temp') as mapping:
py_compile.compile(mapping['_temp'])
- bytecode_path = support.bytecode_path(mapping['_temp'])
+ bytecode_path = source_util.bytecode_path(mapping['_temp'])
with open(bytecode_path, 'r+b') as bytecode_file:
bytecode_file.seek(4)
bytecode_file.write(zeros)
@@ -248,8 +249,8 @@ class BadBytecodeTest(unittest.TestCase):
# [bad marshal]
def test_bad_marshal(self):
- with support.create_modules('_temp') as mapping:
- bytecode_path = support.bytecode_path(mapping['_temp'])
+ with source_util.create_modules('_temp') as mapping:
+ bytecode_path = source_util.bytecode_path(mapping['_temp'])
source_mtime = os.path.getmtime(mapping['_temp'])
source_timestamp = importlib._w_long(source_mtime)
with open(bytecode_path, 'wb') as bytecode_file:
diff --git a/Lib/importlib/test/source/test_path_hook.py b/Lib/importlib/test/source/test_path_hook.py
index ef410779..5fa3fd9 100644
--- a/Lib/importlib/test/source/test_path_hook.py
+++ b/Lib/importlib/test/source/test_path_hook.py
@@ -1,5 +1,5 @@
import importlib
-from .. import support
+from . import util
import unittest
@@ -9,7 +9,7 @@ class PathHookTest(unittest.TestCase):
def test_success(self):
# XXX Only work on existing directories?
- with support.create_modules('dummy') as mapping:
+ with util.create_modules('dummy') as mapping:
self.assert_(hasattr(importlib.FileImporter(mapping['.root']),
'find_module'))
diff --git a/Lib/importlib/test/source/test_source_encoding.py b/Lib/importlib/test/source/test_source_encoding.py
index 97096df..7c9a57b 100644
--- a/Lib/importlib/test/source/test_source_encoding.py
+++ b/Lib/importlib/test/source/test_source_encoding.py
@@ -1,5 +1,6 @@
import importlib
from .. import support
+from . import util as source_util
import codecs
import re
@@ -32,7 +33,7 @@ class EncodingTest(unittest.TestCase):
module_name = '_temp'
def run_test(self, source):
- with support.create_modules(self.module_name) as mapping:
+ with source_util.create_modules(self.module_name) as mapping:
with open(mapping[self.module_name], 'wb')as file:
file.write(source)
loader = importlib._PyFileLoader(self.module_name,
@@ -93,7 +94,7 @@ class LineEndingTest(unittest.TestCase):
module_name = '_temp'
source_lines = [b"a = 42", b"b = -13", b'']
source = line_ending.join(source_lines)
- with support.create_modules(module_name) as mapping:
+ with source_util.create_modules(module_name) as mapping:
with open(mapping[module_name], 'wb') as file:
file.write(source)
loader = importlib._PyFileLoader(module_name, mapping[module_name],
diff --git a/Lib/importlib/test/source/util.py b/Lib/importlib/test/source/util.py
new file mode 100644
index 0000000..5400c82
--- /dev/null
+++ b/Lib/importlib/test/source/util.py
@@ -0,0 +1,88 @@
+from .. import support as util
+import contextlib
+import imp
+import os
+import os.path
+import sys
+import tempfile
+from test import support as support
+
+
+def writes_bytecode(fxn):
+ """Decorator that returns the function if writing bytecode is enabled, else
+ a stub function that accepts anything and simply returns None."""
+ if sys.dont_write_bytecode:
+ return lambda *args, **kwargs: None
+ else:
+ return fxn
+
+
+def bytecode_path(source_path):
+ for suffix, _, type_ in imp.get_suffixes():
+ if type_ == imp.PY_COMPILED:
+ bc_suffix = suffix
+ break
+ else:
+ raise ValueError("no bytecode suffix is defined")
+ return os.path.splitext(source_path)[0] + bc_suffix
+
+
+@contextlib.contextmanager
+def create_modules(*names):
+ """Temporarily create each named module with an attribute (named 'attr')
+ that contains the name passed into the context manager that caused the
+ creation of the module.
+
+ All files are created in a temporary directory specified by
+ tempfile.gettempdir(). This directory is inserted at the beginning of
+ sys.path. When the context manager exits all created files (source and
+ bytecode) are explicitly deleted.
+
+ No magic is performed when creating packages! This means that if you create
+ a module within a package you must also create the package's __init__ as
+ well.
+
+ """
+ source = 'attr = {0!r}'
+ created_paths = []
+ mapping = {}
+ try:
+ temp_dir = tempfile.gettempdir()
+ mapping['.root'] = temp_dir
+ import_names = set()
+ for name in names:
+ if not name.endswith('__init__'):
+ import_name = name
+ else:
+ import_name = name[:-len('.__init__')]
+ import_names.add(import_name)
+ if import_name in sys.modules:
+ del sys.modules[import_name]
+ name_parts = name.split('.')
+ file_path = temp_dir
+ for directory in name_parts[:-1]:
+ file_path = os.path.join(file_path, directory)
+ if not os.path.exists(file_path):
+ os.mkdir(file_path)
+ created_paths.append(file_path)
+ file_path = os.path.join(file_path, name_parts[-1] + '.py')
+ with open(file_path, 'w') as file:
+ file.write(source.format(name))
+ created_paths.append(file_path)
+ mapping[name] = file_path
+ uncache_manager = util.uncache(*import_names)
+ uncache_manager.__enter__()
+ state_manager = util.import_state(path=[temp_dir])
+ state_manager.__enter__()
+ yield mapping
+ finally:
+ state_manager.__exit__(None, None, None)
+ uncache_manager.__exit__(None, None, None)
+ # Reverse the order for path removal to unroll directory creation.
+ for path in reversed(created_paths):
+ if file_path.endswith('.py'):
+ support.unlink(path)
+ support.unlink(path + 'c')
+ support.unlink(path + 'o')
+ else:
+ os.rmdir(path)
diff --git a/Lib/importlib/test/support.py b/Lib/importlib/test/support.py
index 3097811..1518d74 100644
--- a/Lib/importlib/test/support.py
+++ b/Lib/importlib/test/support.py
@@ -6,7 +6,6 @@ import imp
import os.path
from test.support import unlink
import sys
-from tempfile import gettempdir
using___import__ = False
@@ -28,14 +27,6 @@ def importlib_only(fxn):
update_wrapper(inner, fxn)
return inner
-def writes_bytecode(fxn):
- """Decorator that returns the function if writing bytecode is enabled, else
- a stub function that accepts anything and simply returns None."""
- if sys.dont_write_bytecode:
- return lambda *args, **kwargs: None
- else:
- return fxn
-
def case_insensitive_tests(class_):
"""Class decorator that nullifies tests that require a case-insensitive
@@ -102,67 +93,6 @@ def import_state(**kwargs):
setattr(sys, attr, value)
-@contextmanager
-def create_modules(*names):
- """Temporarily create each named module with an attribute (named 'attr')
- that contains the name passed into the context manager that caused the
- creation of the module.
-
- All files are created in a temporary directory specified by
- tempfile.gettempdir(). This directory is inserted at the beginning of
- sys.path. When the context manager exits all created files (source and
- bytecode) are explicitly deleted.
-
- No magic is performed when creating packages! This means that if you create
- a module within a package you must also create the package's __init__ as
- well.
-
- """
- source = 'attr = {0!r}'
- created_paths = []
- mapping = {}
- try:
- temp_dir = gettempdir()
- mapping['.root'] = temp_dir
- import_names = set()
- for name in names:
- if not name.endswith('__init__'):
- import_name = name
- else:
- import_name = name[:-len('.__init__')]
- import_names.add(import_name)
- if import_name in sys.modules:
- del sys.modules[import_name]
- name_parts = name.split('.')
- file_path = temp_dir
- for directory in name_parts[:-1]:
- file_path = os.path.join(file_path, directory)
- if not os.path.exists(file_path):
- os.mkdir(file_path)
- created_paths.append(file_path)
- file_path = os.path.join(file_path, name_parts[-1] + '.py')
- with open(file_path, 'w') as file:
- file.write(source.format(name))
- created_paths.append(file_path)
- mapping[name] = file_path
- uncache_manager = uncache(*import_names)
- uncache_manager.__enter__()
- state_manager = import_state(path=[temp_dir])
- state_manager.__enter__()
- yield mapping
- finally:
- state_manager.__exit__(None, None, None)
- uncache_manager.__exit__(None, None, None)
- # Reverse the order for path removal to unroll directory creation.
- for path in reversed(created_paths):
- if file_path.endswith('.py'):
- unlink(path)
- unlink(path + 'c')
- unlink(path + 'o')
- else:
- os.rmdir(path)
-
-
class mock_modules:
"""A mock importer/loader."""
@@ -221,13 +151,3 @@ def mock_path_hook(*entries, importer):
raise ImportError
return importer
return hook
-
-
-def bytecode_path(source_path):
- for suffix, _, type_ in imp.get_suffixes():
- if type_ == imp.PY_COMPILED:
- bc_suffix = suffix
- break
- else:
- raise ValueError("no bytecode suffix is defined")
- return os.path.splitext(source_path)[0] + bc_suffix