mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Merged revisions 71465 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r71465 | nick.coghlan | 2009-04-11 23:31:31 +1000 (Sat, 11 Apr 2009) | 1 line Issue 5354: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks ........
This commit is contained in:
parent
2d87e42921
commit
fce769e73d
4 changed files with 105 additions and 34 deletions
|
@ -41,22 +41,63 @@ class ResourceDenied(unittest.SkipTest):
|
|||
and unexpected skips.
|
||||
"""
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _ignore_deprecated_imports(ignore=True):
|
||||
"""Context manager to suppress package and module deprecation
|
||||
warnings when importing them.
|
||||
|
||||
If ignore is False, this context manager has no effect."""
|
||||
if ignore:
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings("ignore", ".+ (module|package)",
|
||||
DeprecationWarning)
|
||||
yield
|
||||
else:
|
||||
yield
|
||||
|
||||
|
||||
def import_module(name, deprecated=False):
|
||||
"""Import and return the module to be tested, raising SkipTest if
|
||||
it is not available.
|
||||
|
||||
If deprecated is True, any module or package deprecation messages
|
||||
will be suppressed."""
|
||||
with warnings.catch_warnings():
|
||||
if deprecated:
|
||||
warnings.filterwarnings("ignore", ".+ (module|package)",
|
||||
DeprecationWarning)
|
||||
with _ignore_deprecated_imports(deprecated):
|
||||
try:
|
||||
module = importlib.import_module(name)
|
||||
return importlib.import_module(name)
|
||||
except ImportError as msg:
|
||||
raise unittest.SkipTest(str(msg))
|
||||
else:
|
||||
return module
|
||||
|
||||
|
||||
def import_fresh_module(name, blocked_names=None, deprecated=False):
|
||||
"""Imports and returns a module, deliberately bypassing the sys.modules cache
|
||||
and importing a fresh copy of the module. Once the import is complete,
|
||||
the sys.modules cache is restored to its original state.
|
||||
|
||||
Importing of modules named in blocked_names is prevented while the fresh import
|
||||
takes place.
|
||||
|
||||
If deprecated is True, any module or package deprecation messages
|
||||
will be suppressed."""
|
||||
# NOTE: test_heapq and test_warnings include extra sanity checks to make
|
||||
# sure that this utility function is working as expected
|
||||
with _ignore_deprecated_imports(deprecated):
|
||||
if blocked_names is None:
|
||||
blocked_names = ()
|
||||
orig_modules = {}
|
||||
if name in sys.modules:
|
||||
orig_modules[name] = sys.modules[name]
|
||||
del sys.modules[name]
|
||||
try:
|
||||
for blocked in blocked_names:
|
||||
orig_modules[blocked] = sys.modules[blocked]
|
||||
sys.modules[blocked] = 0
|
||||
py_module = importlib.import_module(name)
|
||||
finally:
|
||||
for blocked, module in orig_modules.items():
|
||||
sys.modules[blocked] = module
|
||||
return py_module
|
||||
|
||||
|
||||
def get_attribute(obj, name):
|
||||
"""Get an attribute, raising SkipTest if AttributeError is raised."""
|
||||
|
|
|
@ -7,23 +7,8 @@ import sys
|
|||
|
||||
# We do a bit of trickery here to be able to test both the C implementation
|
||||
# and the Python implementation of the module.
|
||||
|
||||
# Make it impossible to import the C implementation anymore.
|
||||
sys.modules['_heapq'] = 0
|
||||
# We must also handle the case that heapq was imported before.
|
||||
if 'heapq' in sys.modules:
|
||||
del sys.modules['heapq']
|
||||
|
||||
# Now we can import the module and get the pure Python implementation.
|
||||
import heapq as py_heapq
|
||||
|
||||
# Restore everything to normal.
|
||||
del sys.modules['_heapq']
|
||||
del sys.modules['heapq']
|
||||
|
||||
# This is now the module with the C implementation.
|
||||
import heapq as c_heapq
|
||||
|
||||
py_heapq = support.import_fresh_module('heapq', ['_heapq'])
|
||||
|
||||
class TestHeap(unittest.TestCase):
|
||||
module = None
|
||||
|
@ -194,6 +179,13 @@ class TestHeap(unittest.TestCase):
|
|||
class TestHeapPython(TestHeap):
|
||||
module = py_heapq
|
||||
|
||||
# As an early adopter, we sanity check the
|
||||
# test.support.import_fresh_module utility function
|
||||
def test_pure_python(self):
|
||||
self.assertFalse(sys.modules['heapq'] is self.module)
|
||||
self.assertTrue(hasattr(self.module.heapify, '__code__'))
|
||||
|
||||
|
||||
class TestHeapC(TestHeap):
|
||||
module = c_heapq
|
||||
|
||||
|
@ -219,6 +211,12 @@ class TestHeapC(TestHeap):
|
|||
self.assertEqual(hsort(data, LT), target)
|
||||
self.assertRaises(TypeError, data, LE)
|
||||
|
||||
# As an early adopter, we sanity check the
|
||||
# test.support.import_fresh_module utility function
|
||||
def test_accelerated(self):
|
||||
self.assertTrue(sys.modules['heapq'] is self.module)
|
||||
self.assertFalse(hasattr(self.module.heapify, '__code__'))
|
||||
|
||||
|
||||
#==============================================================================
|
||||
|
||||
|
|
|
@ -10,18 +10,14 @@ from test import warning_tests
|
|||
|
||||
import warnings as original_warnings
|
||||
|
||||
sys.modules['_warnings'] = 0
|
||||
del sys.modules['warnings']
|
||||
|
||||
import warnings as py_warnings
|
||||
|
||||
py_warnings = support.import_fresh_module('warnings', ['_warnings'])
|
||||
# XXX (ncoghlan 20090412):
|
||||
# Something in Py3k doesn't like sharing the same instance of
|
||||
# _warnings between original_warnings and c_warnings
|
||||
# Will leave issue 5354 open until I understand why 3.x breaks
|
||||
# without the next line, while 2.x doesn't care
|
||||
del sys.modules['_warnings']
|
||||
del sys.modules['warnings']
|
||||
|
||||
import warnings as c_warnings
|
||||
|
||||
sys.modules['warnings'] = original_warnings
|
||||
|
||||
c_warnings = support.import_fresh_module('warnings')
|
||||
|
||||
@contextmanager
|
||||
def warnings_state(module):
|
||||
|
@ -351,9 +347,21 @@ class WarnTests(unittest.TestCase):
|
|||
class CWarnTests(BaseTest, WarnTests):
|
||||
module = c_warnings
|
||||
|
||||
# As an early adopter, we sanity check the
|
||||
# test.support.import_fresh_module utility function
|
||||
def test_accelerated(self):
|
||||
self.assertFalse(original_warnings is self.module)
|
||||
self.assertFalse(hasattr(self.module.warn, '__code__'))
|
||||
|
||||
class PyWarnTests(BaseTest, WarnTests):
|
||||
module = py_warnings
|
||||
|
||||
# As an early adopter, we sanity check the
|
||||
# test.support.import_fresh_module utility function
|
||||
def test_pure_python(self):
|
||||
self.assertFalse(original_warnings is self.module)
|
||||
self.assertTrue(hasattr(self.module.warn, '__code__'))
|
||||
|
||||
|
||||
class WCmdLineTests(unittest.TestCase):
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue