diff options
| author | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2023-02-13 20:32:19 +0000 |
|---|---|---|
| committer | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2023-02-13 20:32:19 +0000 |
| commit | 52c605573716db3100543be728addf1bce965802 (patch) | |
| tree | b35e3eb73a3dcb07a6249a576d5a95c53f214d8f /setuptools/command | |
| parent | bc5f3c306d328a6d3a54fa4172dc62b5d5dddc80 (diff) | |
| parent | 51bf7563d1513ec3a2edbbcf00a533f85cf26d66 (diff) | |
| download | python-setuptools-git-52c605573716db3100543be728addf1bce965802.tar.gz | |
Reduce usage of pkg_resources (#3792)
Diffstat (limited to 'setuptools/command')
| -rw-r--r-- | setuptools/command/bdist_egg.py | 15 | ||||
| -rw-r--r-- | setuptools/command/develop.py | 17 | ||||
| -rw-r--r-- | setuptools/command/dist_info.py | 40 | ||||
| -rw-r--r-- | setuptools/command/editable_wheel.py | 43 | ||||
| -rw-r--r-- | setuptools/command/egg_info.py | 37 | ||||
| -rw-r--r-- | setuptools/command/install_egg_info.py | 5 | ||||
| -rw-r--r-- | setuptools/command/install_scripts.py | 9 |
7 files changed, 70 insertions, 96 deletions
diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 11a1c6be..33f483cf 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -11,7 +11,6 @@ import re import textwrap import marshal -from pkg_resources import get_build_platform, Distribution from setuptools.extension import Library from setuptools import Command from .._path import ensure_directory @@ -64,7 +63,7 @@ class bdist_egg(Command): ('bdist-dir=', 'b', "temporary directory for creating the distribution"), ('plat-name=', 'p', "platform name to embed in generated filenames " - "(default: %s)" % get_build_platform()), + "(by default uses `pkg_resources.get_build_platform()`)"), ('exclude-source-files', None, "remove all .py files from the generated egg"), ('keep-temp', 'k', @@ -98,18 +97,18 @@ class bdist_egg(Command): self.bdist_dir = os.path.join(bdist_base, 'egg') if self.plat_name is None: + from pkg_resources import get_build_platform + self.plat_name = get_build_platform() self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) if self.egg_output is None: - # Compute filename of the output egg - basename = Distribution( - None, None, ei_cmd.egg_name, ei_cmd.egg_version, - get_python_version(), - self.distribution.has_ext_modules() and self.plat_name - ).egg_name() + basename = ei_cmd._get_egg_basename( + py_version=get_python_version(), + platform=self.distribution.has_ext_modules() and self.plat_name, + ) self.egg_output = os.path.join(self.dist_dir, basename + '.egg') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 24fb0a7c..5630ca4c 100644 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -5,8 +5,8 @@ import os import glob import io -import pkg_resources from setuptools.command.easy_install import easy_install +from setuptools import _path from setuptools import namespaces import setuptools @@ -42,6 +42,8 @@ class develop(namespaces.DevelopInstaller, easy_install): self.always_copy_from = '.' # always copy eggs installed in curdir def finalize_options(self): + import pkg_resources + ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: template = "Please rename %r to %r before using 'develop'" @@ -61,10 +63,8 @@ class develop(namespaces.DevelopInstaller, easy_install): if self.egg_path is None: self.egg_path = os.path.abspath(ei.egg_base) - target = pkg_resources.normalize_path(self.egg_base) - egg_path = pkg_resources.normalize_path( - os.path.join(self.install_dir, self.egg_path) - ) + target = _path.normpath(self.egg_base) + egg_path = _path.normpath(os.path.join(self.install_dir, self.egg_path)) if egg_path != target: raise DistutilsOptionError( "--egg-path must be a relative path from the install" @@ -94,15 +94,16 @@ class develop(namespaces.DevelopInstaller, easy_install): path_to_setup = egg_base.replace(os.sep, '/').rstrip('/') if path_to_setup != os.curdir: path_to_setup = '../' * (path_to_setup.count('/') + 1) - resolved = pkg_resources.normalize_path( + resolved = _path.normpath( os.path.join(install_dir, egg_path, path_to_setup) ) - if resolved != pkg_resources.normalize_path(os.curdir): + curdir = _path.normpath(os.curdir) + if resolved != curdir: raise DistutilsOptionError( "Can't get a consistent path to setup script from" " installation directory", resolved, - pkg_resources.normalize_path(os.curdir), + curdir, ) return path_to_setup diff --git a/setuptools/command/dist_info.py b/setuptools/command/dist_info.py index 4966d852..545e9995 100644 --- a/setuptools/command/dist_info.py +++ b/setuptools/command/dist_info.py @@ -4,18 +4,16 @@ As defined in the wheel specification """ import os -import re import shutil import sys import warnings from contextlib import contextmanager -from inspect import cleandoc +from distutils import log +from distutils.core import Command from pathlib import Path -from distutils.core import Command -from distutils import log -from setuptools.extern import packaging -from setuptools._deprecation_warning import SetuptoolsDeprecationWarning +from .. import _normalization +from .._deprecation_warning import SetuptoolsDeprecationWarning class dist_info(Command): @@ -76,8 +74,8 @@ class dist_info(Command): egg_info.finalize_options() self.egg_info = egg_info - name = _safe(dist.get_name()) - version = _version(dist.get_version()) + name = _normalization.safer_name(dist.get_name()) + version = _normalization.safer_best_effort_version(dist.get_version()) self.name = f"{name}-{version}" self.dist_info_dir = os.path.join(self.output_dir, f"{self.name}.dist-info") @@ -109,32 +107,6 @@ class dist_info(Command): bdist_wheel.egg2dist(egg_info_dir, self.dist_info_dir) -def _safe(component: str) -> str: - """Escape a component used to form a wheel name according to PEP 491""" - return re.sub(r"[^\w\d.]+", "_", component) - - -def _version(version: str) -> str: - """Convert an arbitrary string to a version string.""" - v = version.replace(' ', '.') - try: - return str(packaging.version.Version(v)).replace("-", "_") - except packaging.version.InvalidVersion: - msg = f"""Invalid version: {version!r}. - !!\n\n - ################### - # Invalid version # - ################### - {version!r} is not valid according to PEP 440.\n - Please make sure specify a valid version for your package. - Also note that future releases of setuptools may halt the build process - if an invalid version is given. - \n\n!! - """ - warnings.warn(cleandoc(msg)) - return _safe(v).strip("_") - - def _rm(dir_name, **opts): if os.path.isdir(dir_name): shutil.rmtree(dir_name, **opts) diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 083ef185..5e532a7f 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -12,7 +12,6 @@ Create a wheel that, when installed, will make the source package 'editable' import logging import os -import re import shutil import sys import traceback @@ -36,10 +35,17 @@ from typing import ( Union, ) -from setuptools import Command, SetuptoolsDeprecationWarning, errors, namespaces -from setuptools.command.build_py import build_py as build_py_cls -from setuptools.discovery import find_package_path -from setuptools.dist import Distribution +from .. import ( + Command, + SetuptoolsDeprecationWarning, + _normalization, + _path, + errors, + namespaces, +) +from ..discovery import find_package_path +from ..dist import Distribution +from .build_py import build_py as build_py_cls if TYPE_CHECKING: from wheel.wheelfile import WheelFile # noqa @@ -482,7 +488,7 @@ class _TopLevelFinder: )) name = f"__editable__.{self.name}.finder" - finder = _make_identifier(name) + finder = _normalization.safe_identifier(name) content = bytes(_finder_template(name, roots, namespaces_), "utf-8") wheel.writestr(f"{finder}.py", content) @@ -561,7 +567,7 @@ def _simple_layout( return set(package_dir) in ({}, {""}) parent = os.path.commonpath([_parent_path(k, v) for k, v in layout.items()]) return all( - _normalize_path(Path(parent, *key.split('.'))) == _normalize_path(value) + _path.same_path(Path(parent, *key.split('.')), value) for key, value in layout.items() ) @@ -690,21 +696,14 @@ def _is_nested(pkg: str, pkg_path: str, parent: str, parent_path: str) -> bool: >>> _is_nested("b.a", "path/b/a", "a", "path/a") False """ - norm_pkg_path = _normalize_path(pkg_path) + norm_pkg_path = _path.normpath(pkg_path) rest = pkg.replace(parent, "", 1).strip(".").split(".") return ( pkg.startswith(parent) - and norm_pkg_path == _normalize_path(Path(parent_path, *rest)) + and norm_pkg_path == _path.normpath(Path(parent_path, *rest)) ) -def _normalize_path(filename: _Path) -> str: - """Normalize a file/dir name for comparison purposes""" - # See pkg_resources.normalize_path - file = os.path.abspath(filename) if sys.platform == 'cygwin' else filename - return os.path.normcase(os.path.realpath(os.path.normpath(file))) - - def _empty_dir(dir_: _P) -> _P: """Create a directory ensured to be empty. Existing files may be removed.""" shutil.rmtree(dir_, ignore_errors=True) @@ -712,18 +711,6 @@ def _empty_dir(dir_: _P) -> _P: return dir_ -def _make_identifier(name: str) -> str: - """Make a string safe to be used as Python identifier. - >>> _make_identifier("12abc") - '_12abc' - >>> _make_identifier("__editable__.myns.pkg-78.9.3_local") - '__editable___myns_pkg_78_9_3_local' - """ - safe = re.sub(r'\W|^(?=\d)', '_', name) - assert safe.isidentifier() - return safe - - class _NamespaceInstaller(namespaces.Installer): def __init__(self, distribution, installation_dir, editable_name, src_root): self.distribution = distribution diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 86e99dd2..afcde5a2 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -18,16 +18,13 @@ import time import collections from .._importlib import metadata -from .. import _entry_points +from .. import _entry_points, _normalization from setuptools import Command from setuptools.command.sdist import sdist from setuptools.command.sdist import walk_revctrl from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg -from pkg_resources import ( - Requirement, safe_name, parse_version, - safe_version, to_filename) import setuptools.unicode_utils as unicode_utils from setuptools.glob import glob @@ -36,6 +33,9 @@ from setuptools.extern.jaraco.text import yield_lines from setuptools import SetuptoolsDeprecationWarning +PY_MAJOR = '{}.{}'.format(*sys.version_info) + + def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME """ Translate a file path glob like '*.txt' in to a regular expression. @@ -125,10 +125,11 @@ class InfoCommon: @property def name(self): - return safe_name(self.distribution.get_name()) + return _normalization.safe_name(self.distribution.get_name()) def tagged_version(self): - return safe_version(self._maybe_tag(self.distribution.get_version())) + tagged = self._maybe_tag(self.distribution.get_version()) + return _normalization.best_effort_version(tagged) def _maybe_tag(self, version): """ @@ -148,7 +149,7 @@ class InfoCommon: def _safe_tags(self) -> str: # To implement this we can rely on `safe_version` pretending to be version 0 # followed by tags. Then we simply discard the starting 0 (fake version number) - return safe_version(f"0{self.vtags}")[1:] + return _normalization.best_effort_version(f"0{self.vtags}")[1:] def tags(self) -> str: version = '' @@ -216,12 +217,12 @@ class egg_info(InfoCommon, Command): # repercussions. self.egg_name = self.name self.egg_version = self.tagged_version() - parsed_version = parse_version(self.egg_version) + parsed_version = packaging.version.Version(self.egg_version) try: is_version = isinstance(parsed_version, packaging.version.Version) spec = "%s==%s" if is_version else "%s===%s" - Requirement(spec % (self.egg_name, self.egg_version)) + packaging.requirements.Requirement(spec % (self.egg_name, self.egg_version)) except ValueError as e: raise distutils.errors.DistutilsOptionError( "Invalid distribution name or version syntax: %s-%s" % @@ -233,7 +234,7 @@ class egg_info(InfoCommon, Command): self.egg_base = (dirs or {}).get('', os.curdir) self.ensure_dirname('egg_base') - self.egg_info = to_filename(self.egg_name) + '.egg-info' + self.egg_info = _normalization.filename_component(self.egg_name) + '.egg-info' if self.egg_base != os.curdir: self.egg_info = os.path.join(self.egg_base, self.egg_info) if '-' in self.egg_name: @@ -251,9 +252,13 @@ class egg_info(InfoCommon, Command): pd = self.distribution._patched_dist if pd is not None and pd.key == self.egg_name.lower(): pd._version = self.egg_version - pd._parsed_version = parse_version(self.egg_version) + pd._parsed_version = packaging.version.Version(self.egg_version) self.distribution._patched_dist = None + def _get_egg_basename(self, py_version=PY_MAJOR, platform=None): + """Compute filename of the output egg. Private API.""" + return _egg_basename(self.egg_name, self.egg_version, py_version, platform) + def write_or_delete_file(self, what, filename, data, force=False): """Write `data` to `filename` or delete if empty @@ -771,5 +776,15 @@ def get_pkg_info_revision(): return 0 +def _egg_basename(egg_name, egg_version, py_version=None, platform=None): + """Compute filename of the output egg. Private API.""" + name = _normalization.filename_component(egg_name) + version = _normalization.filename_component(egg_version) + egg = f"{name}-{version}-py{py_version or PY_MAJOR}" + if platform: + egg += f"-{platform}" + return egg + + class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning): """Deprecated behavior warning for EggInfo, bypassing suppression.""" diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index 65ede406..1c549c98 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -5,7 +5,6 @@ from setuptools import Command from setuptools import namespaces from setuptools.archive_util import unpack_archive from .._path import ensure_directory -import pkg_resources class install_egg_info(namespaces.Installer, Command): @@ -24,9 +23,7 @@ class install_egg_info(namespaces.Installer, Command): self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) ei_cmd = self.get_finalized_command("egg_info") - basename = pkg_resources.Distribution( - None, None, ei_cmd.egg_name, ei_cmd.egg_version - ).egg_name() + '.egg-info' + basename = f"{ei_cmd._get_egg_basename()}.egg-info" self.source = ei_cmd.egg_info self.target = os.path.join(self.install_dir, basename) self.outputs = [] diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index aeb0e424..8b3133f1 100644 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -4,7 +4,6 @@ from distutils.errors import DistutilsModuleError import os import sys -from pkg_resources import Distribution, PathMetadata from .._path import ensure_directory @@ -16,8 +15,6 @@ class install_scripts(orig.install_scripts): self.no_ep = False def run(self): - import setuptools.command.easy_install as ei - self.run_command("egg_info") if self.distribution.scripts: orig.install_scripts.run(self) # run first to set up self.outfiles @@ -26,6 +23,12 @@ class install_scripts(orig.install_scripts): if self.no_ep: # don't install entry point scripts into .egg file! return + self._install_ep_scripts() + + def _install_ep_scripts(self): + # Delay import side-effects + from pkg_resources import Distribution, PathMetadata + from . import easy_install as ei ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( |
