From 28e1b5ab2f4d573a91705cdbb025e57023d264b1 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Mon, 13 Jul 2020 11:15:26 -0400 Subject: Use .pth file to import distutils from setuptools --- setup.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 1fe18bd1..daab3e87 100755 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ import os import sys import setuptools +from setuptools.command.install import install here = os.path.dirname(__file__) @@ -49,6 +50,7 @@ def _gen_console_scripts(): package_data = dict( setuptools=['script (dev).tmpl', 'script.tmpl', 'site-patch.py'], + _distutils_importer=['distutils-shim-package/distutils/__init__.py'], ) force_windows_specific_files = ( @@ -81,8 +83,38 @@ def pypi_link(pkg_filename): return '/'.join(parts) +class install_with_pth(install): + """ + Custom install command to install a .pth file for distutils patching. + + This is necessary because there's no standard way to install a `.pth` file + alongside your package (and there probably shouldn't be one), but we need + to do this in order to give precedence higher precedence to our version of + `distutils` than the standard library. + """ + + def initialize_options(self): + install.initialize_options(self) + + name = 'distutils_precedence' + with open(os.path.join(here, name + '.pth'), 'rt') as f: + contents = f.read() + + self.extra_path = (name, contents) + + def finalize_options(self): + install.finalize_options(self) + + install_suffix = os.path.relpath(self.install_lib, + self.install_libbase) + + if install_suffix == self.extra_path[1]: + self.install_lib = self.install_libbase + + setup_params = dict( src_root=None, + cmdclass={'install': install_with_pth}, package_data=package_data, entry_points={ "distutils.commands": [ -- cgit v1.2.1 From 370839b417f6bafe783fa040646d80bdf673fac4 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Mon, 13 Jul 2020 15:25:32 -0400 Subject: Use import hook instead of sys.path manipulation --- setup.py | 1 - 1 file changed, 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index daab3e87..cba37d3e 100755 --- a/setup.py +++ b/setup.py @@ -50,7 +50,6 @@ def _gen_console_scripts(): package_data = dict( setuptools=['script (dev).tmpl', 'script.tmpl', 'site-patch.py'], - _distutils_importer=['distutils-shim-package/distutils/__init__.py'], ) force_windows_specific_files = ( -- cgit v1.2.1 From e371422476f51a83d27d70dc45bbfba1544aad55 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 19 Jul 2020 21:36:33 -0400 Subject: Consolidate distutils importing hacks into _distutils_importer package. Generate distutils-precedence.pth inline. --- setup.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index cba37d3e..a6e1abc4 100755 --- a/setup.py +++ b/setup.py @@ -94,12 +94,8 @@ class install_with_pth(install): def initialize_options(self): install.initialize_options(self) - - name = 'distutils_precedence' - with open(os.path.join(here, name + '.pth'), 'rt') as f: - contents = f.read() - - self.extra_path = (name, contents) + self.extra_path = ( + 'distutils-precedence', 'import _distutils_importer.install') def finalize_options(self): install.finalize_options(self) -- cgit v1.2.1 From dcc71f773576c19a3658735879893515b056ece5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:35:02 -0400 Subject: Rename _distutils_importer to _distutils_hack, as it supplies more than just an importer. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index a6e1abc4..2d8bdf85 100755 --- a/setup.py +++ b/setup.py @@ -95,7 +95,7 @@ class install_with_pth(install): def initialize_options(self): install.initialize_options(self) self.extra_path = ( - 'distutils-precedence', 'import _distutils_importer.install') + 'distutils-precedence', 'import _distutils_hack.install') def finalize_options(self): install.finalize_options(self) -- cgit v1.2.1 From 384a51657c94271d29c437415080f25f7df4103b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:38:13 -0400 Subject: Extract pth name and contents into class variables. --- setup.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 2d8bdf85..edb2bbcf 100755 --- a/setup.py +++ b/setup.py @@ -92,18 +92,21 @@ class install_with_pth(install): `distutils` than the standard library. """ + _pth_name = 'distutils-precedence' + _pth_contents = 'import _distutils_hack.install' + def initialize_options(self): install.initialize_options(self) - self.extra_path = ( - 'distutils-precedence', 'import _distutils_hack.install') + self.extra_path = self._pth_name, self._pth_contents def finalize_options(self): install.finalize_options(self) + # undo secondary effect of `extra_path` adding to `install_lib` install_suffix = os.path.relpath(self.install_lib, self.install_libbase) - if install_suffix == self.extra_path[1]: + if install_suffix == self._pth_contents: self.install_lib = self.install_libbase -- cgit v1.2.1 From f3b177e9c2b77104ddebaec7b581e2aee73a1184 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:42:15 -0400 Subject: Update docstring to use imperative voice, provide a bit more context, and advise against copying of the behavior. --- setup.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index edb2bbcf..45ddb149 100755 --- a/setup.py +++ b/setup.py @@ -86,10 +86,13 @@ class install_with_pth(install): """ Custom install command to install a .pth file for distutils patching. - This is necessary because there's no standard way to install a `.pth` file - alongside your package (and there probably shouldn't be one), but we need - to do this in order to give precedence higher precedence to our version of - `distutils` than the standard library. + This hack is necessary because there's no standard way to install behavior + on startup (and it's debatable if there should be one). This hack (ab)uses + the `extra_path` behavior in Setuptools to install a `.pth` file with + implicit behavior on startup to give higher precedence to the local version + of `distutils` over the version from the standard library. + + Please do not replicate this behavior. """ _pth_name = 'distutils-precedence' -- cgit v1.2.1 From 268ef5f553f29977f708c256ee398c9e29cb4da7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:43:08 -0400 Subject: Remove hanging indent --- setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 45ddb149..6290a746 100755 --- a/setup.py +++ b/setup.py @@ -106,8 +106,10 @@ class install_with_pth(install): install.finalize_options(self) # undo secondary effect of `extra_path` adding to `install_lib` - install_suffix = os.path.relpath(self.install_lib, - self.install_libbase) + install_suffix = os.path.relpath( + self.install_lib, + self.install_libbase, + ) if install_suffix == self._pth_contents: self.install_lib = self.install_libbase -- cgit v1.2.1 From 5642e413fb6c75434f109be943bdb09ea9e7ade2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:44:51 -0400 Subject: Extract function for restoring install lib to encapsulate behavior. --- setup.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 6290a746..6f6601fe 100755 --- a/setup.py +++ b/setup.py @@ -104,14 +104,15 @@ class install_with_pth(install): def finalize_options(self): install.finalize_options(self) + self._restore_install_lib() - # undo secondary effect of `extra_path` adding to `install_lib` - install_suffix = os.path.relpath( - self.install_lib, - self.install_libbase, - ) + def _restore_install_lib(self): + """ + Undo secondary effect of `extra_path` adding to `install_lib` + """ + suffix = os.path.relpath(self.install_lib, self.install_libbase) - if install_suffix == self._pth_contents: + if suffix == self._pth_contents: self.install_lib = self.install_libbase -- cgit v1.2.1 From 83a85a71cd779b1b1b3a44e21cc198264650da46 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:51:40 -0400 Subject: Restore early opt-in/opt-out for pth behavior. --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 6f6601fe..2e44225e 100755 --- a/setup.py +++ b/setup.py @@ -5,6 +5,7 @@ Distutils setup file, used to install or test 'setuptools' import os import sys +import textwrap import setuptools from setuptools.command.install import install @@ -96,7 +97,11 @@ class install_with_pth(install): """ _pth_name = 'distutils-precedence' - _pth_contents = 'import _distutils_hack.install' + _pth_contents = textwrap.dedent(""" + import os + enabled = os.environ.get('SETUPTOOLS_USE_DISTUTILS') == 'local' + enabled and __import__('_distutils_hack.install') + """).lstrip().replace('\n', '; ') def initialize_options(self): install.initialize_options(self) -- cgit v1.2.1 From 1251a231ad75fa649da700645690eb3c0a348f08 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Jul 2020 10:53:31 -0400 Subject: Replace install behavior on import with direct invocation (now that 'enabled' logic is duplicated in pth file). --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 2e44225e..37953051 100755 --- a/setup.py +++ b/setup.py @@ -100,7 +100,7 @@ class install_with_pth(install): _pth_contents = textwrap.dedent(""" import os enabled = os.environ.get('SETUPTOOLS_USE_DISTUTILS') == 'local' - enabled and __import__('_distutils_hack.install') + enabled and __import__('_distutils_hack').add_shim() """).lstrip().replace('\n', '; ') def initialize_options(self): -- cgit v1.2.1 From 48a17a56ecfc77fb60780e3cfa75390f6bb10b15 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 8 Aug 2020 12:22:05 -0400 Subject: As discovered in bpo-41509, relpath can strip spaces, so match that expectation. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 37953051..5d98c029 100755 --- a/setup.py +++ b/setup.py @@ -117,7 +117,7 @@ class install_with_pth(install): """ suffix = os.path.relpath(self.install_lib, self.install_libbase) - if suffix == self._pth_contents: + if suffix.strip() == self._pth_contents.strip(): self.install_lib = self.install_libbase -- cgit v1.2.1 From c0085e87c69629ec3cf24dfce887c0fb93fa80dd Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 2 Sep 2020 17:41:38 -0400 Subject: Make stdlib distutils the default again. Stop the burning. Ref #2350 and others. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 34654e19..2bd48daa 100755 --- a/setup.py +++ b/setup.py @@ -100,7 +100,7 @@ class install_with_pth(install): _pth_contents = textwrap.dedent(""" import os var = 'SETUPTOOLS_USE_DISTUTILS' - enabled = os.environ.get(var, 'local') == 'local' + enabled = os.environ.get(var, 'stdlib') == 'local' enabled and __import__('_distutils_hack').add_shim() """).lstrip().replace('\n', '; ') -- cgit v1.2.1