From 06d2c56b85c97d0e3cfa278048a8fab43d38684e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 7 Jul 2020 18:03:06 -0400 Subject: http https://sources.debian.org/data/main/p/python3.8/3.8.4~rc1-1/debian/patches/distutils-install-layout.diff | git apply --include 'Lib/distutils/*' --- command/install.py | 43 ++++++++++++++++++++++++++++++++++++++++++- command/install_egg_info.py | 30 +++++++++++++++++++++++++----- sysconfig.py | 7 +++++++ tests/test_bdist_dumb.py | 2 +- tests/test_install.py | 4 ++-- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/command/install.py b/command/install.py index aaa300ef..1067e673 100644 --- a/command/install.py +++ b/command/install.py @@ -35,6 +35,20 @@ INSTALL_SCHEMES = { 'scripts': '$base/bin', 'data' : '$base', }, + 'unix_local': { + 'purelib': '$base/local/lib/python$py_version_short/dist-packages', + 'platlib': '$platbase/local/lib/python$py_version_short/dist-packages', + 'headers': '$base/local/include/python$py_version_short/$dist_name', + 'scripts': '$base/local/bin', + 'data' : '$base/local', + }, + 'deb_system': { + 'purelib': '$base/lib/python3/dist-packages', + 'platlib': '$platbase/lib/python3/dist-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, 'unix_home': { 'purelib': '$base/lib/python', 'platlib': '$base/$platlibdir/python', @@ -131,6 +145,9 @@ class install(Command): ('record=', None, "filename in which to record list of installed files"), + + ('install-layout=', None, + "installation layout to choose (known values: deb, unix)"), ] boolean_options = ['compile', 'force', 'skip-build'] @@ -151,6 +168,7 @@ class install(Command): self.exec_prefix = None self.home = None self.user = 0 + self.prefix_option = None # These select only the installation base; it's up to the user to # specify the installation scheme (currently, that means supplying @@ -172,6 +190,9 @@ class install(Command): self.install_userbase = USER_BASE self.install_usersite = USER_SITE + # enable custom installation, known values: deb + self.install_layout = None + self.compile = None self.optimize = None @@ -414,6 +435,7 @@ class install(Command): self.install_base = self.install_platbase = self.home self.select_scheme("unix_home") else: + self.prefix_option = self.prefix if self.prefix is None: if self.exec_prefix is not None: raise DistutilsOptionError( @@ -428,7 +450,26 @@ class install(Command): self.install_base = self.prefix self.install_platbase = self.exec_prefix - self.select_scheme("unix_prefix") + if self.install_layout: + if self.install_layout.lower() in ['deb']: + self.select_scheme("deb_system") + elif self.install_layout.lower() in ['unix']: + self.select_scheme("unix_prefix") + else: + raise DistutilsOptionError( + "unknown value for --install-layout") + elif ((self.prefix_option and + os.path.normpath(self.prefix) != '/usr/local') + or sys.base_prefix != sys.prefix + or 'PYTHONUSERBASE' in os.environ + or 'VIRTUAL_ENV' in os.environ + or 'real_prefix' in sys.__dict__): + self.select_scheme("unix_prefix") + else: + if os.path.normpath(self.prefix) == '/usr/local': + self.prefix = self.exec_prefix = '/usr' + self.install_base = self.install_platbase = '/usr' + self.select_scheme("unix_local") def finalize_other(self): """Finalizes options for non-posix platforms""" diff --git a/command/install_egg_info.py b/command/install_egg_info.py index 0ddc7367..0a71b610 100644 --- a/command/install_egg_info.py +++ b/command/install_egg_info.py @@ -14,18 +14,38 @@ class install_egg_info(Command): description = "Install package's PKG-INFO metadata as an .egg-info file" user_options = [ ('install-dir=', 'd', "directory to install to"), + ('install-layout', None, "custom installation layout"), ] def initialize_options(self): self.install_dir = None + self.install_layout = None + self.prefix_option = None def finalize_options(self): self.set_undefined_options('install_lib',('install_dir','install_dir')) - basename = "%s-%s-py%d.%d.egg-info" % ( - to_filename(safe_name(self.distribution.get_name())), - to_filename(safe_version(self.distribution.get_version())), - *sys.version_info[:2] - ) + self.set_undefined_options('install',('install_layout','install_layout')) + self.set_undefined_options('install',('prefix_option','prefix_option')) + if self.install_layout: + if not self.install_layout.lower() in ['deb', 'unix']: + raise DistutilsOptionError( + "unknown value for --install-layout") + no_pyver = (self.install_layout.lower() == 'deb') + elif self.prefix_option: + no_pyver = False + else: + no_pyver = True + if no_pyver: + basename = "%s-%s.egg-info" % ( + to_filename(safe_name(self.distribution.get_name())), + to_filename(safe_version(self.distribution.get_version())) + ) + else: + basename = "%s-%s-py%d.%d.egg-info" % ( + to_filename(safe_name(self.distribution.get_name())), + to_filename(safe_version(self.distribution.get_version())), + *sys.version_info[:2] + ) self.target = os.path.join(self.install_dir, basename) self.outputs = [self.target] diff --git a/sysconfig.py b/sysconfig.py index 37feae5d..6edad79a 100644 --- a/sysconfig.py +++ b/sysconfig.py @@ -138,6 +138,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): If 'prefix' is supplied, use it instead of sys.base_prefix or sys.base_exec_prefix -- i.e., ignore 'plat_specific'. """ + is_default_prefix = not prefix or os.path.normpath(prefix) in ('/usr', '/usr/local') if prefix is None: if standard_lib: prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX @@ -156,6 +157,12 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): "python" + get_python_version()) if standard_lib: return libpython + elif (is_default_prefix and + 'PYTHONUSERBASE' not in os.environ and + 'VIRTUAL_ENV' not in os.environ and + 'real_prefix' not in sys.__dict__ and + sys.prefix == sys.base_prefix): + return os.path.join(prefix, "lib", "python3", "dist-packages") else: return os.path.join(libpython, "site-packages") elif os.name == "nt": diff --git a/tests/test_bdist_dumb.py b/tests/test_bdist_dumb.py index 01a233bc..f99dec53 100644 --- a/tests/test_bdist_dumb.py +++ b/tests/test_bdist_dumb.py @@ -85,7 +85,7 @@ class BuildDumbTestCase(support.TempdirManager, fp.close() contents = sorted(filter(None, map(os.path.basename, contents))) - wanted = ['foo-0.1-py%s.%s.egg-info' % sys.version_info[:2], 'foo.py'] + wanted = ['foo-0.1.egg-info', 'foo.py'] if not sys.dont_write_bytecode: wanted.append('foo.%s.pyc' % sys.implementation.cache_tag) self.assertEqual(contents, sorted(wanted)) diff --git a/tests/test_install.py b/tests/test_install.py index 51c80e04..2ada481f 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -194,7 +194,7 @@ class InstallTestCase(support.TempdirManager, found = [os.path.basename(line) for line in content.splitlines()] expected = ['hello.py', 'hello.%s.pyc' % sys.implementation.cache_tag, 'sayhi', - 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] + 'UNKNOWN-0.0.0.egg-info'] self.assertEqual(found, expected) def test_record_extensions(self): @@ -227,7 +227,7 @@ class InstallTestCase(support.TempdirManager, found = [os.path.basename(line) for line in content.splitlines()] expected = [_make_ext_name('xx'), - 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] + 'UNKNOWN-0.0.0.egg-info'] self.assertEqual(found, expected) def test_debug_mode(self): -- cgit v1.2.1 From f945849aa91150e0a568a2a047df8b092096feb4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 8 Jul 2020 19:34:22 -0400 Subject: Restore test expectations on non-Debian hosts. --- distutils/_platform.py | 21 +++++++++++++++++++++ distutils/tests/test_bdist_dumb.py | 8 +++++++- distutils/tests/test_install.py | 7 +++++-- 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 distutils/_platform.py diff --git a/distutils/_platform.py b/distutils/_platform.py new file mode 100644 index 00000000..b03659a9 --- /dev/null +++ b/distutils/_platform.py @@ -0,0 +1,21 @@ +import re +import pathlib +import contextlib + + +# from jaraco.context +class suppress(contextlib.suppress, contextlib.ContextDecorator): + """ + A version of contextlib.suppress with decorator support. + + >>> @suppress(KeyError) + ... def key_error(): + ... {}[''] + >>> key_error() + """ + + +@suppress(Exception) +def is_debian(): + issue = pathlib.Path('/etc/issue').read_text() + return bool(re.search('(debian|buntu|mint)', issue, re.IGNORE_CASE)) diff --git a/distutils/tests/test_bdist_dumb.py b/distutils/tests/test_bdist_dumb.py index f99dec53..e58d775d 100644 --- a/distutils/tests/test_bdist_dumb.py +++ b/distutils/tests/test_bdist_dumb.py @@ -9,6 +9,7 @@ from test.support import run_unittest from distutils.core import Distribution from distutils.command.bdist_dumb import bdist_dumb from distutils.tests import support +from distutils._platform import is_debian SETUP_PY = """\ from distutils.core import setup @@ -85,7 +86,12 @@ class BuildDumbTestCase(support.TempdirManager, fp.close() contents = sorted(filter(None, map(os.path.basename, contents))) - wanted = ['foo-0.1.egg-info', 'foo.py'] + egg_info_name = ( + 'foo-0.1.egg-info' if is_debian() else + 'foo-0.1-py%s.%s.egg-info' % sys.version_info[:2] + ) + wanted = [egg_info_name, 'foo.py'] + if not sys.dont_write_bytecode: wanted.append('foo.%s.pyc' % sys.implementation.cache_tag) self.assertEqual(contents, sorted(wanted)) diff --git a/distutils/tests/test_install.py b/distutils/tests/test_install.py index 7553888d..907442bb 100644 --- a/distutils/tests/test_install.py +++ b/distutils/tests/test_install.py @@ -15,6 +15,7 @@ from distutils.command.install import INSTALL_SCHEMES from distutils.core import Distribution from distutils.errors import DistutilsOptionError from distutils.extension import Extension +from distutils._platform import is_debian from distutils.tests import support from test import support as test_support @@ -195,7 +196,8 @@ class InstallTestCase(support.TempdirManager, found = [os.path.basename(line) for line in content.splitlines()] expected = ['hello.py', 'hello.%s.pyc' % sys.implementation.cache_tag, 'sayhi', - 'UNKNOWN-0.0.0.egg-info'] + 'UNKNOWN-0.0.0.egg-info' if is_debian() else + 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] self.assertEqual(found, expected) def test_record_extensions(self): @@ -228,7 +230,8 @@ class InstallTestCase(support.TempdirManager, found = [os.path.basename(line) for line in content.splitlines()] expected = [_make_ext_name('xx'), - 'UNKNOWN-0.0.0.egg-info'] + 'UNKNOWN-0.0.0.egg-info' if is_debian() else + 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] self.assertEqual(found, expected) def test_debug_mode(self): -- cgit v1.2.1 From f65fe9dcf7f63ca7ad25ca13eac7b42e1970d1dd Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 8 Jul 2020 19:42:03 -0400 Subject: Restore default behavior on non-Debian systems. --- distutils/command/install.py | 7 +++++-- distutils/command/install_egg_info.py | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/distutils/command/install.py b/distutils/command/install.py index 34896f03..889e683d 100644 --- a/distutils/command/install.py +++ b/distutils/command/install.py @@ -14,6 +14,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 distutils._platform import is_debian from site import USER_BASE from site import USER_SITE @@ -206,7 +207,7 @@ class install(Command): # enable custom installation, known values: deb self.install_layout = None - + self.compile = None self.optimize = None @@ -479,11 +480,13 @@ class install(Command): or 'VIRTUAL_ENV' in os.environ or 'real_prefix' in sys.__dict__): self.select_scheme("unix_prefix") - else: + elif is_debian(): if os.path.normpath(self.prefix) == '/usr/local': self.prefix = self.exec_prefix = '/usr' self.install_base = self.install_platbase = '/usr' self.select_scheme("unix_local") + else: + self.select_scheme("unix_prefix") def finalize_other(self): """Finalizes options for non-posix platforms""" diff --git a/distutils/command/install_egg_info.py b/distutils/command/install_egg_info.py index 0a71b610..a9b6067a 100644 --- a/distutils/command/install_egg_info.py +++ b/distutils/command/install_egg_info.py @@ -6,6 +6,7 @@ a package's PKG-INFO metadata.""" from distutils.cmd import Command from distutils import log, dir_util +from distutils._platform import is_debian import os, sys, re class install_egg_info(Command): @@ -34,7 +35,7 @@ class install_egg_info(Command): elif self.prefix_option: no_pyver = False else: - no_pyver = True + no_pyver = is_debian() if no_pyver: basename = "%s-%s.egg-info" % ( to_filename(safe_name(self.distribution.get_name())), -- cgit v1.2.1