diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2020-09-23 17:26:24 -0400 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2020-09-23 17:26:34 -0400 |
commit | 8cca69b8ffd372ce5e3089cebbdbf92c071f3761 (patch) | |
tree | 6300de4fda7c64f81ecc98e54c1ca3e3ea9bd5d5 /setuptools/_distutils/tests/support.py | |
parent | f852d1598a7814f5f4f6e8bf26d3d60cffe1798a (diff) | |
parent | 662816b65fbbfaf4e8ff523e39a6034785a4d8eb (diff) | |
download | python-setuptools-git-feature/2093-docs-revamp.tar.gz |
Merge branch 'master' into feature/2093-docs-revampfeature/2093-docs-revamp
Diffstat (limited to 'setuptools/_distutils/tests/support.py')
-rw-r--r-- | setuptools/_distutils/tests/support.py | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/setuptools/_distutils/tests/support.py b/setuptools/_distutils/tests/support.py new file mode 100644 index 00000000..b4410fc9 --- /dev/null +++ b/setuptools/_distutils/tests/support.py @@ -0,0 +1,210 @@ +"""Support code for distutils test cases.""" +import os +import sys +import shutil +import tempfile +import unittest +import sysconfig +from copy import deepcopy + +from . import py38compat as os_helper + +from distutils import log +from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL +from distutils.core import Distribution + + +class LoggingSilencer(object): + + def setUp(self): + super().setUp() + self.threshold = log.set_threshold(log.FATAL) + # catching warnings + # when log will be replaced by logging + # we won't need such monkey-patch anymore + self._old_log = log.Log._log + log.Log._log = self._log + self.logs = [] + + def tearDown(self): + log.set_threshold(self.threshold) + log.Log._log = self._old_log + super().tearDown() + + def _log(self, level, msg, args): + if level not in (DEBUG, INFO, WARN, ERROR, FATAL): + raise ValueError('%s wrong log level' % str(level)) + if not isinstance(msg, str): + raise TypeError("msg should be str, not '%.200s'" + % (type(msg).__name__)) + self.logs.append((level, msg, args)) + + def get_logs(self, *levels): + return [msg % args for level, msg, args + in self.logs if level in levels] + + def clear_logs(self): + self.logs = [] + + +class TempdirManager(object): + """Mix-in class that handles temporary directories for test cases. + + This is intended to be used with unittest.TestCase. + """ + + def setUp(self): + super().setUp() + self.old_cwd = os.getcwd() + self.tempdirs = [] + + def tearDown(self): + # Restore working dir, for Solaris and derivatives, where rmdir() + # on the current directory fails. + os.chdir(self.old_cwd) + super().tearDown() + while self.tempdirs: + tmpdir = self.tempdirs.pop() + os_helper.rmtree(tmpdir) + + def mkdtemp(self): + """Create a temporary directory that will be cleaned up. + + Returns the path of the directory. + """ + d = tempfile.mkdtemp() + self.tempdirs.append(d) + return d + + def write_file(self, path, content='xxx'): + """Writes a file in the given path. + + + path can be a string or a sequence. + """ + if isinstance(path, (list, tuple)): + path = os.path.join(*path) + f = open(path, 'w') + try: + f.write(content) + finally: + f.close() + + def create_dist(self, pkg_name='foo', **kw): + """Will generate a test environment. + + This function creates: + - a Distribution instance using keywords + - a temporary directory with a package structure + + It returns the package directory and the distribution + instance. + """ + tmp_dir = self.mkdtemp() + pkg_dir = os.path.join(tmp_dir, pkg_name) + os.mkdir(pkg_dir) + dist = Distribution(attrs=kw) + + return pkg_dir, dist + + +class DummyCommand: + """Class to store options for retrieval via set_undefined_options().""" + + def __init__(self, **kwargs): + for kw, val in kwargs.items(): + setattr(self, kw, val) + + def ensure_finalized(self): + pass + + +class EnvironGuard(object): + + def setUp(self): + super(EnvironGuard, self).setUp() + self.old_environ = deepcopy(os.environ) + + def tearDown(self): + for key, value in self.old_environ.items(): + if os.environ.get(key) != value: + os.environ[key] = value + + for key in tuple(os.environ.keys()): + if key not in self.old_environ: + del os.environ[key] + + super(EnvironGuard, self).tearDown() + + +def copy_xxmodule_c(directory): + """Helper for tests that need the xxmodule.c source file. + + Example use: + + def test_compile(self): + copy_xxmodule_c(self.tmpdir) + self.assertIn('xxmodule.c', os.listdir(self.tmpdir)) + + If the source file can be found, it will be copied to *directory*. If not, + the test will be skipped. Errors during copy are not caught. + """ + filename = _get_xxmodule_path() + if filename is None: + raise unittest.SkipTest('cannot find xxmodule.c (test must run in ' + 'the python build dir)') + shutil.copy(filename, directory) + + +def _get_xxmodule_path(): + srcdir = sysconfig.get_config_var('srcdir') + candidates = [ + # use installed copy if available + os.path.join(os.path.dirname(__file__), 'xxmodule.c'), + # otherwise try using copy from build directory + os.path.join(srcdir, 'Modules', 'xxmodule.c'), + # srcdir mysteriously can be $srcdir/Lib/distutils/tests when + # this file is run from its parent directory, so walk up the + # tree to find the real srcdir + os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'), + ] + for path in candidates: + if os.path.exists(path): + return path + + +def fixup_build_ext(cmd): + """Function needed to make build_ext tests pass. + + When Python was built with --enable-shared on Unix, -L. is not enough to + find libpython<blah>.so, because regrtest runs in a tempdir, not in the + source directory where the .so lives. + + When Python was built with in debug mode on Windows, build_ext commands + need their debug attribute set, and it is not done automatically for + some reason. + + This function handles both of these things. Example use: + + cmd = build_ext(dist) + support.fixup_build_ext(cmd) + cmd.ensure_finalized() + + Unlike most other Unix platforms, Mac OS X embeds absolute paths + to shared libraries into executables, so the fixup is not needed there. + """ + if os.name == 'nt': + cmd.debug = sys.executable.endswith('_d.exe') + elif sysconfig.get_config_var('Py_ENABLE_SHARED'): + # To further add to the shared builds fun on Unix, we can't just add + # library_dirs to the Extension() instance because that doesn't get + # plumbed through to the final compiler command. + runshared = sysconfig.get_config_var('RUNSHARED') + if runshared is None: + cmd.library_dirs = ['.'] + else: + if sys.platform == 'darwin': + cmd.library_dirs = [] + else: + name, equals, value = runshared.partition('=') + cmd.library_dirs = [d for d in value.split(os.pathsep) if d] |