From 7d66cde95cdf32b70d457064f5be0b2c5f02ce62 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 4 Jul 2024 20:45:49 -0400 Subject: [PATCH 1/6] Move paths_on_pythonpath out of the command.test module. --- setuptools/_path.py | 30 ++++++++++++++++++++++++++ setuptools/command/test.py | 33 +++-------------------------- setuptools/tests/test_develop.py | 9 ++++---- setuptools/tests/test_namespaces.py | 13 ++++++------ 4 files changed, 44 insertions(+), 41 deletions(-) diff --git a/setuptools/_path.py b/setuptools/_path.py index fb8ef0e198..7ce6919136 100644 --- a/setuptools/_path.py +++ b/setuptools/_path.py @@ -1,7 +1,11 @@ +import contextlib import os import sys from typing import Union +from setuptools.extern.more_itertools import unique_everseen + + if sys.version_info >= (3, 9): StrPath = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath else: @@ -38,3 +42,29 @@ def normpath(filename: StrPath) -> str: # See pkg_resources.normalize_path for notes about cygwin file = os.path.abspath(filename) if sys.platform == 'cygwin' else filename return os.path.normcase(os.path.realpath(os.path.normpath(file))) + + +@contextlib.contextmanager +def paths_on_pythonpath(paths): + """ + Add the indicated paths to the head of the PYTHONPATH environment + variable so that subprocesses will also see the packages at + these paths. + + Do this in a context that restores the value on exit. + """ + nothing = object() + orig_pythonpath = os.environ.get('PYTHONPATH', nothing) + current_pythonpath = os.environ.get('PYTHONPATH', '') + try: + prefix = os.pathsep.join(unique_everseen(paths)) + to_join = filter(None, [prefix, current_pythonpath]) + new_path = os.pathsep.join(to_join) + if new_path: + os.environ['PYTHONPATH'] = new_path + yield + finally: + if orig_pythonpath is nothing: + os.environ.pop('PYTHONPATH', None) + else: + os.environ['PYTHONPATH'] = orig_pythonpath diff --git a/setuptools/command/test.py b/setuptools/command/test.py index af1349e1c6..1ef69c47fd 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -1,4 +1,3 @@ -import os import operator import sys import contextlib @@ -18,8 +17,8 @@ require, ) from .._importlib import metadata +from .._path import paths_on_pythonpath from setuptools import Command -from setuptools.extern.more_itertools import unique_everseen from setuptools.extern.jaraco.functools import pass_none @@ -150,7 +149,7 @@ def project_on_sys_path(self, include_dists=()): working_set.__init__() add_activation_listener(lambda dist: dist.activate()) require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version)) - with self.paths_on_pythonpath([project_path]): + with paths_on_pythonpath([project_path]): yield finally: sys.path[:] = old_path @@ -158,32 +157,6 @@ def project_on_sys_path(self, include_dists=()): sys.modules.update(old_modules) working_set.__init__() - @staticmethod - @contextlib.contextmanager - def paths_on_pythonpath(paths): - """ - Add the indicated paths to the head of the PYTHONPATH environment - variable so that subprocesses will also see the packages at - these paths. - - Do this in a context that restores the value on exit. - """ - nothing = object() - orig_pythonpath = os.environ.get('PYTHONPATH', nothing) - current_pythonpath = os.environ.get('PYTHONPATH', '') - try: - prefix = os.pathsep.join(unique_everseen(paths)) - to_join = filter(None, [prefix, current_pythonpath]) - new_path = os.pathsep.join(to_join) - if new_path: - os.environ['PYTHONPATH'] = new_path - yield - finally: - if orig_pythonpath is nothing: - os.environ.pop('PYTHONPATH', None) - else: - os.environ['PYTHONPATH'] = orig_pythonpath - @staticmethod def install_dists(dist): """ @@ -218,7 +191,7 @@ def run(self): self.announce('running "%s"' % cmd) paths = map(operator.attrgetter('location'), installed_dists) - with self.paths_on_pythonpath(paths): + with paths_on_pythonpath(paths): with self.project_on_sys_path(): self.run_tests() diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index d36447edbb..6f17beb703 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -6,12 +6,11 @@ import pathlib import platform -from setuptools.command import test - import pytest from setuptools.command.develop import develop from setuptools.dist import Distribution +from setuptools._path import paths_on_pythonpath from . import contexts from . import namespaces @@ -124,7 +123,7 @@ def install_develop(src_dir, target): str(target), ] with src_dir.as_cwd(): - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(develop_cmd) @pytest.mark.skipif( @@ -163,7 +162,7 @@ def test_namespace_package_importable(self, tmpdir): '-c', 'import myns.pkgA; import myns.pkgB', ] - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(try_import) # additionally ensure that pkg_resources import works @@ -172,5 +171,5 @@ def test_namespace_package_importable(self, tmpdir): '-c', 'import pkg_resources', ] - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(pkg_resources_imp) diff --git a/setuptools/tests/test_namespaces.py b/setuptools/tests/test_namespaces.py index 76b5af296a..56689301da 100644 --- a/setuptools/tests/test_namespaces.py +++ b/setuptools/tests/test_namespaces.py @@ -1,8 +1,9 @@ import sys import subprocess +from setuptools._path import paths_on_pythonpath + from . import namespaces -from setuptools.command import test class TestNamespaces: @@ -45,7 +46,7 @@ def test_mixed_site_and_non_site(self, tmpdir): '-c', 'import myns.pkgA; import myns.pkgB', ] - with test.test.paths_on_pythonpath(map(str, targets)): + with paths_on_pythonpath(map(str, targets)): subprocess.check_call(try_import) def test_pkg_resources_import(self, tmpdir): @@ -65,7 +66,7 @@ def test_pkg_resources_import(self, tmpdir): str(target), str(pkg), ] - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(install_cmd) namespaces.make_site_dir(target) try_import = [ @@ -73,7 +74,7 @@ def test_pkg_resources_import(self, tmpdir): '-c', 'import pkg_resources', ] - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(try_import) def test_namespace_package_installed_and_cwd(self, tmpdir): @@ -102,7 +103,7 @@ def test_namespace_package_installed_and_cwd(self, tmpdir): '-c', 'import pkg_resources; import myns.pkgA', ] - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(pkg_resources_imp, cwd=str(pkg_A)) def test_packages_in_the_same_namespace_installed_and_cwd(self, tmpdir): @@ -133,5 +134,5 @@ def test_packages_in_the_same_namespace_installed_and_cwd(self, tmpdir): '-c', 'import pkg_resources; import myns.pkgA; import myns.pkgB', ] - with test.test.paths_on_pythonpath([str(target)]): + with paths_on_pythonpath([str(target)]): subprocess.check_call(pkg_resources_imp, cwd=str(pkg_B)) From b5bd38edc1cec78b6c1baca047aebf23c6635a48 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 4 Jul 2024 20:46:04 -0400 Subject: [PATCH 2/6] Remove test module and associated tests. --- pyproject.toml | 1 - setuptools/command/test.py | 223 ---------------------------- setuptools/tests/test_egg_info.py | 11 -- setuptools/tests/test_setuptools.py | 37 ----- setuptools/tests/test_test.py | 39 ----- setuptools/tests/test_virtualenv.py | 74 --------- 6 files changed, 385 deletions(-) delete mode 100644 setuptools/command/test.py delete mode 100644 setuptools/tests/test_test.py diff --git a/pyproject.toml b/pyproject.toml index 00e7ee169f..f5441ddf0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -118,7 +118,6 @@ rotate = "setuptools.command.rotate:rotate" saveopts = "setuptools.command.saveopts:saveopts" sdist = "setuptools.command.sdist:sdist" setopt = "setuptools.command.setopt:setopt" -test = "setuptools.command.test:test" upload_docs = "setuptools.command.upload_docs:upload_docs" [project.entry-points."setuptools.finalize_distribution_options"] diff --git a/setuptools/command/test.py b/setuptools/command/test.py deleted file mode 100644 index 1ef69c47fd..0000000000 --- a/setuptools/command/test.py +++ /dev/null @@ -1,223 +0,0 @@ -import operator -import sys -import contextlib -import itertools -import unittest -from distutils.errors import DistutilsError, DistutilsOptionError -from distutils import log -from unittest import TestLoader - -from pkg_resources import ( - resource_listdir, - resource_exists, - normalize_path, - working_set, - evaluate_marker, - add_activation_listener, - require, -) -from .._importlib import metadata -from .._path import paths_on_pythonpath -from setuptools import Command -from setuptools.extern.jaraco.functools import pass_none - - -class ScanningLoader(TestLoader): - def __init__(self): - TestLoader.__init__(self) - self._visited = set() - - def loadTestsFromModule(self, module, pattern=None): - """Return a suite of all tests cases contained in the given module - - If the module is a package, load tests from all the modules in it. - If the module has an ``additional_tests`` function, call it and add - the return value to the tests. - """ - if module in self._visited: - return None - self._visited.add(module) - - tests = [] - tests.append(TestLoader.loadTestsFromModule(self, module)) - - if hasattr(module, "additional_tests"): - tests.append(module.additional_tests()) - - if hasattr(module, '__path__'): - for file in resource_listdir(module.__name__, ''): - if file.endswith('.py') and file != '__init__.py': - submodule = module.__name__ + '.' + file[:-3] - else: - if resource_exists(module.__name__, file + '/__init__.py'): - submodule = module.__name__ + '.' + file - else: - continue - tests.append(self.loadTestsFromName(submodule)) - - if len(tests) != 1: - return self.suiteClass(tests) - else: - return tests[0] # don't create a nested suite for only one return - - -# adapted from jaraco.classes.properties:NonDataProperty -class NonDataProperty: - def __init__(self, fget): - self.fget = fget - - def __get__(self, obj, objtype=None): - if obj is None: - return self - return self.fget(obj) - - -class test(Command): - """Command to run unit tests after in-place build""" - - description = "run unit tests after in-place build (deprecated)" - - user_options = [ - ('test-module=', 'm', "Run 'test_suite' in specified module"), - ( - 'test-suite=', - 's', - "Run single test, case or suite (e.g. 'module.test_suite')", - ), - ('test-runner=', 'r', "Test runner to use"), - ] - - def initialize_options(self): - self.test_suite = None - self.test_module = None - self.test_loader = None - self.test_runner = None - - def finalize_options(self): - if self.test_suite and self.test_module: - msg = "You may specify a module or a suite, but not both" - raise DistutilsOptionError(msg) - - if self.test_suite is None: - if self.test_module is None: - self.test_suite = self.distribution.test_suite - else: - self.test_suite = self.test_module + ".test_suite" - - if self.test_loader is None: - self.test_loader = getattr(self.distribution, 'test_loader', None) - if self.test_loader is None: - self.test_loader = "setuptools.command.test:ScanningLoader" - if self.test_runner is None: - self.test_runner = getattr(self.distribution, 'test_runner', None) - - @NonDataProperty - def test_args(self): - return list(self._test_args()) - - def _test_args(self): - if not self.test_suite: - yield 'discover' - if self.verbose: - yield '--verbose' - if self.test_suite: - yield self.test_suite - - def with_project_on_sys_path(self, func): - """ - Backward compatibility for project_on_sys_path context. - """ - with self.project_on_sys_path(): - func() - - @contextlib.contextmanager - def project_on_sys_path(self, include_dists=()): - self.run_command('egg_info') - - # Build extensions in-place - self.reinitialize_command('build_ext', inplace=True) - self.run_command('build_ext') - - ei_cmd = self.get_finalized_command("egg_info") - - old_path = sys.path[:] - old_modules = sys.modules.copy() - - try: - project_path = normalize_path(ei_cmd.egg_base) - sys.path.insert(0, project_path) - working_set.__init__() - add_activation_listener(lambda dist: dist.activate()) - require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version)) - with paths_on_pythonpath([project_path]): - yield - finally: - sys.path[:] = old_path - sys.modules.clear() - sys.modules.update(old_modules) - working_set.__init__() - - @staticmethod - def install_dists(dist): - """ - Install the requirements indicated by self.distribution and - return an iterable of the dists that were built. - """ - ir_d = dist.fetch_build_eggs(dist.install_requires) - tr_d = dist.fetch_build_eggs(dist.tests_require or []) - er_d = dist.fetch_build_eggs( - v - for k, v in dist.extras_require.items() - if k.startswith(':') and evaluate_marker(k[1:]) - ) - return itertools.chain(ir_d, tr_d, er_d) - - def run(self): - self.announce( - "WARNING: Testing via this command is deprecated and will be " - "removed in a future version. Users looking for a generic test " - "entry point independent of test runner are encouraged to use " - "tox.", - log.WARN, - ) - - installed_dists = self.install_dists(self.distribution) - - cmd = ' '.join(self._argv) - if self.dry_run: - self.announce('skipping "%s" (dry run)' % cmd) - return - - self.announce('running "%s"' % cmd) - - paths = map(operator.attrgetter('location'), installed_dists) - with paths_on_pythonpath(paths): - with self.project_on_sys_path(): - self.run_tests() - - def run_tests(self): - test = unittest.main( - None, - None, - self._argv, - testLoader=self._resolve_as_ep(self.test_loader), - testRunner=self._resolve_as_ep(self.test_runner), - exit=False, - ) - if not test.result.wasSuccessful(): - msg = 'Test failed: %s' % test.result - self.announce(msg, log.ERROR) - raise DistutilsError(msg) - - @property - def _argv(self): - return ['unittest'] + self.test_args - - @staticmethod - @pass_none - def _resolve_as_ep(val): - """ - Load the indicated attribute value, called, as a as if it were - specified as an entry point. - """ - return metadata.EntryPoint(value=val, name=None, group=None).load()() diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 8616f813c1..856dd127bc 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -395,17 +395,6 @@ def parametrize(*test_list, **format_dict): setup_requires = barbazquux; {mismatch_marker} - """, - """ - tests_require_with_markers - {'cmd': ['test'], 'output': "Ran 0 tests in"} - - tests_require=["barbazquux;{mismatch_marker}"], - - [options] - tests_require = - barbazquux; {mismatch_marker} - """, """ extras_require_with_extra diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py index b1ca2396bd..3aa9bf048e 100644 --- a/setuptools/tests/test_setuptools.py +++ b/setuptools/tests/test_setuptools.py @@ -221,43 +221,6 @@ def testInvalidIncludeExclude(self): self.dist.exclude(package_dir=['q']) -class TestCommandTests: - def testTestIsCommand(self): - test_cmd = makeSetup().get_command_obj('test') - assert isinstance(test_cmd, distutils.cmd.Command) - - def testLongOptSuiteWNoDefault(self): - ts1 = makeSetup(script_args=['test', '--test-suite=foo.tests.suite']) - ts1 = ts1.get_command_obj('test') - ts1.ensure_finalized() - assert ts1.test_suite == 'foo.tests.suite' - - def testDefaultSuite(self): - ts2 = makeSetup(test_suite='bar.tests.suite').get_command_obj('test') - ts2.ensure_finalized() - assert ts2.test_suite == 'bar.tests.suite' - - def testDefaultWModuleOnCmdLine(self): - ts3 = makeSetup( - test_suite='bar.tests', script_args=['test', '-m', 'foo.tests'] - ).get_command_obj('test') - ts3.ensure_finalized() - assert ts3.test_module == 'foo.tests' - assert ts3.test_suite == 'foo.tests.test_suite' - - def testConflictingOptions(self): - ts4 = makeSetup( - script_args=['test', '-m', 'bar.tests', '-s', 'foo.tests.suite'] - ).get_command_obj('test') - with pytest.raises(DistutilsOptionError): - ts4.ensure_finalized() - - def testNoSuite(self): - ts5 = makeSetup().get_command_obj('test') - ts5.ensure_finalized() - assert ts5.test_suite is None - - @pytest.fixture def example_source(tmpdir): tmpdir.mkdir('foo') diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py deleted file mode 100644 index 989996f3ba..0000000000 --- a/setuptools/tests/test_test.py +++ /dev/null @@ -1,39 +0,0 @@ -import pytest -from jaraco import path - -from setuptools.command.test import test -from setuptools.dist import Distribution - -from .textwrap import DALS - - -@pytest.mark.usefixtures('tmpdir_cwd') -def test_tests_are_run_once(capfd): - params = dict( - packages=['dummy'], - ) - files = { - 'setup.py': 'from setuptools import setup; setup(' - + ','.join(f'{name}={params[name]!r}' for name in params) - + ')', - 'dummy': { - '__init__.py': '', - 'test_dummy.py': DALS( - """ - import unittest - class TestTest(unittest.TestCase): - def test_test(self): - print('Foo') - """ - ), - }, - } - path.build(files) - dist = Distribution(params) - dist.script_name = 'setup.py' - cmd = test(dist) - cmd.ensure_finalized() - cmd.run() - out, err = capfd.readouterr() - assert out.endswith('Foo\n') - assert len(out.split('Foo')) == 2 diff --git a/setuptools/tests/test_virtualenv.py b/setuptools/tests/test_virtualenv.py index b84702aa70..21e5273529 100644 --- a/setuptools/tests/test_virtualenv.py +++ b/setuptools/tests/test_virtualenv.py @@ -111,80 +111,6 @@ def test_pip_upgrade_from_source( venv.run(["pip", "install", "--no-cache-dir", "--upgrade", str(setuptools_sdist)]) -def _check_test_command_install_requirements(venv, tmpdir): - """ - Check the test command will install all required dependencies. - """ - - def sdist(distname, version): - dist_path = tmpdir.join('%s-%s.tar.gz' % (distname, version)) - make_nspkg_sdist(str(dist_path), distname, version) - return dist_path - - dependency_links = [ - pathlib.Path(str(dist_path)).as_uri() - for dist_path in ( - sdist('foobar', '2.4'), - sdist('bits', '4.2'), - sdist('bobs', '6.0'), - sdist('pieces', '0.6'), - ) - ] - with tmpdir.join('setup.py').open('w') as fp: - fp.write( - DALS( - ''' - from setuptools import setup - - setup( - dependency_links={dependency_links!r}, - install_requires=[ - 'barbazquux1; sys_platform in ""', - 'foobar==2.4', - ], - setup_requires='bits==4.2', - tests_require=""" - bobs==6.0 - """, - extras_require={{ - 'test': ['barbazquux2'], - ':"" in sys_platform': 'pieces==0.6', - ':python_version > "1"': """ - pieces - foobar - """, - }} - ) - '''.format(dependency_links=dependency_links) - ) - ) - with tmpdir.join('test.py').open('w') as fp: - fp.write( - DALS( - """ - import foobar - import bits - import bobs - import pieces - - open('success', 'w').close() - """ - ) - ) - - cmd = ["python", 'setup.py', 'test', '-s', 'test'] - venv.run(cmd, cwd=str(tmpdir)) - assert tmpdir.join('success').check() - - -def test_test_command_install_requirements(venv, tmpdir, tmpdir_cwd): - # Ensure pip is installed. - venv.run(["python", "-c", "import pip"]) - # disable index URL so bits and bobs aren't requested from PyPI - with contexts.environment(PYTHONPATH=None, PIP_NO_INDEX="1"): - _check_test_command_install_requirements(venv, tmpdir) - - def test_no_missing_dependencies(bare_venv, request): """ Quick and dirty test to ensure all external dependencies are vendored. From 67a0a043e8f5fa3bd201cc36697bd1ad66747264 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 5 Jul 2024 08:39:04 -0400 Subject: [PATCH 3/6] Add some doctests to paths_on_pythonpath, giving it full test coverage. --- setuptools/_path.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/setuptools/_path.py b/setuptools/_path.py index 7ce6919136..7a521ed705 100644 --- a/setuptools/_path.py +++ b/setuptools/_path.py @@ -52,6 +52,18 @@ def paths_on_pythonpath(paths): these paths. Do this in a context that restores the value on exit. + + >>> getfixture('monkeypatch').setenv('PYTHONPATH', 'anything') + >>> with paths_on_pythonpath(['foo', 'bar']): + ... assert 'foo' in os.environ['PYTHONPATH'] + ... assert 'anything' in os.environ['PYTHONPATH'] + >>> os.environ['PYTHONPATH'] + 'anything' + + >>> getfixture('monkeypatch').delenv('PYTHONPATH') + >>> with paths_on_pythonpath(['foo', 'bar']): + ... assert 'foo' in os.environ['PYTHONPATH'] + >>> os.environ.get('PYTHONPATH') """ nothing = object() orig_pythonpath = os.environ.get('PYTHONPATH', nothing) From 6929cc4b127bbef49006c30a02beedaed47be42b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 5 Jul 2024 08:47:00 -0400 Subject: [PATCH 4/6] Add news fragment. --- newsfragments/931.removal.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/931.removal.rst diff --git a/newsfragments/931.removal.rst b/newsfragments/931.removal.rst new file mode 100644 index 0000000000..cffc7456d5 --- /dev/null +++ b/newsfragments/931.removal.rst @@ -0,0 +1 @@ +The test command has been removed. Users relying on 'setup.py test' will need to migrate to another test runner or pin setuptools before this version. \ No newline at end of file From 6404823b4a16f340b7786793cd1256fe451f47eb Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 5 Jul 2024 08:58:44 -0400 Subject: [PATCH 5/6] Removed support for tests_require and other test command parameters. --- pyproject.toml | 4 ---- setuptools/config/setupcfg.py | 1 - setuptools/dist.py | 11 ---------- setuptools/tests/config/setupcfg_examples.txt | 1 - .../tests/config/test_apply_pyprojecttoml.py | 21 ------------------- setuptools/tests/config/test_setupcfg.py | 6 ------ setuptools/tests/test_bdist_wheel.py | 1 - 7 files changed, 45 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f5441ddf0a..9f3c41127b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -129,19 +129,15 @@ eager_resources = "setuptools.dist:assert_string_list" namespace_packages = "setuptools.dist:check_nsp" extras_require = "setuptools.dist:check_extras" install_requires = "setuptools.dist:check_requirements" -tests_require = "setuptools.dist:check_requirements" setup_requires = "setuptools.dist:check_requirements" python_requires = "setuptools.dist:check_specifier" entry_points = "setuptools.dist:check_entry_points" -test_suite = "setuptools.dist:check_test_suite" zip_safe = "setuptools.dist:assert_bool" package_data = "setuptools.dist:check_package_data" exclude_package_data = "setuptools.dist:check_package_data" include_package_data = "setuptools.dist:assert_bool" packages = "setuptools.dist:check_packages" dependency_links = "setuptools.dist:assert_string_list" -test_loader = "setuptools.dist:check_importable" -test_runner = "setuptools.dist:check_importable" use_2to3 = "setuptools.dist:invalid_unless_false" [project.entry-points."egg_info.writers"] diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index 80ebe3d9bd..7dbcbe60ec 100644 --- a/setuptools/config/setupcfg.py +++ b/setuptools/config/setupcfg.py @@ -646,7 +646,6 @@ def parsers(self): self._parse_requirements_list, "install_requires" ), 'setup_requires': self._parse_list_semicolon, - 'tests_require': self._parse_list_semicolon, 'packages': self._parse_packages, 'entry_points': self._parse_file_in_root, 'py_modules': parse_list, diff --git a/setuptools/dist.py b/setuptools/dist.py index 32e8d43c64..a93c26deb5 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -170,11 +170,6 @@ def check_entry_points(dist, attr, value): raise DistutilsSetupError(e) from e -def check_test_suite(dist, attr, value): - if not isinstance(value, str): - raise DistutilsSetupError("test_suite must be a string") - - def check_package_data(dist, attr, value): """Verify that value is a dictionary of package names to glob lists""" if not isinstance(value, dict): @@ -235,12 +230,6 @@ class Distribution(_Distribution): EasyInstall and requests one of your extras, the corresponding additional requirements will be installed if needed. - 'test_suite' -- the name of a test suite to run for the 'test' command. - If the user runs 'python setup.py test', the package will be installed, - and the named test suite will be run. The format is the same as - would be used on a 'unittest.py' command line. That is, it is the - dotted name of an object to import and call to generate a test suite. - 'package_data' -- a dictionary mapping package names to lists of filenames or globs to use to find data files contained in the named packages. If the dictionary has filenames or globs listed under '""' (the empty diff --git a/setuptools/tests/config/setupcfg_examples.txt b/setuptools/tests/config/setupcfg_examples.txt index 5db3565464..6aab887ff1 100644 --- a/setuptools/tests/config/setupcfg_examples.txt +++ b/setuptools/tests/config/setupcfg_examples.txt @@ -15,7 +15,6 @@ https://github.com/pallets/click/raw/6411f425fae545f42795665af4162006b36c5e4a/se https://github.com/sqlalchemy/sqlalchemy/raw/533f5718904b620be8d63f2474229945d6f8ba5d/setup.cfg https://github.com/pytest-dev/pluggy/raw/461ef63291d13589c4e21aa182cd1529257e9a0a/setup.cfg https://github.com/pytest-dev/pytest/raw/c7be96dae487edbd2f55b561b31b68afac1dabe6/setup.cfg -https://github.com/tqdm/tqdm/raw/fc69d5dcf578f7c7986fa76841a6b793f813df35/setup.cfg https://github.com/platformdirs/platformdirs/raw/7b7852128dd6f07511b618d6edea35046bd0c6ff/setup.cfg https://github.com/pandas-dev/pandas/raw/bc17343f934a33dc231c8c74be95d8365537c376/setup.cfg https://github.com/django/django/raw/4e249d11a6e56ca8feb4b055b681cec457ef3a3d/setup.cfg diff --git a/setuptools/tests/config/test_apply_pyprojecttoml.py b/setuptools/tests/config/test_apply_pyprojecttoml.py index 6b3ee9cf1e..68da71fd99 100644 --- a/setuptools/tests/config/test_apply_pyprojecttoml.py +++ b/setuptools/tests/config/test_apply_pyprojecttoml.py @@ -51,7 +51,6 @@ def test_apply_pyproject_equivalent_to_setupcfg(url, monkeypatch, tmp_path): dist_toml = pyprojecttoml.apply_configuration(makedist(tmp_path), pyproject_example) dist_cfg = setupcfg.apply_configuration(makedist(tmp_path), setupcfg_example) - _port_tests_require(dist_cfg) pkg_info_toml = core_metadata(dist_toml) pkg_info_cfg = core_metadata(dist_cfg) @@ -84,12 +83,6 @@ def test_apply_pyproject_equivalent_to_setupcfg(url, monkeypatch, tmp_path): assert set(dist_toml.install_requires) == set(dist_cfg.install_requires) if any(getattr(d, "extras_require", None) for d in (dist_toml, dist_cfg)): - if ( - "testing" in dist_toml.extras_require - and "testing" not in dist_cfg.extras_require - ): - # ini2toml can automatically convert `tests_require` to `testing` extra - dist_toml.extras_require.pop("testing") extra_req_toml = {(k, *sorted(v)) for k, v in dist_toml.extras_require.items()} extra_req_cfg = {(k, *sorted(v)) for k, v in dist_cfg.extras_require.items()} assert extra_req_toml == extra_req_cfg @@ -467,8 +460,6 @@ def core_metadata(dist) -> str: skip_prefixes += ("Project-URL: Homepage,", "Home-page:") # May be missing in original (relying on default) but backfilled in the TOML skip_prefixes += ("Description-Content-Type:",) - # ini2toml can automatically convert `tests_require` to `testing` extra - skip_lines.add("Provides-Extra: testing") # Remove empty lines skip_lines.add("") @@ -479,15 +470,3 @@ def core_metadata(dist) -> str: result.append(line + "\n") return "".join(result) - - -def _port_tests_require(dist): - """ - ``ini2toml`` "forward fix" deprecated tests_require definitions by moving - them into an extra called ``testing``. - """ - tests_require = getattr(dist, "tests_require", None) or [] - if tests_require: - dist.tests_require = [] - dist.extras_require.setdefault("testing", []).extend(tests_require) - dist._finalize_requires() diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index bf9777c668..502b6eb5dc 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -465,7 +465,6 @@ def test_basic(self, tmpdir): 'scripts = bin/one.py, bin/two.py\n' 'eager_resources = bin/one.py, bin/two.py\n' 'install_requires = docutils>=0.3; pack ==1.1, ==1.3; hey\n' - 'tests_require = mock==0.7.2; pytest\n' 'setup_requires = docutils>=0.3; spack ==1.1, ==1.3; there\n' 'dependency_links = http://some.com/here/1, ' 'http://some.com/there/2\n' @@ -494,7 +493,6 @@ def test_basic(self, tmpdir): 'spack ==1.1, ==1.3', 'there', ]) - assert dist.tests_require == ['mock==0.7.2', 'pytest'] assert dist.python_requires == '>=1.0, !=2.8' assert dist.py_modules == ['module1', 'module2'] @@ -521,9 +519,6 @@ def test_multiline(self, tmpdir): ' docutils>=0.3\n' ' pack ==1.1, ==1.3\n' ' hey\n' - 'tests_require = \n' - ' mock==0.7.2\n' - ' pytest\n' 'setup_requires = \n' ' docutils>=0.3\n' ' spack ==1.1, ==1.3\n' @@ -552,7 +547,6 @@ def test_multiline(self, tmpdir): 'spack ==1.1, ==1.3', 'there', ]) - assert dist.tests_require == ['mock==0.7.2', 'pytest'] def test_package_dir_fail(self, tmpdir): fake_env(tmpdir, '[options]\npackage_dir = a b\n') diff --git a/setuptools/tests/test_bdist_wheel.py b/setuptools/tests/test_bdist_wheel.py index 232b66d368..46fcff548e 100644 --- a/setuptools/tests/test_bdist_wheel.py +++ b/setuptools/tests/test_bdist_wheel.py @@ -98,7 +98,6 @@ setup_requires=["setuptools"], install_requires=["quux", "splort"], extras_require={"simple": ["simple.dist"]}, - tests_require=["foo", "bar>=10.0.0"], entry_points={ "console_scripts": [ "complex-dist=complexdist:main", From 63c89f93d6d43ff96ce5f7f5a862395f924905d0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 21 Jul 2024 12:17:34 -0400 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20(d?= =?UTF-8?q?elint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setuptools/tests/test_setuptools.py | 1 - setuptools/tests/test_virtualenv.py | 5 ----- 2 files changed, 6 deletions(-) diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py index 073d14507f..9865ee847c 100644 --- a/setuptools/tests/test_setuptools.py +++ b/setuptools/tests/test_setuptools.py @@ -5,7 +5,6 @@ import os import distutils.core import distutils.cmd -from distutils.errors import DistutilsOptionError from distutils.errors import DistutilsSetupError from distutils.core import Extension from zipfile import ZipFile diff --git a/setuptools/tests/test_virtualenv.py b/setuptools/tests/test_virtualenv.py index 21e5273529..4554581ed0 100644 --- a/setuptools/tests/test_virtualenv.py +++ b/setuptools/tests/test_virtualenv.py @@ -4,14 +4,9 @@ from urllib.request import urlopen from urllib.error import URLError -import pathlib import pytest -from . import contexts -from .textwrap import DALS -from .test_easy_install import make_nspkg_sdist - @pytest.fixture(autouse=True) def pytest_virtualenv_works(venv):