mirror of
https://github.com/python/cpython.git
synced 2025-07-23 11:15:24 +00:00
Split out support code that is specific to source tests out of
importlib.test.support to importlib.test.source.util.
This commit is contained in:
parent
30b047dc35
commit
4ee2cdaf65
8 changed files with 123 additions and 113 deletions
|
@ -3,9 +3,6 @@ to do
|
||||||
|
|
||||||
* Reorganize support code.
|
* 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.
|
+ Add a file loader mock that returns monotonically increasing mtime.
|
||||||
- Use in source/test_reload.
|
- Use in source/test_reload.
|
||||||
- Use in source/test_load_module_mixed.
|
- Use in source/test_load_module_mixed.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Test case-sensitivity (PEP 235)."""
|
"""Test case-sensitivity (PEP 235)."""
|
||||||
import importlib
|
import importlib
|
||||||
from .. import support
|
from .. import support
|
||||||
|
from . import util as source_util
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from test import support as test_support
|
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."""
|
"""Look for a module with matching and non-matching sensitivity."""
|
||||||
sensitive_pkg = 'sensitive.{0}'.format(self.name)
|
sensitive_pkg = 'sensitive.{0}'.format(self.name)
|
||||||
insensitive_pkg = 'insensitive.{0}'.format(self.name.lower())
|
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')
|
sensitive_path = os.path.join(mapping['.root'], 'sensitive')
|
||||||
insensitive_path = os.path.join(mapping['.root'], 'insensitive')
|
insensitive_path = os.path.join(mapping['.root'], 'insensitive')
|
||||||
return self.find(sensitive_path), self.find(insensitive_path)
|
return self.find(sensitive_path), self.find(insensitive_path)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import importlib
|
import importlib
|
||||||
from .. import abc
|
from .. import abc
|
||||||
from .. import support
|
from .. import support
|
||||||
|
from . import util as source_util
|
||||||
import os
|
import os
|
||||||
import py_compile
|
import py_compile
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -45,7 +46,7 @@ class FinderTests(abc.FinderTests):
|
||||||
"""
|
"""
|
||||||
if create is None:
|
if create is None:
|
||||||
create = {test}
|
create = {test}
|
||||||
with support.create_modules(*create) as mapping:
|
with source_util.create_modules(*create) as mapping:
|
||||||
if compile_:
|
if compile_:
|
||||||
for name in compile_:
|
for name in compile_:
|
||||||
py_compile.compile(mapping[name])
|
py_compile.compile(mapping[name])
|
||||||
|
@ -76,14 +77,14 @@ class FinderTests(abc.FinderTests):
|
||||||
|
|
||||||
# [sub module]
|
# [sub module]
|
||||||
def test_module_in_package(self):
|
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__'])
|
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
|
||||||
loader = self.import_(pkg_dir, 'pkg.sub')
|
loader = self.import_(pkg_dir, 'pkg.sub')
|
||||||
self.assert_(hasattr(loader, 'load_module'))
|
self.assert_(hasattr(loader, 'load_module'))
|
||||||
|
|
||||||
# [sub package]
|
# [sub package]
|
||||||
def test_package_in_package(self):
|
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:
|
with context as mapping:
|
||||||
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
|
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
|
||||||
loader = self.import_(pkg_dir, 'pkg.sub')
|
loader = self.import_(pkg_dir, 'pkg.sub')
|
||||||
|
@ -91,7 +92,7 @@ class FinderTests(abc.FinderTests):
|
||||||
|
|
||||||
# [sub empty]
|
# [sub empty]
|
||||||
def test_empty_sub_directory(self):
|
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():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("error", ImportWarning)
|
warnings.simplefilter("error", ImportWarning)
|
||||||
with context as mapping:
|
with context as mapping:
|
||||||
|
@ -109,7 +110,7 @@ class FinderTests(abc.FinderTests):
|
||||||
|
|
||||||
|
|
||||||
def test_failure(self):
|
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')
|
nothing = self.import_(mapping['.root'], 'sdfsadsadf')
|
||||||
self.assert_(nothing is None)
|
self.assert_(nothing is None)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import importlib
|
import importlib
|
||||||
from .. import abc
|
from .. import abc
|
||||||
from .. import support
|
from .. import support
|
||||||
|
from . import util as source_util
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import os
|
import os
|
||||||
|
@ -18,7 +19,7 @@ class SimpleTest(unittest.TestCase):
|
||||||
|
|
||||||
# [basic]
|
# [basic]
|
||||||
def test_module(self):
|
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)
|
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
|
||||||
module = loader.load_module('_temp')
|
module = loader.load_module('_temp')
|
||||||
self.assert_('_temp' in sys.modules)
|
self.assert_('_temp' in sys.modules)
|
||||||
|
@ -28,7 +29,7 @@ class SimpleTest(unittest.TestCase):
|
||||||
self.assertEqual(getattr(module, attr), value)
|
self.assertEqual(getattr(module, attr), value)
|
||||||
|
|
||||||
def test_package(self):
|
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__'],
|
loader = importlib._PyFileLoader('_pkg', mapping['_pkg.__init__'],
|
||||||
True)
|
True)
|
||||||
module = loader.load_module('_pkg')
|
module = loader.load_module('_pkg')
|
||||||
|
@ -41,7 +42,7 @@ class SimpleTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_lacking_parent(self):
|
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'],
|
loader = importlib._PyFileLoader('_pkg.mod', mapping['_pkg.mod'],
|
||||||
False)
|
False)
|
||||||
module = loader.load_module('_pkg.mod')
|
module = loader.load_module('_pkg.mod')
|
||||||
|
@ -56,7 +57,7 @@ class SimpleTest(unittest.TestCase):
|
||||||
return lambda name: fxn(name) + 1
|
return lambda name: fxn(name) + 1
|
||||||
|
|
||||||
def test_module_reuse(self):
|
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)
|
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
|
||||||
module = loader.load_module('_temp')
|
module = loader.load_module('_temp')
|
||||||
module_id = id(module)
|
module_id = id(module)
|
||||||
|
@ -81,7 +82,7 @@ class SimpleTest(unittest.TestCase):
|
||||||
attributes = ('__file__', '__path__', '__package__')
|
attributes = ('__file__', '__path__', '__package__')
|
||||||
value = '<test>'
|
value = '<test>'
|
||||||
name = '_temp'
|
name = '_temp'
|
||||||
with support.create_modules(name) as mapping:
|
with source_util.create_modules(name) as mapping:
|
||||||
orig_module = imp.new_module(name)
|
orig_module = imp.new_module(name)
|
||||||
for attr in attributes:
|
for attr in attributes:
|
||||||
setattr(orig_module, attr, value)
|
setattr(orig_module, attr, value)
|
||||||
|
@ -94,7 +95,7 @@ class SimpleTest(unittest.TestCase):
|
||||||
|
|
||||||
# [syntax error]
|
# [syntax error]
|
||||||
def test_bad_syntax(self):
|
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:
|
with open(mapping['_temp'], 'w') as file:
|
||||||
file.write('=')
|
file.write('=')
|
||||||
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
|
loader = importlib._PyFileLoader('_temp', mapping['_temp'], False)
|
||||||
|
@ -109,12 +110,12 @@ class DontWriteBytecodeTest(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
sys.dont_write_bytecode = False
|
sys.dont_write_bytecode = False
|
||||||
|
|
||||||
@support.writes_bytecode
|
@source_util.writes_bytecode
|
||||||
def run_test(self, assertion):
|
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 = importlib._PyFileLoader('_temp', mapping['_temp'], False)
|
||||||
loader.load_module('_temp')
|
loader.load_module('_temp')
|
||||||
bytecode_path = support.bytecode_path(mapping['_temp'])
|
bytecode_path = source_util.bytecode_path(mapping['_temp'])
|
||||||
assertion(bytecode_path)
|
assertion(bytecode_path)
|
||||||
|
|
||||||
def test_bytecode_written(self):
|
def test_bytecode_written(self):
|
||||||
|
@ -137,10 +138,10 @@ class BadDataTest(unittest.TestCase):
|
||||||
|
|
||||||
# [bad magic]
|
# [bad magic]
|
||||||
def test_bad_magic(self):
|
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'])
|
py_compile.compile(mapping['_temp'])
|
||||||
os.unlink(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:
|
with open(bytecode_path, 'r+b') as file:
|
||||||
file.seek(0)
|
file.seek(0)
|
||||||
file.write(b'\x00\x00\x00\x00')
|
file.write(b'\x00\x00\x00\x00')
|
||||||
|
@ -164,7 +165,7 @@ class SourceBytecodeInteraction(unittest.TestCase):
|
||||||
|
|
||||||
def run_test(self, test, *create, pkg=False):
|
def run_test(self, test, *create, pkg=False):
|
||||||
create += (test,)
|
create += (test,)
|
||||||
with support.create_modules(*create) as mapping:
|
with source_util.create_modules(*create) as mapping:
|
||||||
for name in create:
|
for name in create:
|
||||||
py_compile.compile(mapping[name])
|
py_compile.compile(mapping[name])
|
||||||
if pkg:
|
if pkg:
|
||||||
|
@ -217,11 +218,11 @@ class BadBytecodeTest(unittest.TestCase):
|
||||||
self.assert_(module_name in sys.modules)
|
self.assert_(module_name in sys.modules)
|
||||||
|
|
||||||
# [bad magic]
|
# [bad magic]
|
||||||
@support.writes_bytecode
|
@source_util.writes_bytecode
|
||||||
def test_bad_magic(self):
|
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'])
|
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:
|
with open(bytecode_path, 'r+b') as bytecode_file:
|
||||||
bytecode_file.seek(0)
|
bytecode_file.seek(0)
|
||||||
bytecode_file.write(b'\x00\x00\x00\x00')
|
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())
|
self.assertEqual(bytecode_file.read(4), imp.get_magic())
|
||||||
|
|
||||||
# [bad timestamp]
|
# [bad timestamp]
|
||||||
@support.writes_bytecode
|
@source_util.writes_bytecode
|
||||||
def test_bad_bytecode(self):
|
def test_bad_bytecode(self):
|
||||||
zeros = b'\x00\x00\x00\x00'
|
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'])
|
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:
|
with open(bytecode_path, 'r+b') as bytecode_file:
|
||||||
bytecode_file.seek(4)
|
bytecode_file.seek(4)
|
||||||
bytecode_file.write(zeros)
|
bytecode_file.write(zeros)
|
||||||
|
@ -248,8 +249,8 @@ class BadBytecodeTest(unittest.TestCase):
|
||||||
|
|
||||||
# [bad marshal]
|
# [bad marshal]
|
||||||
def test_bad_marshal(self):
|
def test_bad_marshal(self):
|
||||||
with support.create_modules('_temp') as mapping:
|
with source_util.create_modules('_temp') as mapping:
|
||||||
bytecode_path = support.bytecode_path(mapping['_temp'])
|
bytecode_path = source_util.bytecode_path(mapping['_temp'])
|
||||||
source_mtime = os.path.getmtime(mapping['_temp'])
|
source_mtime = os.path.getmtime(mapping['_temp'])
|
||||||
source_timestamp = importlib._w_long(source_mtime)
|
source_timestamp = importlib._w_long(source_mtime)
|
||||||
with open(bytecode_path, 'wb') as bytecode_file:
|
with open(bytecode_path, 'wb') as bytecode_file:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import importlib
|
import importlib
|
||||||
from .. import support
|
from . import util
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ class PathHookTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_success(self):
|
def test_success(self):
|
||||||
# XXX Only work on existing directories?
|
# 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']),
|
self.assert_(hasattr(importlib.FileImporter(mapping['.root']),
|
||||||
'find_module'))
|
'find_module'))
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import importlib
|
import importlib
|
||||||
from .. import support
|
from .. import support
|
||||||
|
from . import util as source_util
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import re
|
import re
|
||||||
|
@ -32,7 +33,7 @@ class EncodingTest(unittest.TestCase):
|
||||||
module_name = '_temp'
|
module_name = '_temp'
|
||||||
|
|
||||||
def run_test(self, source):
|
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:
|
with open(mapping[self.module_name], 'wb')as file:
|
||||||
file.write(source)
|
file.write(source)
|
||||||
loader = importlib._PyFileLoader(self.module_name,
|
loader = importlib._PyFileLoader(self.module_name,
|
||||||
|
@ -93,7 +94,7 @@ class LineEndingTest(unittest.TestCase):
|
||||||
module_name = '_temp'
|
module_name = '_temp'
|
||||||
source_lines = [b"a = 42", b"b = -13", b'']
|
source_lines = [b"a = 42", b"b = -13", b'']
|
||||||
source = line_ending.join(source_lines)
|
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:
|
with open(mapping[module_name], 'wb') as file:
|
||||||
file.write(source)
|
file.write(source)
|
||||||
loader = importlib._PyFileLoader(module_name, mapping[module_name],
|
loader = importlib._PyFileLoader(module_name, mapping[module_name],
|
||||||
|
|
88
Lib/importlib/test/source/util.py
Normal file
88
Lib/importlib/test/source/util.py
Normal file
|
@ -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)
|
|
@ -6,7 +6,6 @@ import imp
|
||||||
import os.path
|
import os.path
|
||||||
from test.support import unlink
|
from test.support import unlink
|
||||||
import sys
|
import sys
|
||||||
from tempfile import gettempdir
|
|
||||||
|
|
||||||
|
|
||||||
using___import__ = False
|
using___import__ = False
|
||||||
|
@ -28,14 +27,6 @@ def importlib_only(fxn):
|
||||||
update_wrapper(inner, fxn)
|
update_wrapper(inner, fxn)
|
||||||
return inner
|
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_):
|
def case_insensitive_tests(class_):
|
||||||
"""Class decorator that nullifies tests that require a case-insensitive
|
"""Class decorator that nullifies tests that require a case-insensitive
|
||||||
|
@ -102,67 +93,6 @@ def import_state(**kwargs):
|
||||||
setattr(sys, attr, value)
|
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:
|
class mock_modules:
|
||||||
|
|
||||||
"""A mock importer/loader."""
|
"""A mock importer/loader."""
|
||||||
|
@ -221,13 +151,3 @@ def mock_path_hook(*entries, importer):
|
||||||
raise ImportError
|
raise ImportError
|
||||||
return importer
|
return importer
|
||||||
return hook
|
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
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue