From 76c9ab9efc3f13e5ef8681614bebbe437bf51012 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 20 Dec 2021 11:50:50 -0500 Subject: In easy_install, re-use scheme selection from distutils if available. --- setuptools/command/easy_install.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index fc848d0d..00b59904 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -17,10 +17,10 @@ from distutils.errors import ( DistutilsArgError, DistutilsOptionError, DistutilsError, DistutilsPlatformError, ) -from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS from distutils import log, dir_util from distutils.command.build_scripts import first_line_re from distutils.spawn import find_executable +from distutils.command import install import sys import os import zipimport @@ -251,6 +251,9 @@ class easy_install(Command): 'exec_prefix': exec_prefix, # Only python 3.2+ has abiflags 'abiflags': getattr(sys, 'abiflags', ''), + 'platlibdir': getattr(sys, 'platlibdir', 'lib'), + 'implementation_lower': install._get_implementation().lower(), + 'implementation': install._get_implementation(), } if site.ENABLE_USER_SITE: @@ -711,13 +714,7 @@ class easy_install(Command): return dist def select_scheme(self, name): - """Sets the install directories by applying the install schemes.""" - # it's the caller's problem if they supply a bad name! - scheme = INSTALL_SCHEMES[name] - for key in SCHEME_KEYS: - attrname = 'install_' + key - if getattr(self, attrname) is None: - setattr(self, attrname, scheme[key]) + install._select_scheme(self, name) # FIXME: 'easy_install.process_distribution' is too complex (12) def process_distribution( # noqa: C901 -- cgit v1.2.1 From 60b78468341d52bc033f0ad77e890a656ccb9a72 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 20 Dec 2021 12:01:37 -0500 Subject: Add fallback support for distutils in stdlib. --- setuptools/command/easy_install.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 00b59904..e8150057 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -252,9 +252,13 @@ class easy_install(Command): # Only python 3.2+ has abiflags 'abiflags': getattr(sys, 'abiflags', ''), 'platlibdir': getattr(sys, 'platlibdir', 'lib'), - 'implementation_lower': install._get_implementation().lower(), - 'implementation': install._get_implementation(), } + with contextlib.suppress(AttributeError): + # only for distutils outside stdlib + self.config_vars.update({ + 'implementation_lower': install._get_implementation().lower(), + 'implementation': install._get_implementation(), + }) if site.ENABLE_USER_SITE: self.config_vars['userbase'] = self.install_userbase @@ -714,7 +718,11 @@ class easy_install(Command): return dist def select_scheme(self, name): - install._select_scheme(self, name) + try: + install._select_scheme(self, name) + except AttributeError: + # stdlib distutils + install.install.select_scheme(self, name) # FIXME: 'easy_install.process_distribution' is too complex (12) def process_distribution( # noqa: C901 -- cgit v1.2.1 From edf116b1cc4a72075b9af06748df3b177d55d4dc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 20 Dec 2021 16:43:07 -0500 Subject: Select 'posix_user' for the scheme unless falling back to stdlib, then use 'unix_user'. Fixes #2938. --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index e8150057..fb34d10e 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -378,7 +378,7 @@ class easy_install(Command): msg = "User base directory is not specified" raise DistutilsPlatformError(msg) self.install_base = self.install_platbase = self.install_userbase - scheme_name = os.name.replace('posix', 'unix') + '_user' + scheme_name = f'{os.name}_user' self.select_scheme(scheme_name) def _expand_attrs(self, attrs): @@ -722,7 +722,7 @@ class easy_install(Command): install._select_scheme(self, name) except AttributeError: # stdlib distutils - install.install.select_scheme(self, name) + install.install.select_scheme(self, name.replace('posix', 'unix')) # FIXME: 'easy_install.process_distribution' is too complex (12) def process_distribution( # noqa: C901 -- cgit v1.2.1 From b028d4636e6a9cb1737758f42f321340bf5abc25 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 3 Jan 2022 12:44:56 -0500 Subject: Use 'dict()' instead of '.copy()', for compatibility with DictStack. --- setuptools/command/easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index fb34d10e..aad5794a 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1350,7 +1350,7 @@ class easy_install(Command): if self.prefix: # Set default install_dir/scripts from --prefix - config_vars = config_vars.copy() + config_vars = dict(config_vars) config_vars['base'] = self.prefix scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME) for attr, val in scheme.items(): -- cgit v1.2.1 From a257f0cb1f960e1d37933c5009da39a49a4622bc Mon Sep 17 00:00:00 2001 From: liuzhe Date: Wed, 22 Dec 2021 13:48:04 +0800 Subject: fix version parsing --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index aad5794a..a2962a7d 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -243,8 +243,8 @@ class easy_install(Command): 'dist_version': self.distribution.get_version(), 'dist_fullname': self.distribution.get_fullname(), 'py_version': py_version, - 'py_version_short': py_version[0:3], - 'py_version_nodot': py_version[0] + py_version[2], + 'py_version_short': f'{sys.version_info.major}.{sys.version_info.minor}', + 'py_version_nodot': f'{sys.version_info.major}{sys.version_info.minor}', 'sys_prefix': prefix, 'prefix': prefix, 'sys_exec_prefix': exec_prefix, -- cgit v1.2.1 From b789d313eeb514e9ba469e10f81a333a8f7acc47 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 12 Jan 2022 09:51:18 -0500 Subject: Honor sysconfig variables in easy_install. Fixes #3026. --- setuptools/command/easy_install.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index a2962a7d..514719de 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -39,9 +39,10 @@ import subprocess import shlex import io import configparser +import sysconfig -from sysconfig import get_config_vars, get_path +from sysconfig import get_path from setuptools import SetuptoolsDeprecationWarning @@ -236,23 +237,22 @@ class easy_install(Command): self.version and self._render_version() py_version = sys.version.split()[0] - prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix') - self.config_vars = { + self.config_vars = dict(sysconfig.get_config_vars()) + + self.config_vars.update({ 'dist_name': self.distribution.get_name(), 'dist_version': self.distribution.get_version(), 'dist_fullname': self.distribution.get_fullname(), 'py_version': py_version, 'py_version_short': f'{sys.version_info.major}.{sys.version_info.minor}', 'py_version_nodot': f'{sys.version_info.major}{sys.version_info.minor}', - 'sys_prefix': prefix, - 'prefix': prefix, - 'sys_exec_prefix': exec_prefix, - 'exec_prefix': exec_prefix, + 'sys_prefix': self.config_vars['prefix'], + 'sys_exec_prefix': self.config_vars['exec_prefix'], # Only python 3.2+ has abiflags 'abiflags': getattr(sys, 'abiflags', ''), 'platlibdir': getattr(sys, 'platlibdir', 'lib'), - } + }) with contextlib.suppress(AttributeError): # only for distutils outside stdlib self.config_vars.update({ -- cgit v1.2.1 From a7c6d64f76091d1cfd8297ba813fe4e901d00ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=AD=E4=B9=9D=E9=BC=8E?= <109224573@qq.com> Date: Wed, 26 Jan 2022 16:58:29 +0800 Subject: Use super() --- setuptools/command/easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 514719de..5fab0fdb 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1577,7 +1577,7 @@ class PthDistributions(Environment): self.sitedirs = list(map(normalize_path, sitedirs)) self.basedir = normalize_path(os.path.dirname(self.filename)) self._load() - Environment.__init__(self, [], None, None) + super().__init__([], None, None) for path in yield_lines(self.paths): list(map(self.add, find_distributions(path, True))) -- cgit v1.2.1 From 44649c5a483a9c1cf2d80f6e9706d581cfc7437e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Jan 2022 15:25:09 -0500 Subject: Add py_version_nodot_plat substitution support to easy_install. --- setuptools/command/easy_install.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 5fab0fdb..e25090b8 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -260,6 +260,12 @@ class easy_install(Command): 'implementation': install._get_implementation(), }) + # pypa/distutils#113 Python 3.9 compat + self.config_vars.setdefault( + 'py_version_nodot_plat', + getattr(sys, 'windir', '').replace('.', ''), + ) + if site.ENABLE_USER_SITE: self.config_vars['userbase'] = self.install_userbase self.config_vars['usersite'] = self.install_usersite -- cgit v1.2.1 From ee8ed624ac46a7769fa16179ecca9b6aca8c02a6 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Tue, 1 Feb 2022 17:30:53 +0000 Subject: Skip non-string values from sysconfig.get_config_vars() --- setuptools/command/easy_install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index e25090b8..bdacbbfc 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1334,7 +1334,9 @@ class easy_install(Command): if not self.user: return home = convert_path(os.path.expanduser("~")) - for name, path in self.config_vars.items(): + for path in self.config_vars.values(): + if not isinstance(path, str): + continue if path.startswith(home) and not os.path.isdir(path): self.debug_print("os.makedirs('%s', 0o700)" % path) os.makedirs(path, 0o700) -- cgit v1.2.1 From a3bc3d44fb0ad669d75e674218078752de7bb24d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Feb 2022 20:13:22 -0500 Subject: Create a function for only_strs to help document its purpose. --- setuptools/command/easy_install.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index bdacbbfc..ef1a9b23 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1334,9 +1334,7 @@ class easy_install(Command): if not self.user: return home = convert_path(os.path.expanduser("~")) - for path in self.config_vars.values(): - if not isinstance(path, str): - continue + for path in only_strs(self.config_vars.values()): if path.startswith(home) and not os.path.isdir(path): self.debug_print("os.makedirs('%s', 0o700)" % path) os.makedirs(path, 0o700) @@ -2306,6 +2304,13 @@ def current_umask(): return tmp +def only_strs(values): + """ + Exclude non-str values. Ref #3063. + """ + return filter(lambda val: isinstance(val, str), values) + + class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning): """ Warning for EasyInstall deprecations, bypassing suppression. -- cgit v1.2.1 From 4cbbb99a953ac5b1fec3b1dfdd106a7781f4293d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Dec 2021 22:17:12 -0500 Subject: Move ensure_directory into setuptools. --- setuptools/command/bdist_egg.py | 3 ++- setuptools/command/easy_install.py | 3 ++- setuptools/command/install_egg_info.py | 3 ++- setuptools/command/install_scripts.py | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index e6b1609f..11a1c6be 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -11,9 +11,10 @@ import re import textwrap import marshal -from pkg_resources import get_build_platform, Distribution, ensure_directory +from pkg_resources import get_build_platform, Distribution from setuptools.extension import Library from setuptools import Command +from .._path import ensure_directory from sysconfig import get_path, get_python_version diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index ef1a9b23..b1260dcd 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -56,12 +56,13 @@ from setuptools.package_index import ( from setuptools.command import bdist_egg, egg_info from setuptools.wheel import Wheel from pkg_resources import ( - yield_lines, normalize_path, resource_string, ensure_directory, + yield_lines, normalize_path, resource_string, get_distribution, find_distributions, Environment, Requirement, Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, VersionConflict, DEVELOP_DIST, ) import pkg_resources +from .._path import ensure_directory # Turn on PEP440Warnings warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index edc4718b..65ede406 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -4,6 +4,7 @@ import os from setuptools import Command from setuptools import namespaces from setuptools.archive_util import unpack_archive +from .._path import ensure_directory import pkg_resources @@ -37,7 +38,7 @@ class install_egg_info(namespaces.Installer, Command): elif os.path.exists(self.target): self.execute(os.unlink, (self.target,), "Removing " + self.target) if not self.dry_run: - pkg_resources.ensure_directory(self.target) + ensure_directory(self.target) self.execute( self.copytree, (), "Copying %s to %s" % (self.source, self.target) ) diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 9cd8eb06..aeb0e424 100644 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -4,7 +4,8 @@ from distutils.errors import DistutilsModuleError import os import sys -from pkg_resources import Distribution, PathMetadata, ensure_directory +from pkg_resources import Distribution, PathMetadata +from .._path import ensure_directory class install_scripts(orig.install_scripts): -- cgit v1.2.1 From 157e36ed63408713f56e16f25c5f813e82bb7442 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 5 Feb 2022 09:55:05 -0500 Subject: Replace use of parse_requirements with simple constructor. --- setuptools/command/egg_info.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index f2210292..379f9398 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -23,7 +23,7 @@ from setuptools.command.sdist import walk_revctrl from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg from pkg_resources import ( - parse_requirements, safe_name, parse_version, + Requirement, safe_name, parse_version, safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) import setuptools.unicode_utils as unicode_utils from setuptools.glob import glob @@ -205,12 +205,8 @@ class egg_info(InfoCommon, Command): try: is_version = isinstance(parsed_version, packaging.version.Version) - spec = ( - "%s==%s" if is_version else "%s===%s" - ) - list( - parse_requirements(spec % (self.egg_name, self.egg_version)) - ) + spec = "%s==%s" if is_version else "%s===%s" + Requirement(spec % (self.egg_name, self.egg_version)) except ValueError as e: raise distutils.errors.DistutilsOptionError( "Invalid distribution name or version syntax: %s-%s" % -- cgit v1.2.1 From ff3447a694f3b08dae8bd5268e64aa43f05a47a9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 11:20:38 -0500 Subject: Migrate remainder of 'iter_entry_points' to importlib_metadata. --- setuptools/command/egg_info.py | 11 ++++++----- setuptools/command/sdist.py | 4 ++-- setuptools/command/upload_docs.py | 10 ++++++---- 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 379f9398..d0e73002 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -17,6 +17,8 @@ import warnings import time import collections +from .._importlib import metadata + from setuptools import Command from setuptools.command.sdist import sdist from setuptools.command.sdist import walk_revctrl @@ -24,7 +26,7 @@ from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg from pkg_resources import ( Requirement, safe_name, parse_version, - safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) + safe_version, yield_lines, EntryPoint, to_filename) import setuptools.unicode_utils as unicode_utils from setuptools.glob import glob @@ -281,10 +283,9 @@ class egg_info(InfoCommon, Command): def run(self): self.mkpath(self.egg_info) os.utime(self.egg_info, None) - installer = self.distribution.fetch_build_egg - for ep in iter_entry_points('egg_info.writers'): - ep.require(installer=installer) - writer = ep.resolve() + 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)) # Get rid of native_libs.txt if it was put there by older bdist_egg diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 0285b690..0ffeacf3 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -7,14 +7,14 @@ import contextlib from .py36compat import sdist_add_defaults -import pkg_resources +from .._importlib import metadata _default_revctrl = list def walk_revctrl(dirname=''): """Find all files under revision control""" - for ep in pkg_resources.iter_entry_points('setuptools.file_finders'): + for ep in metadata.entry_points(group='setuptools.file_finders'): for item in ep.load()(dirname): yield item diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index 845bff44..f429f568 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -18,7 +18,8 @@ import functools import http.client import urllib.parse -from pkg_resources import iter_entry_points +from .._importlib import metadata + from .upload import upload @@ -43,9 +44,10 @@ class upload_docs(upload): boolean_options = upload.boolean_options def has_sphinx(self): - if self.upload_dir is None: - for ep in iter_entry_points('distutils.commands', 'build_sphinx'): - return True + return bool( + self.upload_dir is None + and metadata.entry_points(group='distutils.commands', name='build_sphinx') + ) sub_commands = [('build_sphinx', has_sphinx)] -- cgit v1.2.1 From 867147f45c2b929f32b364284448b9d08c397dcb Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 11:28:02 -0500 Subject: Avoid dual-use variable. --- setuptools/command/egg_info.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index d0e73002..17955207 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -721,13 +721,13 @@ def write_entries(cmd, basename, filename): if isinstance(ep, str) or ep is None: data = ep elif ep is not None: - data = [] + lines = [] for section, contents in sorted(ep.items()): if not isinstance(contents, str): contents = EntryPoint.parse_group(section, contents) contents = '\n'.join(sorted(map(str, contents.values()))) - data.append('[%s]\n%s\n\n' % (section, contents)) - data = ''.join(data) + lines.append('[%s]\n%s\n\n' % (section, contents)) + data = ''.join(lines) cmd.write_or_delete_file('entry points', filename, data, True) -- cgit v1.2.1 From 282f2120979d0d97ae52feb557a19c094e548c87 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 11:29:10 -0500 Subject: Remove duplicate check on ep is None. --- setuptools/command/egg_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 17955207..439fe213 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -720,7 +720,7 @@ def write_entries(cmd, basename, filename): if isinstance(ep, str) or ep is None: data = ep - elif ep is not None: + else: lines = [] for section, contents in sorted(ep.items()): if not isinstance(contents, str): -- cgit v1.2.1 From c5f7e3b19c153712f4e77e3c71ce5a7ba9668bc6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 11:41:00 -0500 Subject: Refactor to construct data in a single expression and extract 'to_str'. --- setuptools/command/egg_info.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 439fe213..473b7aa4 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -721,13 +721,15 @@ def write_entries(cmd, basename, filename): if isinstance(ep, str) or ep is None: data = ep else: - lines = [] - for section, contents in sorted(ep.items()): - if not isinstance(contents, str): - contents = EntryPoint.parse_group(section, contents) - contents = '\n'.join(sorted(map(str, contents.values()))) - lines.append('[%s]\n%s\n\n' % (section, contents)) - data = ''.join(lines) + def to_str(contents): + if isinstance(contents, str): + return contents + eps = EntryPoint.parse_group('anything', contents) + return '\n'.join(sorted(map(str, eps.values()))) + data = ''.join( + f'[{section}]\n{to_str(contents)}\n\n' + for section, contents in sorted(ep.items()) + ) cmd.write_or_delete_file('entry points', filename, data, True) -- cgit v1.2.1 From d47d35616920f2f373cc6afbdaf4f30f3faca90f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 11:52:27 -0500 Subject: Refactor to extract entry_points_definition generation. --- setuptools/command/egg_info.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 473b7aa4..b98b84d4 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -715,23 +715,30 @@ def write_arg(cmd, basename, filename, force=False): cmd.write_or_delete_file(argname, filename, value, force) -def write_entries(cmd, basename, filename): - ep = cmd.distribution.entry_points - - if isinstance(ep, str) or ep is None: - data = ep - else: - def to_str(contents): - if isinstance(contents, str): - return contents - eps = EntryPoint.parse_group('anything', contents) - return '\n'.join(sorted(map(str, eps.values()))) - data = ''.join( - f'[{section}]\n{to_str(contents)}\n\n' - for section, contents in sorted(ep.items()) - ) +@functools.singledispatch +def entry_points_definition(eps): + """ + Given a Distribution.entry_points, produce a multiline + string definition of those entry points. + """ + def to_str(contents): + if isinstance(contents, str): + return contents + parsed = EntryPoint.parse_group('anything', contents) + return '\n'.join(sorted(map(str, parsed.values()))) + return ''.join( + f'[{section}]\n{to_str(contents)}\n\n' + for section, contents in sorted(eps.items()) + ) - cmd.write_or_delete_file('entry points', filename, data, True) + +entry_points_definition.register(type(None), lambda x: x) +entry_points_definition.register(str, lambda x: x) + + +def write_entries(cmd, basename, filename): + defn = entry_points_definition(cmd.distribution.entry_points) + cmd.write_or_delete_file('entry points', filename, defn, True) def get_pkg_info_revision(): -- cgit v1.2.1 From 161ff0ff6f679967d323e9fd461eff312d0f12e6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 12:00:14 -0500 Subject: Extract function for converting entry points to a string. --- setuptools/command/egg_info.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index b98b84d4..afab5cd6 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -715,19 +715,27 @@ def write_arg(cmd, basename, filename, force=False): cmd.write_or_delete_file(argname, filename, value, force) +@functools.singledispatch +def entry_point_definition_to_str(value): + """ + Given a value of an entry point or series of entry points, + return each entry point on a single line. + """ + parsed = EntryPoint.parse_group('anything', value) + return '\n'.join(sorted(map(str, parsed.values()))) + + +entry_point_definition_to_str.register(str, lambda x: x) + + @functools.singledispatch def entry_points_definition(eps): """ Given a Distribution.entry_points, produce a multiline string definition of those entry points. """ - def to_str(contents): - if isinstance(contents, str): - return contents - parsed = EntryPoint.parse_group('anything', contents) - return '\n'.join(sorted(map(str, parsed.values()))) return ''.join( - f'[{section}]\n{to_str(contents)}\n\n' + f'[{section}]\n{entry_point_definition_to_str(contents)}\n\n' for section, contents in sorted(eps.items()) ) -- cgit v1.2.1 From b257d137ae2bcf1ef2e188f20e60f3ca5770e090 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 12:43:29 -0500 Subject: In egg_info, port use of pkg_resources.EntryPoint to importlib.metadata --- setuptools/command/egg_info.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index afab5cd6..2ed58eef 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -16,8 +16,10 @@ import io import warnings import time import collections +import operator from .._importlib import metadata +from .._itertools import ensure_unique from setuptools import Command from setuptools.command.sdist import sdist @@ -26,7 +28,7 @@ from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg from pkg_resources import ( Requirement, safe_name, parse_version, - safe_version, yield_lines, EntryPoint, to_filename) + safe_version, yield_lines, to_filename) import setuptools.unicode_utils as unicode_utils from setuptools.glob import glob @@ -721,8 +723,14 @@ def entry_point_definition_to_str(value): Given a value of an entry point or series of entry points, return each entry point on a single line. """ - parsed = EntryPoint.parse_group('anything', value) - return '\n'.join(sorted(map(str, parsed.values()))) + # normalize to a single sequence of lines + lines = yield_lines(value) + parsed = metadata.EntryPoints._from_text('[x]\n' + '\n'.join(lines)) + valid = ensure_unique(parsed, key=operator.attrgetter('name')) + + def ep_to_str(ep): + return f'{ep.name} = {ep.value}' + return '\n'.join(sorted(map(ep_to_str, valid))) entry_point_definition_to_str.register(str, lambda x: x) -- cgit v1.2.1 From abf002112b77c26102a60116a0336ad2e4f56611 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 13:31:44 -0500 Subject: In test command, rely on metadata.EntryPoint for loading the value. --- setuptools/command/test.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 4a389e4d..652f3e4a 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -16,10 +16,11 @@ from pkg_resources import ( evaluate_marker, add_activation_listener, require, - EntryPoint, ) +from .._importlib import metadata from setuptools import Command from setuptools.extern.more_itertools import unique_everseen +from setuptools.extern.jaraco.functools import pass_none class ScanningLoader(TestLoader): @@ -241,12 +242,10 @@ class test(Command): 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. """ - if val is None: - return - parsed = EntryPoint.parse("x=" + val) - return parsed.resolve()() + return metadata.EntryPoint(value=val, name=None, group=None).load()() -- cgit v1.2.1 From 67b25e3986aef5ac04b57be1a5c569e18f95a3d1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 14:30:08 -0500 Subject: Extract module for entry point management. --- setuptools/command/egg_info.py | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 2ed58eef..2e8ca4b7 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -16,10 +16,9 @@ import io import warnings import time import collections -import operator from .._importlib import metadata -from .._itertools import ensure_unique +from .. import _entry_points from setuptools import Command from setuptools.command.sdist import sdist @@ -717,43 +716,8 @@ def write_arg(cmd, basename, filename, force=False): cmd.write_or_delete_file(argname, filename, value, force) -@functools.singledispatch -def entry_point_definition_to_str(value): - """ - Given a value of an entry point or series of entry points, - return each entry point on a single line. - """ - # normalize to a single sequence of lines - lines = yield_lines(value) - parsed = metadata.EntryPoints._from_text('[x]\n' + '\n'.join(lines)) - valid = ensure_unique(parsed, key=operator.attrgetter('name')) - - def ep_to_str(ep): - return f'{ep.name} = {ep.value}' - return '\n'.join(sorted(map(ep_to_str, valid))) - - -entry_point_definition_to_str.register(str, lambda x: x) - - -@functools.singledispatch -def entry_points_definition(eps): - """ - Given a Distribution.entry_points, produce a multiline - string definition of those entry points. - """ - return ''.join( - f'[{section}]\n{entry_point_definition_to_str(contents)}\n\n' - for section, contents in sorted(eps.items()) - ) - - -entry_points_definition.register(type(None), lambda x: x) -entry_points_definition.register(str, lambda x: x) - - def write_entries(cmd, basename, filename): - defn = entry_points_definition(cmd.distribution.entry_points) + defn = _entry_points.render(cmd.distribution.entry_points) cmd.write_or_delete_file('entry points', filename, defn, True) -- cgit v1.2.1 From ebdaa76c3c6c55d5cffd1a80903484d80cf146c6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 15:22:38 -0500 Subject: Refactor _entry_points to separate loading from rendering. Explicitly validate and restore validation of entry points that don't match the pattern. --- setuptools/command/egg_info.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 2e8ca4b7..8af018f4 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -717,7 +717,8 @@ def write_arg(cmd, basename, filename, force=False): def write_entries(cmd, basename, filename): - defn = _entry_points.render(cmd.distribution.entry_points) + eps = _entry_points.load(cmd.distribution.entry_points) + defn = _entry_points.render(eps) cmd.write_or_delete_file('entry points', filename, defn, True) -- cgit v1.2.1 From 740c3b13427aac1b353c0ad6f776d4c6f2655957 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Feb 2022 15:43:03 -0500 Subject: Prefer jaraco.text for yield_lines. --- setuptools/command/easy_install.py | 4 +++- setuptools/command/egg_info.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index b1260dcd..5b73e6e9 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -56,13 +56,15 @@ from setuptools.package_index import ( from setuptools.command import bdist_egg, egg_info from setuptools.wheel import Wheel from pkg_resources import ( - yield_lines, normalize_path, resource_string, + normalize_path, resource_string, get_distribution, find_distributions, Environment, Requirement, Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, VersionConflict, DEVELOP_DIST, ) import pkg_resources from .._path import ensure_directory +from ..extern.jaraco.text import yield_lines + # Turn on PEP440Warnings warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 8af018f4..63389654 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -27,11 +27,12 @@ from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg from pkg_resources import ( Requirement, safe_name, parse_version, - safe_version, yield_lines, to_filename) + safe_version, to_filename) import setuptools.unicode_utils as unicode_utils from setuptools.glob import glob from setuptools.extern import packaging +from setuptools.extern.jaraco.text import yield_lines from setuptools import SetuptoolsDeprecationWarning -- cgit v1.2.1 From a5e663d83bee3ec96890a5f9b5d818c1fdd2d6bc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 17 Feb 2022 19:36:43 -0500 Subject: Deprecated upload_docs command. Ref #2971 --- setuptools/command/upload_docs.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'setuptools/command') diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index f429f568..a5480005 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -17,8 +17,10 @@ import itertools import functools import http.client import urllib.parse +import warnings from .._importlib import metadata +from .. import SetuptoolsDeprecationWarning from .upload import upload @@ -89,6 +91,12 @@ class upload_docs(upload): zip_file.close() def run(self): + warnings.warn( + "upload_docs is deprecated and will be removed in a future " + "version. Use tools like httpie or curl instead.", + SetuptoolsDeprecationWarning, + ) + # Run sub commands for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) -- cgit v1.2.1 From c44e416b44e5e7126f435a7c0b9adc9b88b85cbd Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 26 Feb 2022 12:44:11 -0500 Subject: Prefer range().__contains__ for bounds check. --- setuptools/command/easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 5b73e6e9..07b45e59 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -358,7 +358,7 @@ class easy_install(Command): if not isinstance(self.optimize, int): try: self.optimize = int(self.optimize) - if not (0 <= self.optimize <= 2): + if self.optimize not in range(3): raise ValueError except ValueError as e: raise DistutilsOptionError( -- cgit v1.2.1 From 66dcd5e54fd8fb1f9413b4fac04e073984ed0713 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 26 Feb 2022 12:29:32 -0500 Subject: Use samefile from stdlib, supported on Windows since Python 3.2. --- setuptools/command/easy_install.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 07b45e59..63403d19 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -70,7 +70,7 @@ from ..extern.jaraco.text import yield_lines warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) __all__ = [ - 'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg', + 'easy_install', 'PthDistributions', 'extract_wininst_cfg', 'get_exe_prefixes', ] @@ -79,22 +79,6 @@ def is_64bit(): return struct.calcsize("P") == 8 -def samefile(p1, p2): - """ - Determine if two paths reference the same file. - - Augments os.path.samefile to work on Windows and - suppresses errors if the path doesn't exist. - """ - both_exist = os.path.exists(p1) and os.path.exists(p2) - use_samefile = hasattr(os.path, 'samefile') and both_exist - if use_samefile: - return os.path.samefile(p1, p2) - norm_p1 = os.path.normpath(os.path.normcase(p1)) - norm_p2 = os.path.normpath(os.path.normcase(p2)) - return norm_p1 == norm_p2 - - def _to_bytes(s): return s.encode('utf8') @@ -928,7 +912,7 @@ class easy_install(Command): ensure_directory(destination) dist = self.egg_distribution(egg_path) - if not samefile(egg_path, destination): + if not os.path.samefile(egg_path, destination): if os.path.isdir(destination) and not os.path.islink(destination): dir_util.remove_tree(destination, dry_run=self.dry_run) elif os.path.exists(destination): -- cgit v1.2.1 From bbe8b50eccb5700c44bf793346dd09540bff97ee Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 26 Feb 2022 12:48:11 -0500 Subject: Extract method to validate optimize parameter. --- setuptools/command/easy_install.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 07b45e59..abf25eb9 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -355,15 +355,7 @@ class easy_install(Command): if not self.no_find_links: self.package_index.add_find_links(self.find_links) self.set_undefined_options('install_lib', ('optimize', 'optimize')) - if not isinstance(self.optimize, int): - try: - self.optimize = int(self.optimize) - if self.optimize not in range(3): - raise ValueError - except ValueError as e: - raise DistutilsOptionError( - "--optimize must be 0, 1, or 2" - ) from e + self.optimize = self._validate_optimize(self.optimize) if self.editable and not self.build_directory: raise DistutilsArgError( @@ -375,6 +367,22 @@ class easy_install(Command): self.outputs = [] + @staticmethod + def _validate_optimize(value): + if isinstance(value, int): + return value + + try: + value = int(value) + if value not in range(3): + raise ValueError + except ValueError as e: + raise DistutilsOptionError( + "--optimize must be 0, 1, or 2" + ) from e + + return value + def _fix_install_dir_for_user_site(self): """ Fix the install_dir if "--user" was used. -- cgit v1.2.1 From 99f5ac503ab030c4622cbd8b5129e0880103a68f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 26 Feb 2022 12:49:54 -0500 Subject: Remove 'isinstance(int)' check and just validate unconditionally. --- setuptools/command/easy_install.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index abf25eb9..e2a6543e 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -369,9 +369,6 @@ class easy_install(Command): @staticmethod def _validate_optimize(value): - if isinstance(value, int): - return value - try: value = int(value) if value not in range(3): -- cgit v1.2.1 From d387ae78b3c6384cee30a441045e5b33f2a226b4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 26 Feb 2022 12:51:43 -0500 Subject: Move normpath into if block. --- setuptools/command/easy_install.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index e2a6543e..a526d705 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -309,11 +309,9 @@ class easy_install(Command): self.script_dir = self.install_scripts # default --record from the install command self.set_undefined_options('install', ('record', 'record')) - # Should this be moved to the if statement below? It's not used - # elsewhere - normpath = map(normalize_path, sys.path) self.all_site_dirs = get_site_dirs() if self.site_dirs is not None: + normpath = map(normalize_path, sys.path) site_dirs = [ os.path.expanduser(s.strip()) for s in self.site_dirs.split(',') -- cgit v1.2.1 From 339c29920abdabdd9e6b5983ae711efb61b15d76 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 26 Feb 2022 12:57:38 -0500 Subject: Extract method for processing site dirs --- setuptools/command/easy_install.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index a526d705..905bc627 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -310,21 +310,8 @@ class easy_install(Command): # default --record from the install command self.set_undefined_options('install', ('record', 'record')) self.all_site_dirs = get_site_dirs() - if self.site_dirs is not None: - normpath = map(normalize_path, sys.path) - site_dirs = [ - os.path.expanduser(s.strip()) for s in - self.site_dirs.split(',') - ] - for d in site_dirs: - if not os.path.isdir(d): - log.warn("%s (in --site-dirs) does not exist", d) - elif normalize_path(d) not in normpath: - raise DistutilsOptionError( - d + " (in --site-dirs) is not on sys.path" - ) - else: - self.all_site_dirs.append(normalize_path(d)) + self.all_site_dirs.extend(self._process_site_dirs(self.site_dirs)) + if not self.editable: self.check_site_dir() self.index_url = self.index_url or "https://pypi.org/simple/" @@ -365,6 +352,26 @@ class easy_install(Command): self.outputs = [] + @staticmethod + def _process_site_dirs(site_dirs): + if site_dirs is None: + return + + normpath = map(normalize_path, sys.path) + site_dirs = [ + os.path.expanduser(s.strip()) for s in + site_dirs.split(',') + ] + for d in site_dirs: + if not os.path.isdir(d): + log.warn("%s (in --site-dirs) does not exist", d) + elif normalize_path(d) not in normpath: + raise DistutilsOptionError( + d + " (in --site-dirs) is not on sys.path" + ) + else: + yield normalize_path(d) + @staticmethod def _validate_optimize(value): try: -- cgit v1.2.1 From fb7b30d64eb1475a0f5692e015ac123834ff6c40 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Sun, 27 Feb 2022 18:43:22 +0000 Subject: Check for file existence before using samefile --- setuptools/command/easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 3aed8caa..80ff6347 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -922,7 +922,8 @@ class easy_install(Command): ensure_directory(destination) dist = self.egg_distribution(egg_path) - if not os.path.samefile(egg_path, destination): + both_exist = os.path.exists(egg_path) and os.path.exists(destination) + if not (both_exist and os.path.samefile(egg_path, destination)): if os.path.isdir(destination) and not os.path.islink(destination): dir_util.remove_tree(destination, dry_run=self.dry_run) elif os.path.exists(destination): -- cgit v1.2.1 From 597ff8774e505803a565d9bebde2f8a48519b033 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Sun, 27 Feb 2022 18:57:50 +0000 Subject: Just check for if destination file exists --- setuptools/command/easy_install.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 80ff6347..6da39e73 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -922,8 +922,9 @@ class easy_install(Command): ensure_directory(destination) dist = self.egg_distribution(egg_path) - both_exist = os.path.exists(egg_path) and os.path.exists(destination) - if not (both_exist and os.path.samefile(egg_path, destination)): + if not ( + os.path.exists(destination) and os.path.samefile(egg_path, destination) + ): if os.path.isdir(destination) and not os.path.islink(destination): dir_util.remove_tree(destination, dry_run=self.dry_run) elif os.path.exists(destination): -- cgit v1.2.1 From cb229fa27a86fc48bd40340eacbec60fe5aa609b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 27 Feb 2022 20:38:16 -0500 Subject: Use super throughout. --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 6da39e73..107850a9 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1655,14 +1655,14 @@ class PthDistributions(Environment): if new_path: self.paths.append(dist.location) self.dirty = True - Environment.add(self, dist) + super().add(dist) def remove(self, dist): """Remove `dist` from the distribution map""" while dist.location in self.paths: self.paths.remove(dist.location) self.dirty = True - Environment.remove(self, dist) + super().remove(dist) def make_relative(self, path): npath, last = os.path.split(normalize_path(path)) -- cgit v1.2.1 From 6376ad10547315c15dfec719ff3f384e7a94dfc2 Mon Sep 17 00:00:00 2001 From: Andrey Bienkowski Date: Sun, 6 Mar 2022 00:43:07 +0300 Subject: XXX: Debugging --- setuptools/command/easy_install.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 107850a9..318eac31 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -221,6 +221,42 @@ class easy_install(Command): raise SystemExit() def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME + print(sysconfig._INSTALL_SCHEMES) + print(f'{os.name}_user') + + def global_trace(frame, event, arg): + pass + + import sys + + sys.settrace(global_trace) + + XXX = [set()] + + def trace(frame, event, arg): + config_vars = getattr(self, 'config_vars', {}) + o = { + ('USER_BASE', site.USER_BASE), + ('USER_SITE', site.USER_SITE), + ('install_dir', self.install_dir), + ('install_userbase', self.install_userbase), + ('install_usersite', self.install_usersite), + ('install_purelib', self.install_purelib), + ('install_scripts', self.install_scripts), + ('userbase', config_vars.get('userbase')), + ('usersite', config_vars.get('usersite')), + } + if XXX[0] - o: + print('-', XXX[0] - o) + if o - XXX[0]: + print('+', o - XXX[0]) + XXX[0] = o + lines, start = inspect.getsourcelines(frame) + print(frame.f_lineno, lines[frame.f_lineno - start]) + + import inspect + inspect.currentframe().f_trace = trace + self.version and self._render_version() py_version = sys.version.split()[0] @@ -459,6 +495,7 @@ class easy_install(Command): instdir = normalize_path(self.install_dir) pth_file = os.path.join(instdir, 'easy-install.pth') + print('XXX', instdir, os.path.exists(instdir)) if not os.path.exists(instdir): try: os.makedirs(instdir) -- cgit v1.2.1 From 45340d00688ba29fc3492c52c88c47d14ce918e6 Mon Sep 17 00:00:00 2001 From: Andrey Bienkowski Date: Sun, 6 Mar 2022 07:58:24 +0300 Subject: Revert "XXX: Debugging" This reverts commit 6376ad10547315c15dfec719ff3f384e7a94dfc2. --- setuptools/command/easy_install.py | 37 ------------------------------------- 1 file changed, 37 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 318eac31..107850a9 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -221,42 +221,6 @@ class easy_install(Command): raise SystemExit() def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME - print(sysconfig._INSTALL_SCHEMES) - print(f'{os.name}_user') - - def global_trace(frame, event, arg): - pass - - import sys - - sys.settrace(global_trace) - - XXX = [set()] - - def trace(frame, event, arg): - config_vars = getattr(self, 'config_vars', {}) - o = { - ('USER_BASE', site.USER_BASE), - ('USER_SITE', site.USER_SITE), - ('install_dir', self.install_dir), - ('install_userbase', self.install_userbase), - ('install_usersite', self.install_usersite), - ('install_purelib', self.install_purelib), - ('install_scripts', self.install_scripts), - ('userbase', config_vars.get('userbase')), - ('usersite', config_vars.get('usersite')), - } - if XXX[0] - o: - print('-', XXX[0] - o) - if o - XXX[0]: - print('+', o - XXX[0]) - XXX[0] = o - lines, start = inspect.getsourcelines(frame) - print(frame.f_lineno, lines[frame.f_lineno - start]) - - import inspect - inspect.currentframe().f_trace = trace - self.version and self._render_version() py_version = sys.version.split()[0] @@ -495,7 +459,6 @@ class easy_install(Command): instdir = normalize_path(self.install_dir) pth_file = os.path.join(instdir, 'easy-install.pth') - print('XXX', instdir, os.path.exists(instdir)) if not os.path.exists(instdir): try: os.makedirs(instdir) -- cgit v1.2.1 From b828c32cd49f2281156644fce55d3c40663081dd Mon Sep 17 00:00:00 2001 From: Andrey Bienkowski Date: Sat, 5 Mar 2022 15:20:42 +0300 Subject: Fix editable --user installs with build isolation https://github.com/pypa/setuptools/issues/3019 --- setuptools/command/easy_install.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 107850a9..940c916f 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -169,12 +169,8 @@ class easy_install(Command): self.install_data = None self.install_base = None self.install_platbase = None - if site.ENABLE_USER_SITE: - self.install_userbase = site.USER_BASE - self.install_usersite = site.USER_SITE - else: - self.install_userbase = None - self.install_usersite = None + self.install_userbase = site.USER_BASE + self.install_usersite = site.USER_SITE self.no_find_links = None # Options not specifiable via command line @@ -253,11 +249,9 @@ class easy_install(Command): getattr(sys, 'windir', '').replace('.', ''), ) - if site.ENABLE_USER_SITE: - self.config_vars['userbase'] = self.install_userbase - self.config_vars['usersite'] = self.install_usersite - - elif self.user: + self.config_vars['userbase'] = self.install_userbase + self.config_vars['usersite'] = self.install_usersite + if self.user and not site.ENABLE_USER_SITE: log.warn("WARNING: The user site-packages directory is disabled.") self._fix_install_dir_for_user_site() @@ -373,7 +367,7 @@ class easy_install(Command): """ Fix the install_dir if "--user" was used. """ - if not self.user or not site.ENABLE_USER_SITE: + if not self.user: return self.create_home_path() -- cgit v1.2.1 From a5658e826c1191eb1a40bff894fb625af7cccaa9 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 25 Mar 2022 22:47:31 +0000 Subject: Add test for setup.py install and dependencies --- setuptools/command/easy_install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 107850a9..77dcd25c 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -298,7 +298,9 @@ class easy_install(Command): if not self.editable: self.check_site_dir() - self.index_url = self.index_url or "https://pypi.org/simple/" + default_index = os.getenv("__EASYINSTALL_INDEX", "https://pypi.org/simple/") + # ^ Private API for testing purposes only + self.index_url = self.index_url or default_index self.shadow_path = self.all_site_dirs[:] for path_item in self.install_dir, normalize_path(self.script_dir): if path_item not in self.shadow_path: -- cgit v1.2.1 From 93a24585683944a9369d8fd37a824c0bca345af4 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 25 Mar 2022 22:48:21 +0000 Subject: Make install consider dist.run_command is overwritten in v61.0.0 Starting in v61, setuptools.dist overwrites distutils.dist.run_command to add auto-discovery functionality on top of the original implementation. This change modifies the existing code in setuptools.command.install to consider that previous change when trying to decide if the install command was called directly from `setup.py` or not. --- setuptools/command/install.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/install.py b/setuptools/command/install.py index 35e54d20..55fdb124 100644 --- a/setuptools/command/install.py +++ b/setuptools/command/install.py @@ -91,14 +91,21 @@ class install(orig.install): msg = "For best results, pass -X:Frames to enable call stack." warnings.warn(msg) return True - res = inspect.getouterframes(run_frame)[2] - caller, = res[:1] - info = inspect.getframeinfo(caller) - caller_module = caller.f_globals.get('__name__', '') - return ( - caller_module == 'distutils.dist' - and info.function == 'run_commands' - ) + + frames = inspect.getouterframes(run_frame) + for frame in frames[2:4]: + caller, = frame[:1] + info = inspect.getframeinfo(caller) + caller_module = caller.f_globals.get('__name__', '') + + if caller_module == "setuptools.dist" and info.function == "run_command": + # Starting from v61.0.0 setuptools overwrites dist.run_command + continue + + return ( + caller_module == 'distutils.dist' + and info.function == 'run_commands' + ) def do_egg_install(self): -- cgit v1.2.1 From cc93191764ed8b5de21369eec53aba32e692389c Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Tue, 29 Mar 2022 03:03:34 +0100 Subject: Fix duplicated version tags in egg_info Previously egg_info was adding duplicated tags to the version string. This was happening because of the version normalization. When the version normalization was applied to the string the tag was modified, then later egg_info could no longer recognize it before applying. The fix for this problem was to normalize the tag string before applying. --- setuptools/command/egg_info.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 63389654..ea47e519 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -140,13 +140,18 @@ class InfoCommon: else version + self.vtags ) - def tags(self): + def _safe_tags(self, tags: str) -> 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{tags}")[1:] + + def tags(self) -> str: version = '' if self.tag_build: version += self.tag_build if self.tag_date: version += time.strftime("-%Y%m%d") - return version + return self._safe_tags(version) vtags = property(tags) -- cgit v1.2.1 From cabdd37db15e306060c1b5edcaeb242c218152f8 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Tue, 29 Mar 2022 03:37:04 +0100 Subject: Restore tags in egg_info but change the idempotency check --- setuptools/command/egg_info.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'setuptools/command') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index ea47e519..c37ab81f 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -136,14 +136,19 @@ class InfoCommon: in which case the version string already contains all tags. """ return ( - version if self.vtags and version.endswith(self.vtags) + version if self.vtags and self._already_tagged(version) else version + self.vtags ) - def _safe_tags(self, tags: str) -> str: + def _already_tagged(self, version: str) -> bool: + # Depending on their format, tags may change with version normalization. + # So in addition the regular tags, we have to search for the normalized ones. + return version.endswith(self.vtags) or version.endswith(self._safe_tags()) + + 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{tags}")[1:] + return safe_version(f"0{self.vtags}")[1:] def tags(self) -> str: version = '' @@ -151,7 +156,7 @@ class InfoCommon: version += self.tag_build if self.tag_date: version += time.strftime("-%Y%m%d") - return self._safe_tags(version) + return version vtags = property(tags) -- cgit v1.2.1 From 4621b08512ab5c682191c13bf8810d7c200d7e34 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Tue, 29 Mar 2022 03:38:32 +0100 Subject: Change dist_info naming to use the same convention as bdist_wheel --- setuptools/command/dist_info.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'setuptools/command') diff --git a/setuptools/command/dist_info.py b/setuptools/command/dist_info.py index c45258fa..8b8509f3 100644 --- a/setuptools/command/dist_info.py +++ b/setuptools/command/dist_info.py @@ -4,9 +4,13 @@ As defined in the wheel specification """ import os +import re +import warnings +from inspect import cleandoc from distutils.core import Command from distutils import log +from setuptools.extern import packaging class dist_info(Command): @@ -29,8 +33,36 @@ class dist_info(Command): egg_info.egg_base = self.egg_base egg_info.finalize_options() egg_info.run() - dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info' + name = _safe(self.distribution.get_name()) + version = _version(self.distribution.get_version()) + base = self.egg_base or os.curdir + dist_info_dir = os.path.join(base, f"{name}-{version}.dist-info") log.info("creating '{}'".format(os.path.abspath(dist_info_dir))) bdist_wheel = self.get_finalized_command('bdist_wheel') bdist_wheel.egg2dist(egg_info.egg_info, 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"""!!\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("_") -- cgit v1.2.1