Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test.py251 linesDownload Raw Back to command
1import os2import operator3import sys4import contextlib5import itertools6import unittest7from distutils.errors import DistutilsError, DistutilsOptionError8from distutils import log9from unittest import TestLoader10 11from pkg_resources import (12    resource_listdir,13    resource_exists,14    normalize_path,15    working_set,16    evaluate_marker,17    add_activation_listener,18    require,19)20from .._importlib import metadata21from setuptools import Command22from setuptools.extern.more_itertools import unique_everseen23from setuptools.extern.jaraco.functools import pass_none24 25 26class ScanningLoader(TestLoader):27    def __init__(self):28        TestLoader.__init__(self)29        self._visited = set()30 31    def loadTestsFromModule(self, module, pattern=None):32        """Return a suite of all tests cases contained in the given module33 34        If the module is a package, load tests from all the modules in it.35        If the module has an ``additional_tests`` function, call it and add36        the return value to the tests.37        """38        if module in self._visited:39            return None40        self._visited.add(module)41 42        tests = []43        tests.append(TestLoader.loadTestsFromModule(self, module))44 45        if hasattr(module, "additional_tests"):46            tests.append(module.additional_tests())47 48        if hasattr(module, '__path__'):49            for file in resource_listdir(module.__name__, ''):50                if file.endswith('.py') and file != '__init__.py':51                    submodule = module.__name__ + '.' + file[:-3]52                else:53                    if resource_exists(module.__name__, file + '/__init__.py'):54                        submodule = module.__name__ + '.' + file55                    else:56                        continue57                tests.append(self.loadTestsFromName(submodule))58 59        if len(tests) != 1:60            return self.suiteClass(tests)61        else:62            return tests[0]  # don't create a nested suite for only one return63 64 65# adapted from jaraco.classes.properties:NonDataProperty66class NonDataProperty:67    def __init__(self, fget):68        self.fget = fget69 70    def __get__(self, obj, objtype=None):71        if obj is None:72            return self73        return self.fget(obj)74 75 76class test(Command):77    """Command to run unit tests after in-place build"""78 79    description = "run unit tests after in-place build (deprecated)"80 81    user_options = [82        ('test-module=', 'm', "Run 'test_suite' in specified module"),83        (84            'test-suite=',85            's',86            "Run single test, case or suite (e.g. 'module.test_suite')",87        ),88        ('test-runner=', 'r', "Test runner to use"),89    ]90 91    def initialize_options(self):92        self.test_suite = None93        self.test_module = None94        self.test_loader = None95        self.test_runner = None96 97    def finalize_options(self):98        if self.test_suite and self.test_module:99            msg = "You may specify a module or a suite, but not both"100            raise DistutilsOptionError(msg)101 102        if self.test_suite is None:103            if self.test_module is None:104                self.test_suite = self.distribution.test_suite105            else:106                self.test_suite = self.test_module + ".test_suite"107 108        if self.test_loader is None:109            self.test_loader = getattr(self.distribution, 'test_loader', None)110        if self.test_loader is None:111            self.test_loader = "setuptools.command.test:ScanningLoader"112        if self.test_runner is None:113            self.test_runner = getattr(self.distribution, 'test_runner', None)114 115    @NonDataProperty116    def test_args(self):117        return list(self._test_args())118 119    def _test_args(self):120        if not self.test_suite:121            yield 'discover'122        if self.verbose:123            yield '--verbose'124        if self.test_suite:125            yield self.test_suite126 127    def with_project_on_sys_path(self, func):128        """129        Backward compatibility for project_on_sys_path context.130        """131        with self.project_on_sys_path():132            func()133 134    @contextlib.contextmanager135    def project_on_sys_path(self, include_dists=()):136        self.run_command('egg_info')137 138        # Build extensions in-place139        self.reinitialize_command('build_ext', inplace=1)140        self.run_command('build_ext')141 142        ei_cmd = self.get_finalized_command("egg_info")143 144        old_path = sys.path[:]145        old_modules = sys.modules.copy()146 147        try:148            project_path = normalize_path(ei_cmd.egg_base)149            sys.path.insert(0, project_path)150            working_set.__init__()151            add_activation_listener(lambda dist: dist.activate())152            require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))153            with self.paths_on_pythonpath([project_path]):154                yield155        finally:156            sys.path[:] = old_path157            sys.modules.clear()158            sys.modules.update(old_modules)159            working_set.__init__()160 161    @staticmethod162    @contextlib.contextmanager163    def paths_on_pythonpath(paths):164        """165        Add the indicated paths to the head of the PYTHONPATH environment166        variable so that subprocesses will also see the packages at167        these paths.168 169        Do this in a context that restores the value on exit.170        """171        nothing = object()172        orig_pythonpath = os.environ.get('PYTHONPATH', nothing)173        current_pythonpath = os.environ.get('PYTHONPATH', '')174        try:175            prefix = os.pathsep.join(unique_everseen(paths))176            to_join = filter(None, [prefix, current_pythonpath])177            new_path = os.pathsep.join(to_join)178            if new_path:179                os.environ['PYTHONPATH'] = new_path180            yield181        finally:182            if orig_pythonpath is nothing:183                os.environ.pop('PYTHONPATH', None)184            else:185                os.environ['PYTHONPATH'] = orig_pythonpath186 187    @staticmethod188    def install_dists(dist):189        """190        Install the requirements indicated by self.distribution and191        return an iterable of the dists that were built.192        """193        ir_d = dist.fetch_build_eggs(dist.install_requires)194        tr_d = dist.fetch_build_eggs(dist.tests_require or [])195        er_d = dist.fetch_build_eggs(196            v197            for k, v in dist.extras_require.items()198            if k.startswith(':') and evaluate_marker(k[1:])199        )200        return itertools.chain(ir_d, tr_d, er_d)201 202    def run(self):203        self.announce(204            "WARNING: Testing via this command is deprecated and will be "205            "removed in a future version. Users looking for a generic test "206            "entry point independent of test runner are encouraged to use "207            "tox.",208            log.WARN,209        )210 211        installed_dists = self.install_dists(self.distribution)212 213        cmd = ' '.join(self._argv)214        if self.dry_run:215            self.announce('skipping "%s" (dry run)' % cmd)216            return217 218        self.announce('running "%s"' % cmd)219 220        paths = map(operator.attrgetter('location'), installed_dists)221        with self.paths_on_pythonpath(paths):222            with self.project_on_sys_path():223                self.run_tests()224 225    def run_tests(self):226        test = unittest.main(227            None,228            None,229            self._argv,230            testLoader=self._resolve_as_ep(self.test_loader),231            testRunner=self._resolve_as_ep(self.test_runner),232            exit=False,233        )234        if not test.result.wasSuccessful():235            msg = 'Test failed: %s' % test.result236            self.announce(msg, log.ERROR)237            raise DistutilsError(msg)238 239    @property240    def _argv(self):241        return ['unittest'] + self.test_args242 243    @staticmethod244    @pass_none245    def _resolve_as_ep(val):246        """247        Load the indicated attribute value, called, as a as if it were248        specified as an entry point.249        """250        return metadata.EntryPoint(value=val, name=None, group=None).load()()251 
codekingpro/portable-devtools · Team Ai