ยปCore Development>Code coverage>Lib/distutils/tests/support.py

Python code coverage for Lib/distutils/tests/support.py

#countcontent
1n/a"""Support code for distutils test cases."""
2n/aimport os
3n/aimport sys
4n/aimport shutil
5n/aimport tempfile
6n/aimport unittest
7n/aimport sysconfig
8n/afrom copy import deepcopy
9n/a
10n/afrom distutils import log
11n/afrom distutils.log import DEBUG, INFO, WARN, ERROR, FATAL
12n/afrom distutils.core import Distribution
13n/a
14n/a
15n/aclass LoggingSilencer(object):
16n/a
17n/a def setUp(self):
18n/a super().setUp()
19n/a self.threshold = log.set_threshold(log.FATAL)
20n/a # catching warnings
21n/a # when log will be replaced by logging
22n/a # we won't need such monkey-patch anymore
23n/a self._old_log = log.Log._log
24n/a log.Log._log = self._log
25n/a self.logs = []
26n/a
27n/a def tearDown(self):
28n/a log.set_threshold(self.threshold)
29n/a log.Log._log = self._old_log
30n/a super().tearDown()
31n/a
32n/a def _log(self, level, msg, args):
33n/a if level not in (DEBUG, INFO, WARN, ERROR, FATAL):
34n/a raise ValueError('%s wrong log level' % str(level))
35n/a if not isinstance(msg, str):
36n/a raise TypeError("msg should be str, not '%.200s'"
37n/a % (type(msg).__name__))
38n/a self.logs.append((level, msg, args))
39n/a
40n/a def get_logs(self, *levels):
41n/a def _format(msg, args):
42n/a return msg % args
43n/a return [msg % args for level, msg, args
44n/a in self.logs if level in levels]
45n/a
46n/a def clear_logs(self):
47n/a self.logs = []
48n/a
49n/a
50n/aclass TempdirManager(object):
51n/a """Mix-in class that handles temporary directories for test cases.
52n/a
53n/a This is intended to be used with unittest.TestCase.
54n/a """
55n/a
56n/a def setUp(self):
57n/a super().setUp()
58n/a self.old_cwd = os.getcwd()
59n/a self.tempdirs = []
60n/a
61n/a def tearDown(self):
62n/a # Restore working dir, for Solaris and derivatives, where rmdir()
63n/a # on the current directory fails.
64n/a os.chdir(self.old_cwd)
65n/a super().tearDown()
66n/a while self.tempdirs:
67n/a d = self.tempdirs.pop()
68n/a shutil.rmtree(d, os.name in ('nt', 'cygwin'))
69n/a
70n/a def mkdtemp(self):
71n/a """Create a temporary directory that will be cleaned up.
72n/a
73n/a Returns the path of the directory.
74n/a """
75n/a d = tempfile.mkdtemp()
76n/a self.tempdirs.append(d)
77n/a return d
78n/a
79n/a def write_file(self, path, content='xxx'):
80n/a """Writes a file in the given path.
81n/a
82n/a
83n/a path can be a string or a sequence.
84n/a """
85n/a if isinstance(path, (list, tuple)):
86n/a path = os.path.join(*path)
87n/a f = open(path, 'w')
88n/a try:
89n/a f.write(content)
90n/a finally:
91n/a f.close()
92n/a
93n/a def create_dist(self, pkg_name='foo', **kw):
94n/a """Will generate a test environment.
95n/a
96n/a This function creates:
97n/a - a Distribution instance using keywords
98n/a - a temporary directory with a package structure
99n/a
100n/a It returns the package directory and the distribution
101n/a instance.
102n/a """
103n/a tmp_dir = self.mkdtemp()
104n/a pkg_dir = os.path.join(tmp_dir, pkg_name)
105n/a os.mkdir(pkg_dir)
106n/a dist = Distribution(attrs=kw)
107n/a
108n/a return pkg_dir, dist
109n/a
110n/a
111n/aclass DummyCommand:
112n/a """Class to store options for retrieval via set_undefined_options()."""
113n/a
114n/a def __init__(self, **kwargs):
115n/a for kw, val in kwargs.items():
116n/a setattr(self, kw, val)
117n/a
118n/a def ensure_finalized(self):
119n/a pass
120n/a
121n/a
122n/aclass EnvironGuard(object):
123n/a
124n/a def setUp(self):
125n/a super(EnvironGuard, self).setUp()
126n/a self.old_environ = deepcopy(os.environ)
127n/a
128n/a def tearDown(self):
129n/a for key, value in self.old_environ.items():
130n/a if os.environ.get(key) != value:
131n/a os.environ[key] = value
132n/a
133n/a for key in tuple(os.environ.keys()):
134n/a if key not in self.old_environ:
135n/a del os.environ[key]
136n/a
137n/a super(EnvironGuard, self).tearDown()
138n/a
139n/a
140n/adef copy_xxmodule_c(directory):
141n/a """Helper for tests that need the xxmodule.c source file.
142n/a
143n/a Example use:
144n/a
145n/a def test_compile(self):
146n/a copy_xxmodule_c(self.tmpdir)
147n/a self.assertIn('xxmodule.c', os.listdir(self.tmpdir))
148n/a
149n/a If the source file can be found, it will be copied to *directory*. If not,
150n/a the test will be skipped. Errors during copy are not caught.
151n/a """
152n/a filename = _get_xxmodule_path()
153n/a if filename is None:
154n/a raise unittest.SkipTest('cannot find xxmodule.c (test must run in '
155n/a 'the python build dir)')
156n/a shutil.copy(filename, directory)
157n/a
158n/a
159n/adef _get_xxmodule_path():
160n/a srcdir = sysconfig.get_config_var('srcdir')
161n/a candidates = [
162n/a # use installed copy if available
163n/a os.path.join(os.path.dirname(__file__), 'xxmodule.c'),
164n/a # otherwise try using copy from build directory
165n/a os.path.join(srcdir, 'Modules', 'xxmodule.c'),
166n/a # srcdir mysteriously can be $srcdir/Lib/distutils/tests when
167n/a # this file is run from its parent directory, so walk up the
168n/a # tree to find the real srcdir
169n/a os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'),
170n/a ]
171n/a for path in candidates:
172n/a if os.path.exists(path):
173n/a return path
174n/a
175n/a
176n/adef fixup_build_ext(cmd):
177n/a """Function needed to make build_ext tests pass.
178n/a
179n/a When Python was built with --enable-shared on Unix, -L. is not enough to
180n/a find libpython<blah>.so, because regrtest runs in a tempdir, not in the
181n/a source directory where the .so lives.
182n/a
183n/a When Python was built with in debug mode on Windows, build_ext commands
184n/a need their debug attribute set, and it is not done automatically for
185n/a some reason.
186n/a
187n/a This function handles both of these things. Example use:
188n/a
189n/a cmd = build_ext(dist)
190n/a support.fixup_build_ext(cmd)
191n/a cmd.ensure_finalized()
192n/a
193n/a Unlike most other Unix platforms, Mac OS X embeds absolute paths
194n/a to shared libraries into executables, so the fixup is not needed there.
195n/a """
196n/a if os.name == 'nt':
197n/a cmd.debug = sys.executable.endswith('_d.exe')
198n/a elif sysconfig.get_config_var('Py_ENABLE_SHARED'):
199n/a # To further add to the shared builds fun on Unix, we can't just add
200n/a # library_dirs to the Extension() instance because that doesn't get
201n/a # plumbed through to the final compiler command.
202n/a runshared = sysconfig.get_config_var('RUNSHARED')
203n/a if runshared is None:
204n/a cmd.library_dirs = ['.']
205n/a else:
206n/a if sys.platform == 'darwin':
207n/a cmd.library_dirs = []
208n/a else:
209n/a name, equals, value = runshared.partition('=')
210n/a cmd.library_dirs = [d for d in value.split(os.pathsep) if d]