diff options
| author | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-07-04 13:34:58 +0100 |
|---|---|---|
| committer | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-07-04 13:34:58 +0100 |
| commit | 618f4ef94730b0d1756271a12b5ff7ea9f2beb16 (patch) | |
| tree | cf8206194cc3c426dd4e403269d477f32d0fd675 /setuptools | |
| parent | 233c986f690a1f1bef222dd6f7fad803c4f41a6d (diff) | |
| parent | 03b06eef123cbbf22e21d1e7cb06a9c7503313bb (diff) | |
| download | python-setuptools-git-618f4ef94730b0d1756271a12b5ff7ea9f2beb16.tar.gz | |
Merge 'upstream/main' into feature/pep660
Diffstat (limited to 'setuptools')
20 files changed, 202 insertions, 286 deletions
diff --git a/setuptools/_distutils/command/_framework_compat.py b/setuptools/_distutils/command/_framework_compat.py new file mode 100644 index 00000000..e032603a --- /dev/null +++ b/setuptools/_distutils/command/_framework_compat.py @@ -0,0 +1,52 @@ +""" +Backward compatibility for homebrew builds on macOS. +""" + + +import sys +import os +import functools +import subprocess + + +@functools.lru_cache() +def enabled(): + """ + Only enabled for Python 3.9 framework builds except ensurepip and venv. + """ + PY39 = (3, 9) < sys.version_info < (3, 10) + framework = sys.platform == 'darwin' and sys._framework + venv = sys.prefix != sys.base_prefix + ensurepip = os.environ.get("ENSUREPIP_OPTIONS") + return PY39 and framework and not venv and not ensurepip + + +schemes = dict( + osx_framework_library=dict( + stdlib='{installed_base}/{platlibdir}/python{py_version_short}', + platstdlib='{platbase}/{platlibdir}/python{py_version_short}', + purelib='{homebrew_prefix}/lib/python{py_version_short}/site-packages', + platlib='{homebrew_prefix}/{platlibdir}/python{py_version_short}/site-packages', + include='{installed_base}/include/python{py_version_short}{abiflags}', + platinclude='{installed_platbase}/include/python{py_version_short}{abiflags}', + scripts='{homebrew_prefix}/bin', + data='{homebrew_prefix}', + ) +) + + +@functools.lru_cache() +def vars(): + if not enabled(): + return {} + homebrew_prefix = subprocess.check_output(['brew', '--prefix'], text=True).strip() + return locals() + + +def scheme(name): + """ + Override the selected scheme for posix_prefix. + """ + if not enabled() or not name.endswith('_prefix'): + return name + return 'osx_framework_library' diff --git a/setuptools/_distutils/command/build_py.py b/setuptools/_distutils/command/build_py.py index 1b22004e..7723d359 100644 --- a/setuptools/_distutils/command/build_py.py +++ b/setuptools/_distutils/command/build_py.py @@ -201,16 +201,11 @@ class build_py(Command): "but is not a directory" % package_dir ) - # Require __init__.py for all but the "root package" + # Directories without __init__.py are namespace packages (PEP 420). if package: init_py = os.path.join(package_dir, "__init__.py") if os.path.isfile(init_py): return init_py - else: - log.warn( - ("package init file '%s' not found " + "(or not a regular file)"), - init_py, - ) # Either not in a package at all (__init__.py not expected), or # __init__.py doesn't exist -- so don't return the filename. diff --git a/setuptools/_distutils/command/install.py b/setuptools/_distutils/command/install.py index 0660406f..7d9054e3 100644 --- a/setuptools/_distutils/command/install.py +++ b/setuptools/_distutils/command/install.py @@ -17,6 +17,7 @@ from distutils.file_util import write_file from distutils.util import convert_path, subst_vars, change_root from distutils.util import get_platform from distutils.errors import DistutilsOptionError +from . import _framework_compat as fw from .. import _collections from site import USER_BASE @@ -82,6 +83,10 @@ if HAS_USER_SITE: 'data': '{userbase}', } + +INSTALL_SCHEMES.update(fw.schemes) + + # The keys to an installation scheme; if any new types of files are to be # installed, be sure to add an entry to every installation scheme above, # and to SCHEME_KEYS here. @@ -136,7 +141,7 @@ def _resolve_scheme(name): try: resolved = sysconfig.get_preferred_scheme(key) except Exception: - resolved = _pypy_hack(name) + resolved = fw.scheme(_pypy_hack(name)) return resolved @@ -426,7 +431,7 @@ class install(Command): local_vars['usersite'] = self.install_usersite self.config_vars = _collections.DictStack( - [compat_vars, sysconfig.get_config_vars(), local_vars] + [fw.vars(), compat_vars, sysconfig.get_config_vars(), local_vars] ) self.expand_basedirs() diff --git a/setuptools/_distutils/cygwinccompiler.py b/setuptools/_distutils/cygwinccompiler.py index 931b3661..445e2e51 100644 --- a/setuptools/_distutils/cygwinccompiler.py +++ b/setuptools/_distutils/cygwinccompiler.py @@ -58,6 +58,7 @@ from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import ( DistutilsExecError, + DistutilsPlatformError, CCompilerError, CompileError, UnknownFileError, @@ -197,6 +198,12 @@ class CygwinCCompiler(UnixCCompiler): libraries = copy.copy(libraries or []) objects = copy.copy(objects or []) + if runtime_library_dirs: + self.warn( + "I don't know what to do with 'runtime_library_dirs': " + + str(runtime_library_dirs) + ) + # Additional libraries libraries.extend(self.dll_libraries) @@ -265,6 +272,13 @@ class CygwinCCompiler(UnixCCompiler): target_lang, ) + def runtime_library_dir_option(self, dir): + # cygwin doesn't support rpath. While in theory we could error + # out like MSVC does, code might expect it to work like on Unix, so + # just warn and hope for the best. + self.warn("don't know how to set runtime library search path on Windows") + return [] + # -- Miscellaneous methods ----------------------------------------- def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): @@ -325,6 +339,11 @@ class Mingw32CCompiler(CygwinCCompiler): # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() + def runtime_library_dir_option(self, dir): + raise DistutilsPlatformError( + "don't know how to set runtime library search path on Windows" + ) + # Because these compilers aren't configured in Python's pyconfig.h file by # default, we should at least warn the user if he is using an unmodified diff --git a/setuptools/_distutils/tests/test_build_py.py b/setuptools/_distutils/tests/test_build_py.py index 4585d799..eb01d81a 100644 --- a/setuptools/_distutils/tests/test_build_py.py +++ b/setuptools/_distutils/tests/test_build_py.py @@ -7,6 +7,7 @@ import unittest from distutils.command.build_py import build_py from distutils.core import Distribution from distutils.errors import DistutilsFileError +from unittest.mock import patch from distutils.tests import support from test.support import run_unittest @@ -167,6 +168,47 @@ class BuildPyTestCase( self.assertIn('byte-compiling is disabled', self.logs[0][1] % self.logs[0][2]) + @patch("distutils.command.build_py.log.warn") + def test_namespace_package_does_not_warn(self, log_warn): + """ + Originally distutils implementation did not account for PEP 420 + and included warns for package directories that did not contain + ``__init__.py`` files. + After the acceptance of PEP 420, these warnings don't make more sense + so we want to ensure there are not displayed to not confuse the users. + """ + # Create a fake project structure with a package namespace: + tmp = self.mkdtemp() + os.chdir(tmp) + os.makedirs("ns/pkg") + open("ns/pkg/module.py", "w").close() + + # Set up a trap if the undesirable effect is observed: + def _trap(msg, *args): + if "package init file" in msg and "not found" in msg: + raise AssertionError(f"Undesired warning: {msg!r} {args!r}") + + log_warn.side_effect = _trap + + # Configure the package: + attrs = { + "name": "ns.pkg", + "packages": ["ns", "ns.pkg"], + "script_name": "setup.py", + } + dist = Distribution(attrs) + + # Run code paths that would trigger the trap: + cmd = dist.get_command_obj("build_py") + cmd.finalize_options() + modules = cmd.find_all_modules() + assert len(modules) == 1 + module_path = modules[0][-1] + assert module_path.replace(os.sep, "/") == "ns/pkg/module.py" + + cmd.run() + # Test should complete successfully with no exception + def test_suite(): return unittest.TestLoader().loadTestsFromTestCase(BuildPyTestCase) diff --git a/setuptools/_distutils/tests/test_cygwinccompiler.py b/setuptools/_distutils/tests/test_cygwinccompiler.py index b3c164ed..7760436a 100644 --- a/setuptools/_distutils/tests/test_cygwinccompiler.py +++ b/setuptools/_distutils/tests/test_cygwinccompiler.py @@ -48,6 +48,12 @@ class CygwinCCompilerTestCase(support.TempdirManager, unittest.TestCase): self.assertTrue(os.path.exists(linkable_file)) self.assertEquals(linkable_file, "/usr/lib/lib{:s}.dll.a".format(link_name)) + @unittest.skipIf(sys.platform != "cygwin", "Not running on Cygwin") + def test_runtime_library_dir_option(self): + from distutils.cygwinccompiler import CygwinCCompiler + compiler = CygwinCCompiler() + self.assertEqual(compiler.runtime_library_dir_option('/foo'), []) + def test_check_config_h(self): # check_config_h looks for "GCC" in sys.version first diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/INSTALLER b/setuptools/_vendor/nspektr-0.3.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/LICENSE b/setuptools/_vendor/nspektr-0.3.0.dist-info/LICENSE deleted file mode 100644 index 353924be..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright Jason R. Coombs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/METADATA b/setuptools/_vendor/nspektr-0.3.0.dist-info/METADATA deleted file mode 100644 index aadc3749..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/METADATA +++ /dev/null @@ -1,57 +0,0 @@ -Metadata-Version: 2.1 -Name: nspektr -Version: 0.3.0 -Summary: package inspector -Home-page: https://github.com/jaraco/nspektr -Author: Jason R. Coombs -Author-email: jaraco@jaraco.com -License: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Requires-Python: >=3.7 -License-File: LICENSE -Requires-Dist: jaraco.context -Requires-Dist: jaraco.functools -Requires-Dist: more-itertools -Requires-Dist: packaging -Requires-Dist: importlib-metadata (>=3.6) ; python_version < "3.10" -Provides-Extra: docs -Requires-Dist: sphinx ; extra == 'docs' -Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs' -Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' -Provides-Extra: testing -Requires-Dist: pytest (>=6) ; extra == 'testing' -Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing' -Requires-Dist: pytest-flake8 ; extra == 'testing' -Requires-Dist: pytest-cov ; extra == 'testing' -Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing' -Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing' -Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing' - -.. image:: https://img.shields.io/pypi/v/nspektr.svg - :target: `PyPI link`_ - -.. image:: https://img.shields.io/pypi/pyversions/nspektr.svg - :target: `PyPI link`_ - -.. _PyPI link: https://pypi.org/project/nspektr - -.. image:: https://github.com/jaraco/nspektr/workflows/tests/badge.svg - :target: https://github.com/jaraco/nspektr/actions?query=workflow%3A%22tests%22 - :alt: tests - -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black - :alt: Code style: Black - -.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest -.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest - -.. image:: https://img.shields.io/badge/skeleton-2022-informational - :target: https://blog.jaraco.com/skeleton - - diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/RECORD b/setuptools/_vendor/nspektr-0.3.0.dist-info/RECORD deleted file mode 100644 index 5e5de5eb..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/RECORD +++ /dev/null @@ -1,11 +0,0 @@ -nspektr-0.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-nspektr-0.3.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050
-nspektr-0.3.0.dist-info/METADATA,sha256=X0stV4vwFBDBxvzhBl4kAHVdGWPIjEitqAuTJItcQH0,2162
-nspektr-0.3.0.dist-info/RECORD,,
-nspektr-0.3.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-nspektr-0.3.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
-nspektr-0.3.0.dist-info/top_level.txt,sha256=uEA20Ixo04XS3wOIt5-Jk5ZuMkBrtlleFipRr8Y1SjQ,8
-nspektr/__init__.py,sha256=d6-d-ZlGAQQP-MEi_NZMiyn2vLbq8Hw3HxICgm3X0Q8,3949
-nspektr/__pycache__/__init__.cpython-310.pyc,,
-nspektr/__pycache__/_compat.cpython-310.pyc,,
-nspektr/_compat.py,sha256=2QoozYhuhgow_NMUATmhoM-yppBV3jiZYQgdiP-ww0s,582
diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/REQUESTED b/setuptools/_vendor/nspektr-0.3.0.dist-info/REQUESTED deleted file mode 100644 index e69de29b..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/REQUESTED +++ /dev/null diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/WHEEL b/setuptools/_vendor/nspektr-0.3.0.dist-info/WHEEL deleted file mode 100644 index becc9a66..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.37.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/setuptools/_vendor/nspektr-0.3.0.dist-info/top_level.txt b/setuptools/_vendor/nspektr-0.3.0.dist-info/top_level.txt deleted file mode 100644 index b10ef50a..00000000 --- a/setuptools/_vendor/nspektr-0.3.0.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -nspektr diff --git a/setuptools/_vendor/nspektr/__init__.py b/setuptools/_vendor/nspektr/__init__.py deleted file mode 100644 index 938bbdb9..00000000 --- a/setuptools/_vendor/nspektr/__init__.py +++ /dev/null @@ -1,145 +0,0 @@ -import itertools -import functools -import contextlib - -from setuptools.extern.packaging.requirements import Requirement -from setuptools.extern.packaging.version import Version -from setuptools.extern.more_itertools import always_iterable -from setuptools.extern.jaraco.context import suppress -from setuptools.extern.jaraco.functools import apply - -from ._compat import metadata, repair_extras - - -def resolve(req: Requirement) -> metadata.Distribution: - """ - Resolve the requirement to its distribution. - - Ignore exception detail for Python 3.9 compatibility. - - >>> resolve(Requirement('pytest<3')) # doctest: +IGNORE_EXCEPTION_DETAIL - Traceback (most recent call last): - ... - importlib.metadata.PackageNotFoundError: No package metadata was found for pytest<3 - """ - dist = metadata.distribution(req.name) - if not req.specifier.contains(Version(dist.version), prereleases=True): - raise metadata.PackageNotFoundError(str(req)) - dist.extras = req.extras # type: ignore - return dist - - -@apply(bool) -@suppress(metadata.PackageNotFoundError) -def is_satisfied(req: Requirement): - return resolve(req) - - -unsatisfied = functools.partial(itertools.filterfalse, is_satisfied) - - -class NullMarker: - @classmethod - def wrap(cls, req: Requirement): - return req.marker or cls() - - def evaluate(self, *args, **kwargs): - return True - - -def find_direct_dependencies(dist, extras=None): - """ - Find direct, declared dependencies for dist. - """ - simple = ( - req - for req in map(Requirement, always_iterable(dist.requires)) - if NullMarker.wrap(req).evaluate(dict(extra=None)) - ) - extra_deps = ( - req - for req in map(Requirement, always_iterable(dist.requires)) - for extra in always_iterable(getattr(dist, 'extras', extras)) - if NullMarker.wrap(req).evaluate(dict(extra=extra)) - ) - return itertools.chain(simple, extra_deps) - - -def traverse(items, visit): - """ - Given an iterable of items, traverse the items. - - For each item, visit is called to return any additional items - to include in the traversal. - """ - while True: - try: - item = next(items) - except StopIteration: - return - yield item - items = itertools.chain(items, visit(item)) - - -def find_req_dependencies(req): - with contextlib.suppress(metadata.PackageNotFoundError): - dist = resolve(req) - yield from find_direct_dependencies(dist) - - -def find_dependencies(dist, extras=None): - """ - Find all reachable dependencies for dist. - - dist is an importlib.metadata.Distribution (or similar). - TODO: create a suitable protocol for type hint. - - >>> deps = find_dependencies(resolve(Requirement('nspektr'))) - >>> all(isinstance(dep, Requirement) for dep in deps) - True - >>> not any('pytest' in str(dep) for dep in deps) - True - >>> test_deps = find_dependencies(resolve(Requirement('nspektr[testing]'))) - >>> any('pytest' in str(dep) for dep in test_deps) - True - """ - - def visit(req, seen=set()): - if req in seen: - return () - seen.add(req) - return find_req_dependencies(req) - - return traverse(find_direct_dependencies(dist, extras), visit) - - -class Unresolved(Exception): - def __iter__(self): - return iter(self.args[0]) - - -def missing(ep): - """ - Generate the unresolved dependencies (if any) of ep. - """ - return unsatisfied(find_dependencies(ep.dist, repair_extras(ep.extras))) - - -def check(ep): - """ - >>> ep, = metadata.entry_points(group='console_scripts', name='pip') - >>> check(ep) - >>> dist = metadata.distribution('nspektr') - - Since 'docs' extras are not installed, requesting them should fail. - - >>> ep = metadata.EntryPoint( - ... group=None, name=None, value='nspektr [docs]')._for(dist) - >>> check(ep) - Traceback (most recent call last): - ... - nspektr.Unresolved: [...] - """ - missed = list(missing(ep)) - if missed: - raise Unresolved(missed) diff --git a/setuptools/_vendor/nspektr/_compat.py b/setuptools/_vendor/nspektr/_compat.py deleted file mode 100644 index 3278379a..00000000 --- a/setuptools/_vendor/nspektr/_compat.py +++ /dev/null @@ -1,21 +0,0 @@ -import contextlib -import sys - - -if sys.version_info >= (3, 10): - import importlib.metadata as metadata -else: - import setuptools.extern.importlib_metadata as metadata # type: ignore # noqa: F401 - - -def repair_extras(extras): - """ - Repair extras that appear as match objects. - - python/importlib_metadata#369 revealed a flaw in the EntryPoint - implementation. This function wraps the extras to ensure - they are proper strings even on older implementations. - """ - with contextlib.suppress(AttributeError): - return list(item.group(0) for item in extras) - return extras diff --git a/setuptools/_vendor/vendored.txt b/setuptools/_vendor/vendored.txt index 95de2dc5..84c4006c 100644 --- a/setuptools/_vendor/vendored.txt +++ b/setuptools/_vendor/vendored.txt @@ -5,7 +5,6 @@ more_itertools==8.8.0 jaraco.text==3.7.0 importlib_resources==5.4.0 importlib_metadata==4.11.1 -nspektr==0.3.0 # required for importlib_metadata on older Pythons typing_extensions==4.0.1 # required for importlib_resources and _metadata on older Pythons diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 0c9d45ae..25888ed8 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -297,7 +297,6 @@ class egg_info(InfoCommon, Command): self.mkpath(self.egg_info) os.utime(self.egg_info, None) for ep in metadata.entry_points(group='egg_info.writers'): - self.distribution._install_dependencies(ep) writer = ep.load() writer(self, ep.name, os.path.join(self.egg_info, ep.name)) diff --git a/setuptools/dist.py b/setuptools/dist.py index c1ad3008..82423548 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -30,7 +30,6 @@ from distutils.util import rfc822_escape from setuptools.extern import packaging from setuptools.extern import ordered_set from setuptools.extern.more_itertools import unique_everseen, partition -from setuptools.extern import nspektr from ._importlib import metadata @@ -918,18 +917,8 @@ class Distribution(_Distribution): for ep in metadata.entry_points(group='distutils.setup_keywords'): value = getattr(self, ep.name, None) if value is not None: - self._install_dependencies(ep) ep.load()(self, ep.name, value) - def _install_dependencies(self, ep): - """ - Given an entry point, ensure that any declared extras for - its distribution are installed. - """ - for req in nspektr.missing(ep): - # fetch_build_egg expects pkg_resources.Requirement - self.fetch_build_egg(pkg_resources.Requirement(str(req))) - def get_egg_cache_dir(self): egg_cache_dir = os.path.join(os.curdir, '.eggs') if not os.path.exists(egg_cache_dir): @@ -962,7 +951,6 @@ class Distribution(_Distribution): eps = metadata.entry_points(group='distutils.commands', name=command) for ep in eps: - self._install_dependencies(ep) self.cmdclass[command] = cmdclass = ep.load() return cmdclass else: diff --git a/setuptools/extern/__init__.py b/setuptools/extern/__init__.py index 192e55f6..d3a6dc99 100644 --- a/setuptools/extern/__init__.py +++ b/setuptools/extern/__init__.py @@ -71,6 +71,6 @@ class VendorImporter: names = ( 'packaging', 'pyparsing', 'ordered_set', 'more_itertools', 'importlib_metadata', - 'zipp', 'importlib_resources', 'jaraco', 'typing_extensions', 'nspektr', 'tomli', + 'zipp', 'importlib_resources', 'jaraco', 'typing_extensions', 'tomli', ) VendorImporter(__name__, names, 'setuptools._vendor').install() diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 246d634f..d102e586 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -846,9 +846,11 @@ class TestSetupRequires: def test_setup_requires_with_transitive_extra_dependency( self, monkeypatch): - # Use case: installing a package with a build dependency on - # an already installed `dep[extra]`, which in turn depends - # on `extra_dep` (whose is not already installed). + ''' + Use case: installing a package with a build dependency on + an already installed `dep[extra]`, which in turn depends + on `extra_dep` (whose is not already installed). + ''' with contexts.save_pkg_resources_state(): with contexts.tempdir() as temp_dir: # Create source distribution for `extra_dep`. @@ -890,6 +892,75 @@ class TestSetupRequires: monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) run_setup(test_setup_py, [str('--version')]) + def test_setup_requires_with_distutils_command_dep(self, monkeypatch): + ''' + Use case: ensure build requirements' extras + are properly installed and activated. + ''' + with contexts.save_pkg_resources_state(): + with contexts.tempdir() as temp_dir: + # Create source distribution for `extra_dep`. + make_sdist(os.path.join(temp_dir, 'extra_dep-1.0.tar.gz'), [ + ('setup.py', + DALS(""" + import setuptools + setuptools.setup( + name='extra_dep', + version='1.0', + py_modules=['extra_dep'], + ) + """)), + ('setup.cfg', ''), + ('extra_dep.py', ''), + ]) + # Create source tree for `epdep`. + dep_pkg = os.path.join(temp_dir, 'epdep') + os.mkdir(dep_pkg) + path.build({ + 'setup.py': + DALS(""" + import setuptools + setuptools.setup( + name='dep', version='2.0', + py_modules=['epcmd'], + extras_require={'extra': ['extra_dep']}, + entry_points=''' + [distutils.commands] + epcmd = epcmd:epcmd [extra] + ''', + ) + """), + 'setup.cfg': '', + 'epcmd.py': DALS(""" + from distutils.command.build_py import build_py + + import extra_dep + + class epcmd(build_py): + pass + """), + }, prefix=dep_pkg) + # "Install" dep. + run_setup( + os.path.join(dep_pkg, 'setup.py'), [str('dist_info')]) + working_set.add_entry(dep_pkg) + # Create source tree for test package. + test_pkg = os.path.join(temp_dir, 'test_pkg') + test_setup_py = os.path.join(test_pkg, 'setup.py') + os.mkdir(test_pkg) + with open(test_setup_py, 'w') as fp: + fp.write(DALS( + ''' + from setuptools import installer, setup + setup(setup_requires='dep[extra]') + ''')) + # Check... + monkeypatch.setenv(str('PIP_FIND_LINKS'), str(temp_dir)) + monkeypatch.setenv(str('PIP_NO_INDEX'), str('1')) + monkeypatch.setenv(str('PIP_RETRIES'), str('0')) + monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + run_setup(test_setup_py, ['epcmd']) + def make_trivial_sdist(dist_path, distname, version): """ |
