ยปCore Development>Code coverage>Lib/importlib/test/util.py

Python code coverage for Lib/importlib/test/util.py

#countcontent
1n/afrom contextlib import contextmanager
2n/aimport imp
3n/aimport os.path
4n/afrom test import support
5n/aimport unittest
6n/aimport sys
7n/a
8n/a
9n/aCASE_INSENSITIVE_FS = True
10n/a# Windows is the only OS that is *always* case-insensitive
11n/a# (OS X *can* be case-sensitive).
12n/aif sys.platform not in ('win32', 'cygwin'):
13n/a changed_name = __file__.upper()
14n/a if changed_name == __file__:
15n/a changed_name = __file__.lower()
16n/a if not os.path.exists(changed_name):
17n/a CASE_INSENSITIVE_FS = False
18n/a
19n/a
20n/adef case_insensitive_tests(test):
21n/a """Class decorator that nullifies tests requiring a case-insensitive
22n/a file system."""
23n/a return unittest.skipIf(not CASE_INSENSITIVE_FS,
24n/a "requires a case-insensitive filesystem")(test)
25n/a
26n/a
27n/a@contextmanager
28n/adef uncache(*names):
29n/a """Uncache a module from sys.modules.
30n/a
31n/a A basic sanity check is performed to prevent uncaching modules that either
32n/a cannot/shouldn't be uncached.
33n/a
34n/a """
35n/a for name in names:
36n/a if name in ('sys', 'marshal', 'imp'):
37n/a raise ValueError(
38n/a "cannot uncache {0}".format(name))
39n/a try:
40n/a del sys.modules[name]
41n/a except KeyError:
42n/a pass
43n/a try:
44n/a yield
45n/a finally:
46n/a for name in names:
47n/a try:
48n/a del sys.modules[name]
49n/a except KeyError:
50n/a pass
51n/a
52n/a@contextmanager
53n/adef import_state(**kwargs):
54n/a """Context manager to manage the various importers and stored state in the
55n/a sys module.
56n/a
57n/a The 'modules' attribute is not supported as the interpreter state stores a
58n/a pointer to the dict that the interpreter uses internally;
59n/a reassigning to sys.modules does not have the desired effect.
60n/a
61n/a """
62n/a originals = {}
63n/a try:
64n/a for attr, default in (('meta_path', []), ('path', []),
65n/a ('path_hooks', []),
66n/a ('path_importer_cache', {})):
67n/a originals[attr] = getattr(sys, attr)
68n/a if attr in kwargs:
69n/a new_value = kwargs[attr]
70n/a del kwargs[attr]
71n/a else:
72n/a new_value = default
73n/a setattr(sys, attr, new_value)
74n/a if len(kwargs):
75n/a raise ValueError(
76n/a 'unrecognized arguments: {0}'.format(kwargs.keys()))
77n/a yield
78n/a finally:
79n/a for attr, value in originals.items():
80n/a setattr(sys, attr, value)
81n/a
82n/a
83n/aclass mock_modules:
84n/a
85n/a """A mock importer/loader."""
86n/a
87n/a def __init__(self, *names, module_code={}):
88n/a self.modules = {}
89n/a self.module_code = {}
90n/a for name in names:
91n/a if not name.endswith('.__init__'):
92n/a import_name = name
93n/a else:
94n/a import_name = name[:-len('.__init__')]
95n/a if '.' not in name:
96n/a package = None
97n/a elif import_name == name:
98n/a package = name.rsplit('.', 1)[0]
99n/a else:
100n/a package = import_name
101n/a module = imp.new_module(import_name)
102n/a module.__loader__ = self
103n/a module.__file__ = '<mock __file__>'
104n/a module.__package__ = package
105n/a module.attr = name
106n/a if import_name != name:
107n/a module.__path__ = ['<mock __path__>']
108n/a self.modules[import_name] = module
109n/a if import_name in module_code:
110n/a self.module_code[import_name] = module_code[import_name]
111n/a
112n/a def __getitem__(self, name):
113n/a return self.modules[name]
114n/a
115n/a def find_module(self, fullname, path=None):
116n/a if fullname not in self.modules:
117n/a return None
118n/a else:
119n/a return self
120n/a
121n/a def load_module(self, fullname):
122n/a if fullname not in self.modules:
123n/a raise ImportError
124n/a else:
125n/a sys.modules[fullname] = self.modules[fullname]
126n/a if fullname in self.module_code:
127n/a try:
128n/a self.module_code[fullname]()
129n/a except Exception:
130n/a del sys.modules[fullname]
131n/a raise
132n/a return self.modules[fullname]
133n/a
134n/a def __enter__(self):
135n/a self._uncache = uncache(*self.modules.keys())
136n/a self._uncache.__enter__()
137n/a return self
138n/a
139n/a def __exit__(self, *exc_info):
140n/a self._uncache.__exit__(None, None, None)