Aluode/PerceptionLabPortable
0
1"""Support code for distutils test cases."""2 3import itertools4import os5import pathlib6import shutil7import sys8import sysconfig9import tempfile10from distutils.core import Distribution11 12import pytest13from more_itertools import always_iterable14 15 16@pytest.mark.usefixtures('distutils_managed_tempdir')17class TempdirManager:18 """19 Mix-in class that handles temporary directories for test cases.20 """21 22 def mkdtemp(self):23 """Create a temporary directory that will be cleaned up.24 25 Returns the path of the directory.26 """27 d = tempfile.mkdtemp()28 self.tempdirs.append(d)29 return d30 31 def write_file(self, path, content='xxx'):32 """Writes a file in the given path.33 34 path can be a string or a sequence.35 """36 pathlib.Path(*always_iterable(path)).write_text(content, encoding='utf-8')37 38 def create_dist(self, pkg_name='foo', **kw):39 """Will generate a test environment.40 41 This function creates:42 - a Distribution instance using keywords43 - a temporary directory with a package structure44 45 It returns the package directory and the distribution46 instance.47 """48 tmp_dir = self.mkdtemp()49 pkg_dir = os.path.join(tmp_dir, pkg_name)50 os.mkdir(pkg_dir)51 dist = Distribution(attrs=kw)52 53 return pkg_dir, dist54 55 56class DummyCommand:57 """Class to store options for retrieval via set_undefined_options()."""58 59 def __init__(self, **kwargs):60 vars(self).update(kwargs)61 62 def ensure_finalized(self):63 pass64 65 66def copy_xxmodule_c(directory):67 """Helper for tests that need the xxmodule.c source file.68 69 Example use:70 71 def test_compile(self):72 copy_xxmodule_c(self.tmpdir)73 self.assertIn('xxmodule.c', os.listdir(self.tmpdir))74 75 If the source file can be found, it will be copied to *directory*. If not,76 the test will be skipped. Errors during copy are not caught.77 """78 shutil.copy(_get_xxmodule_path(), os.path.join(directory, 'xxmodule.c'))79 80 81def _get_xxmodule_path():82 source_name = 'xxmodule.c' if sys.version_info > (3, 9) else 'xxmodule-3.8.c'83 return os.path.join(os.path.dirname(__file__), source_name)84 85 86def fixup_build_ext(cmd):87 """Function needed to make build_ext tests pass.88 89 When Python was built with --enable-shared on Unix, -L. is not enough to90 find libpython<blah>.so, because regrtest runs in a tempdir, not in the91 source directory where the .so lives.92 93 When Python was built with in debug mode on Windows, build_ext commands94 need their debug attribute set, and it is not done automatically for95 some reason.96 97 This function handles both of these things. Example use:98 99 cmd = build_ext(dist)100 support.fixup_build_ext(cmd)101 cmd.ensure_finalized()102 103 Unlike most other Unix platforms, Mac OS X embeds absolute paths104 to shared libraries into executables, so the fixup is not needed there.105 """106 if os.name == 'nt':107 cmd.debug = sys.executable.endswith('_d.exe')108 elif sysconfig.get_config_var('Py_ENABLE_SHARED'):109 # To further add to the shared builds fun on Unix, we can't just add110 # library_dirs to the Extension() instance because that doesn't get111 # plumbed through to the final compiler command.112 runshared = sysconfig.get_config_var('RUNSHARED')113 if runshared is None:114 cmd.library_dirs = ['.']115 else:116 if sys.platform == 'darwin':117 cmd.library_dirs = []118 else:119 name, equals, value = runshared.partition('=')120 cmd.library_dirs = [d for d in value.split(os.pathsep) if d]121 122 123def combine_markers(cls):124 """125 pytest will honor markers as found on the class, but when126 markers are on multiple subclasses, only one appears. Use127 this decorator to combine those markers.128 """129 cls.pytestmark = [130 mark131 for base in itertools.chain([cls], cls.__bases__)132 for mark in getattr(base, 'pytestmark', [])133 ]134 return cls135 