summaryrefslogtreecommitdiff
path: root/setuptools
diff options
context:
space:
mode:
authorAnderson Bravalheri <andersonbravalheri@gmail.com>2022-07-04 13:34:58 +0100
committerAnderson Bravalheri <andersonbravalheri@gmail.com>2022-07-04 13:34:58 +0100
commit618f4ef94730b0d1756271a12b5ff7ea9f2beb16 (patch)
treecf8206194cc3c426dd4e403269d477f32d0fd675 /setuptools
parent233c986f690a1f1bef222dd6f7fad803c4f41a6d (diff)
parent03b06eef123cbbf22e21d1e7cb06a9c7503313bb (diff)
downloadpython-setuptools-git-618f4ef94730b0d1756271a12b5ff7ea9f2beb16.tar.gz
Merge 'upstream/main' into feature/pep660
Diffstat (limited to 'setuptools')
-rw-r--r--setuptools/_distutils/command/_framework_compat.py52
-rw-r--r--setuptools/_distutils/command/build_py.py7
-rw-r--r--setuptools/_distutils/command/install.py9
-rw-r--r--setuptools/_distutils/cygwinccompiler.py19
-rw-r--r--setuptools/_distutils/tests/test_build_py.py42
-rw-r--r--setuptools/_distutils/tests/test_cygwinccompiler.py6
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/INSTALLER1
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/LICENSE19
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/METADATA57
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/RECORD11
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/REQUESTED0
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/WHEEL5
-rw-r--r--setuptools/_vendor/nspektr-0.3.0.dist-info/top_level.txt1
-rw-r--r--setuptools/_vendor/nspektr/__init__.py145
-rw-r--r--setuptools/_vendor/nspektr/_compat.py21
-rw-r--r--setuptools/_vendor/vendored.txt1
-rw-r--r--setuptools/command/egg_info.py1
-rw-r--r--setuptools/dist.py12
-rw-r--r--setuptools/extern/__init__.py2
-rw-r--r--setuptools/tests/test_easy_install.py77
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):
"""