From 6706f2f56133446d012753c178a4ed61b9d8ac8b Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 24 Jan 2022 17:07:56 +0000 Subject: [PATCH 01/10] Fixes #112 install command doesn't use platform in nt_user scheme --- distutils/command/install.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/distutils/command/install.py b/distutils/command/install.py index 511938f47f..0c280f1c8c 100644 --- a/distutils/command/install.py +++ b/distutils/command/install.py @@ -68,8 +68,8 @@ INSTALL_SCHEMES['nt_user'] = { 'purelib': '{usersite}', 'platlib': '{usersite}', - 'headers': '{userbase}/{implementation}{py_version_nodot}/Include/{dist_name}', - 'scripts': '{userbase}/{implementation}{py_version_nodot}/Scripts', + 'headers': '{userbase}/{implementation}{py_version_nodot_plat}/Include/{dist_name}', + 'scripts': '{userbase}/{implementation}{py_version_nodot_plat}/Scripts', 'data' : '{userbase}', } @@ -411,6 +411,10 @@ def finalize_options(self): 'implementation_lower': _get_implementation().lower(), 'implementation': _get_implementation(), } + try: + local_vars['py_version_nodot_plat'] = sys.winver.replace('.', '') + except AttributeError: + local_vars['py_version_nodot_plat'] = '' if HAS_USER_SITE: local_vars['userbase'] = self.install_userbase From a855f07676a3a925797d6bce49af730dfc7e62c8 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 24 Jan 2022 17:58:53 +0000 Subject: [PATCH 02/10] Fix fake expanduser() and verify calculated headers path --- distutils/tests/test_install.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/distutils/tests/test_install.py b/distutils/tests/test_install.py index 75770b05e6..a60db13993 100644 --- a/distutils/tests/test_install.py +++ b/distutils/tests/test_install.py @@ -81,7 +81,9 @@ def test_user_site(self): install_module.USER_SITE = self.user_site def _expanduser(path): - return self.tmpdir + if path.startswith('~'): + return os.path.normpath(self.tmpdir + path[1:]) + return path self.old_expand = os.path.expanduser os.path.expanduser = _expanduser @@ -122,6 +124,15 @@ def cleanup(): self.assertIn('userbase', cmd.config_vars) self.assertIn('usersite', cmd.config_vars) + actual_headers = os.path.relpath(cmd.install_headers, self.user_base) + expect_headers = os.path.join( + os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base), + "Include", + "xx", + ) + + self.assertEqual(os.path.normcase(actual_headers), os.path.normcase(expect_headers)) + def test_handle_extra_path(self): dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'}) cmd = install(dist) From 2cadaba69aa3d8bef49a5dc8225b4cf5139446a2 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 24 Jan 2022 18:13:13 +0000 Subject: [PATCH 03/10] Add non-NT path for expected path --- distutils/tests/test_install.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/distutils/tests/test_install.py b/distutils/tests/test_install.py index a60db13993..2cc9d31c68 100644 --- a/distutils/tests/test_install.py +++ b/distutils/tests/test_install.py @@ -125,11 +125,18 @@ def cleanup(): self.assertIn('usersite', cmd.config_vars) actual_headers = os.path.relpath(cmd.install_headers, self.user_base) - expect_headers = os.path.join( - os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base), - "Include", - "xx", - ) + if os.name == 'nt': + expect_headers = os.path.join( + os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base), + 'Include', + 'xx', + ) + else: + expect_headers = os.path.join( + 'include', + os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base).rpartition(os.sep)[2], + 'xx', + ) self.assertEqual(os.path.normcase(actual_headers), os.path.normcase(expect_headers)) From aac97591cf99214eb9a7493028ebbbea5b44209c Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 24 Jan 2022 20:19:38 +0000 Subject: [PATCH 04/10] Change API --- distutils/tests/test_install.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/distutils/tests/test_install.py b/distutils/tests/test_install.py index 2cc9d31c68..554b2770e2 100644 --- a/distutils/tests/test_install.py +++ b/distutils/tests/test_install.py @@ -125,18 +125,7 @@ def cleanup(): self.assertIn('usersite', cmd.config_vars) actual_headers = os.path.relpath(cmd.install_headers, self.user_base) - if os.name == 'nt': - expect_headers = os.path.join( - os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base), - 'Include', - 'xx', - ) - else: - expect_headers = os.path.join( - 'include', - os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base).rpartition(os.sep)[2], - 'xx', - ) + expect_headers = os.path.join(sysconfig.get_python_inc(0, ''), 'xx') self.assertEqual(os.path.normcase(actual_headers), os.path.normcase(expect_headers)) From 198cd3b1c38ac0419933484fecc833581e4b5de3 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 24 Jan 2022 20:54:58 +0000 Subject: [PATCH 05/10] Special case for Windows --- distutils/tests/test_install.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/distutils/tests/test_install.py b/distutils/tests/test_install.py index 554b2770e2..e8ef1caf5f 100644 --- a/distutils/tests/test_install.py +++ b/distutils/tests/test_install.py @@ -125,7 +125,14 @@ def cleanup(): self.assertIn('usersite', cmd.config_vars) actual_headers = os.path.relpath(cmd.install_headers, self.user_base) - expect_headers = os.path.join(sysconfig.get_python_inc(0, ''), 'xx') + if os.name == 'nt': + expect_headers = os.path.join( + os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base), + 'Include', + 'xx', + ) + else: + expect_headers = os.path.join(sysconfig.get_python_inc(0, ''), 'xx') self.assertEqual(os.path.normcase(actual_headers), os.path.normcase(expect_headers)) From 4d36a45c4bf1a700105a6b5c34719a50ef2fdb81 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:49:59 +0800 Subject: [PATCH 06/10] Use super() --- distutils/_msvccompiler.py | 2 +- distutils/bcppcompiler.py | 2 +- distutils/command/bdist_msi.py | 2 +- distutils/command/check.py | 2 +- distutils/cygwinccompiler.py | 4 ++-- distutils/msvc9compiler.py | 2 +- distutils/msvccompiler.py | 2 +- distutils/tests/test_config.py | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index c41ea9ae30..f2f801c552 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -203,7 +203,7 @@ class MSVCCompiler(CCompiler) : def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) + super().__init__(verbose, dry_run, force) # target platform (.plat_name is consistent with 'bdist') self.plat_name = None self.initialized = False diff --git a/distutils/bcppcompiler.py b/distutils/bcppcompiler.py index 071fea5d03..2eb6d2e956 100644 --- a/distutils/bcppcompiler.py +++ b/distutils/bcppcompiler.py @@ -55,7 +55,7 @@ def __init__ (self, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) + super().__init__(verbose, dry_run, force) # These executables are assumed to all be in the path. # Borland doesn't seem to use any special registry settings to diff --git a/distutils/command/bdist_msi.py b/distutils/command/bdist_msi.py index 0863a1883e..1525953241 100644 --- a/distutils/command/bdist_msi.py +++ b/distutils/command/bdist_msi.py @@ -27,7 +27,7 @@ class PyDialog(Dialog): def __init__(self, *args, **kw): """Dialog(database, name, x, y, w, h, attributes, title, first, default, cancel, bitmap=true)""" - Dialog.__init__(self, *args) + super().__init__(*args) ruler = self.h - 36 bmwidth = 152*ruler/328 #if kw.get("bitmap", True): diff --git a/distutils/command/check.py b/distutils/command/check.py index ada2500646..525540b6cc 100644 --- a/distutils/command/check.py +++ b/distutils/command/check.py @@ -17,7 +17,7 @@ class SilentReporter(Reporter): def __init__(self, source, report_level, halt_level, stream=None, debug=0, encoding='ascii', error_handler='replace'): self.messages = [] - Reporter.__init__(self, source, report_level, halt_level, stream, + super().__init__(source, report_level, halt_level, stream, debug, encoding, error_handler) def system_message(self, level, message, *children, **kwargs): diff --git a/distutils/cygwinccompiler.py b/distutils/cygwinccompiler.py index fd082f6d27..c5c86d8f07 100644 --- a/distutils/cygwinccompiler.py +++ b/distutils/cygwinccompiler.py @@ -108,7 +108,7 @@ class CygwinCCompiler(UnixCCompiler): def __init__(self, verbose=0, dry_run=0, force=0): - UnixCCompiler.__init__(self, verbose, dry_run, force) + super().__init__(verbose, dry_run, force) status, details = check_config_h() self.debug_print("Python's GCC status: %s (details: %s)" % @@ -268,7 +268,7 @@ class Mingw32CCompiler(CygwinCCompiler): def __init__(self, verbose=0, dry_run=0, force=0): - CygwinCCompiler.__init__ (self, verbose, dry_run, force) + super().__init__ (verbose, dry_run, force) shared_option = "-shared" diff --git a/distutils/msvc9compiler.py b/distutils/msvc9compiler.py index 14d137752d..6b6273836e 100644 --- a/distutils/msvc9compiler.py +++ b/distutils/msvc9compiler.py @@ -324,7 +324,7 @@ class MSVCCompiler(CCompiler) : exe_extension = '.exe' def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) + super().__init__(verbose, dry_run, force) self.__version = VERSION self.__root = r"Software\Microsoft\VisualStudio" # self.__macros = MACROS diff --git a/distutils/msvccompiler.py b/distutils/msvccompiler.py index 2d447b857d..e1367b8918 100644 --- a/distutils/msvccompiler.py +++ b/distutils/msvccompiler.py @@ -228,7 +228,7 @@ class MSVCCompiler(CCompiler) : exe_extension = '.exe' def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) + super().__init__(verbose, dry_run, force) self.__version = get_build_version() self.__arch = get_build_architecture() if self.__arch == "Intel": diff --git a/distutils/tests/test_config.py b/distutils/tests/test_config.py index 8ab70efb16..27bd9d4435 100644 --- a/distutils/tests/test_config.py +++ b/distutils/tests/test_config.py @@ -66,7 +66,7 @@ def setUp(self): class command(PyPIRCCommand): def __init__(self, dist): - PyPIRCCommand.__init__(self, dist) + super().__init__(dist) def initialize_options(self): pass finalize_options = initialize_options From d16d759bb080761732cafb0e85bc804e6b902e46 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Jan 2022 12:55:04 -0500 Subject: [PATCH 07/10] Refactor to limit indentation and share behavior. --- distutils/tests/test_install.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/distutils/tests/test_install.py b/distutils/tests/test_install.py index e8ef1caf5f..5dbc06b090 100644 --- a/distutils/tests/test_install.py +++ b/distutils/tests/test_install.py @@ -126,13 +126,12 @@ def cleanup(): actual_headers = os.path.relpath(cmd.install_headers, self.user_base) if os.name == 'nt': - expect_headers = os.path.join( - os.path.relpath(os.path.dirname(self.old_user_site), self.old_user_base), - 'Include', - 'xx', - ) + site_path = os.path.relpath( + os.path.dirname(self.old_user_site), self.old_user_base) + include = os.path.join(site_path, 'Include') else: - expect_headers = os.path.join(sysconfig.get_python_inc(0, ''), 'xx') + include = sysconfig.get_python_inc(0, '') + expect_headers = os.path.join(include, 'xx') self.assertEqual(os.path.normcase(actual_headers), os.path.normcase(expect_headers)) From 917046dc70da8c6c5ba87571b0864826085e3659 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Jan 2022 13:12:34 -0500 Subject: [PATCH 08/10] Only rely on py_version_nodot_plat where not present (Python 3.9 and earlier). --- distutils/command/install.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/distutils/command/install.py b/distutils/command/install.py index 0c280f1c8c..9fe659131f 100644 --- a/distutils/command/install.py +++ b/distutils/command/install.py @@ -411,17 +411,19 @@ def finalize_options(self): 'implementation_lower': _get_implementation().lower(), 'implementation': _get_implementation(), } - try: - local_vars['py_version_nodot_plat'] = sys.winver.replace('.', '') - except AttributeError: - local_vars['py_version_nodot_plat'] = '' + + # vars for compatibility on older Pythons + compat_vars = dict( + # Python 3.9 and earlier + py_version_nodot_plat=getattr(sys, 'winver', '').replace('.', ''), + ) if HAS_USER_SITE: local_vars['userbase'] = self.install_userbase local_vars['usersite'] = self.install_usersite self.config_vars = _collections.DictStack( - [sysconfig.get_config_vars(), local_vars]) + [compat_vars, sysconfig.get_config_vars(), local_vars]) self.expand_basedirs() From 04b796f1a64577eaa66265778f186b6734a12eb5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Jan 2022 13:18:37 -0500 Subject: [PATCH 09/10] Add changelog --- changelog.d/3062.change.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/3062.change.rst diff --git a/changelog.d/3062.change.rst b/changelog.d/3062.change.rst new file mode 100644 index 0000000000..cf3ff50227 --- /dev/null +++ b/changelog.d/3062.change.rst @@ -0,0 +1 @@ +Merge with pypa/distutils@b53a824ec3 including improved support for lib directories on non-x64 Windows builds. From 44649c5a483a9c1cf2d80f6e9706d581cfc7437e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Jan 2022 15:25:09 -0500 Subject: [PATCH 10/10] Add py_version_nodot_plat substitution support to easy_install. --- setuptools/command/easy_install.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 5fab0fdb5b..e25090b840 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -260,6 +260,12 @@ def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME '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