diff --git a/changelog.d/2944.misc.rst b/changelog.d/2944.misc.rst new file mode 100644 index 0000000000..9cfd7b6a05 --- /dev/null +++ b/changelog.d/2944.misc.rst @@ -0,0 +1 @@ +Add support for extended install schemes in easy_install. diff --git a/setuptools/_distutils/command/install.py b/setuptools/_distutils/command/install.py index 80f5f8c73a..40be5ba67b 100644 --- a/setuptools/_distutils/command/install.py +++ b/setuptools/_distutils/command/install.py @@ -123,6 +123,47 @@ def _get_implementation(): return 'Python' +def _select_scheme(ob, name): + vars(ob).update(_remove_set(ob, _scheme_attrs(_resolve_scheme(name)))) + + +def _remove_set(ob, attrs): + """ + Include only attrs that are None in ob. + """ + return { + key: value + for key, value in attrs.items() + if getattr(ob, key) is None + } + + +def _resolve_scheme(name): + os_name, sep, key = name.partition('_') + try: + resolved = sysconfig.get_preferred_scheme(key) + except Exception: + resolved = _pypy_hack(name) + return resolved + + +def _scheme_attrs(name): + """Resolve install directories by applying the install schemes.""" + scheme = _load_schemes()[name] + return { + f'install_{key}': scheme[key] + for key in SCHEME_KEYS + } + + +def _pypy_hack(name): + PY37 = sys.version_info < (3, 8) + old_pypy = hasattr(sys, 'pypy_version_info') and PY37 + prefix = not name.endswith(('_user', '_home')) + pypy_name = 'pypy' + '_nt' * (os.name == 'nt') + return pypy_name if old_pypy and prefix else name + + class install(Command): description = "install everything from build directory" @@ -520,29 +561,7 @@ def finalize_other(self): "I don't know how to install stuff on '%s'" % os.name) def select_scheme(self, name): - os_name, sep, key = name.partition('_') - try: - resolved = sysconfig.get_preferred_scheme(key) - except Exception: - resolved = self._pypy_hack(name) - return self._select_scheme(resolved) - - 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 = _load_schemes()[name] - for key in SCHEME_KEYS: - attrname = 'install_' + key - if getattr(self, attrname) is None: - setattr(self, attrname, scheme[key]) - - @staticmethod - def _pypy_hack(name): - PY37 = sys.version_info < (3, 8) - old_pypy = hasattr(sys, 'pypy_version_info') and PY37 - prefix = not name.endswith(('_user', '_home')) - pypy_name = 'pypy' + '_nt' * (os.name == 'nt') - return pypy_name if old_pypy and prefix else name + _select_scheme(self, name) def _expand_attrs(self, attrs): for attr in attrs: diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index fc848d0d1c..e815005725 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -17,10 +17,10 @@ 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,7 +251,14 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME 'exec_prefix': 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({ + 'implementation_lower': install._get_implementation().lower(), + 'implementation': install._get_implementation(), + }) if site.ENABLE_USER_SITE: self.config_vars['userbase'] = self.install_userbase @@ -711,13 +718,11 @@ def install_item(self, spec, download, tmpdir, deps, install_needed=False): 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]) + 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