diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2022-07-03 21:04:37 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-03 21:04:37 -0400 |
commit | db66bd02f3cbab129b5b44e9b487597c75601ade (patch) | |
tree | 2cf2e8594e0f94026409732227eafd5d58cfad9f | |
parent | 120d9270c50a07caad0c697ca1f4b865226dde99 (diff) | |
parent | cd62fb6f7c4fc9df6407a0edb23231e39a7954ed (diff) | |
download | python-setuptools-git-db66bd02f3cbab129b5b44e9b487597c75601ade.tar.gz |
Merge pull request #3430 from pypa/feature/distutils-152c13d
Merge with pypa/distutils@152c13d
-rw-r--r-- | changelog.d/3430.change.rst | 1 | ||||
-rw-r--r-- | setuptools/_distutils/command/_framework_compat.py | 52 | ||||
-rw-r--r-- | setuptools/_distutils/command/build_py.py | 7 | ||||
-rw-r--r-- | setuptools/_distutils/command/install.py | 9 | ||||
-rw-r--r-- | setuptools/_distutils/cygwinccompiler.py | 19 | ||||
-rw-r--r-- | setuptools/_distutils/tests/test_build_py.py | 42 | ||||
-rw-r--r-- | setuptools/_distutils/tests/test_cygwinccompiler.py | 6 |
7 files changed, 128 insertions, 8 deletions
diff --git a/changelog.d/3430.change.rst b/changelog.d/3430.change.rst new file mode 100644 index 00000000..10bf768c --- /dev/null +++ b/changelog.d/3430.change.rst @@ -0,0 +1 @@ +Merge with pypa/distutils@152c13d including pypa/distutils#155 (improved compatibility for editable installs on homebrew Python 3.9), pypa/distutils#150 (better handling of runtime_library_dirs on cygwin), and pypa/distutils#151 (remove warnings for namespace packages). diff --git a/setuptools/_distutils/command/_framework_compat.py b/setuptools/_distutils/command/_framework_compat.py new file mode 100644 index 00000000..e032603a --- /dev/null +++ b/setuptools/_distutils/command/_framework_compat.py @@ -0,0 +1,52 @@ +""" +Backward compatibility for homebrew builds on macOS. +""" + + +import sys +import os +import functools +import subprocess + + +@functools.lru_cache() +def enabled(): + """ + Only enabled for Python 3.9 framework builds except ensurepip and venv. + """ + PY39 = (3, 9) < sys.version_info < (3, 10) + framework = sys.platform == 'darwin' and sys._framework + venv = sys.prefix != sys.base_prefix + ensurepip = os.environ.get("ENSUREPIP_OPTIONS") + return PY39 and framework and not venv and not ensurepip + + +schemes = dict( + osx_framework_library=dict( + stdlib='{installed_base}/{platlibdir}/python{py_version_short}', + platstdlib='{platbase}/{platlibdir}/python{py_version_short}', + purelib='{homebrew_prefix}/lib/python{py_version_short}/site-packages', + platlib='{homebrew_prefix}/{platlibdir}/python{py_version_short}/site-packages', + include='{installed_base}/include/python{py_version_short}{abiflags}', + platinclude='{installed_platbase}/include/python{py_version_short}{abiflags}', + scripts='{homebrew_prefix}/bin', + data='{homebrew_prefix}', + ) +) + + +@functools.lru_cache() +def vars(): + if not enabled(): + return {} + homebrew_prefix = subprocess.check_output(['brew', '--prefix'], text=True).strip() + return locals() + + +def scheme(name): + """ + Override the selected scheme for posix_prefix. + """ + if not enabled() or not name.endswith('_prefix'): + return name + return 'osx_framework_library' diff --git a/setuptools/_distutils/command/build_py.py b/setuptools/_distutils/command/build_py.py index 1b22004e..7723d359 100644 --- a/setuptools/_distutils/command/build_py.py +++ b/setuptools/_distutils/command/build_py.py @@ -201,16 +201,11 @@ class build_py(Command): "but is not a directory" % package_dir ) - # Require __init__.py for all but the "root package" + # Directories without __init__.py are namespace packages (PEP 420). if package: init_py = os.path.join(package_dir, "__init__.py") if os.path.isfile(init_py): return init_py - else: - log.warn( - ("package init file '%s' not found " + "(or not a regular file)"), - init_py, - ) # Either not in a package at all (__init__.py not expected), or # __init__.py doesn't exist -- so don't return the filename. diff --git a/setuptools/_distutils/command/install.py b/setuptools/_distutils/command/install.py index 0660406f..7d9054e3 100644 --- a/setuptools/_distutils/command/install.py +++ b/setuptools/_distutils/command/install.py @@ -17,6 +17,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 . import _framework_compat as fw from .. import _collections from site import USER_BASE @@ -82,6 +83,10 @@ if HAS_USER_SITE: 'data': '{userbase}', } + +INSTALL_SCHEMES.update(fw.schemes) + + # The keys to an installation scheme; if any new types of files are to be # installed, be sure to add an entry to every installation scheme above, # and to SCHEME_KEYS here. @@ -136,7 +141,7 @@ def _resolve_scheme(name): try: resolved = sysconfig.get_preferred_scheme(key) except Exception: - resolved = _pypy_hack(name) + resolved = fw.scheme(_pypy_hack(name)) return resolved @@ -426,7 +431,7 @@ class install(Command): local_vars['usersite'] = self.install_usersite self.config_vars = _collections.DictStack( - [compat_vars, sysconfig.get_config_vars(), local_vars] + [fw.vars(), compat_vars, sysconfig.get_config_vars(), local_vars] ) self.expand_basedirs() diff --git a/setuptools/_distutils/cygwinccompiler.py b/setuptools/_distutils/cygwinccompiler.py index 931b3661..445e2e51 100644 --- a/setuptools/_distutils/cygwinccompiler.py +++ b/setuptools/_distutils/cygwinccompiler.py @@ -58,6 +58,7 @@ from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import ( DistutilsExecError, + DistutilsPlatformError, CCompilerError, CompileError, UnknownFileError, @@ -197,6 +198,12 @@ class CygwinCCompiler(UnixCCompiler): libraries = copy.copy(libraries or []) objects = copy.copy(objects or []) + if runtime_library_dirs: + self.warn( + "I don't know what to do with 'runtime_library_dirs': " + + str(runtime_library_dirs) + ) + # Additional libraries libraries.extend(self.dll_libraries) @@ -265,6 +272,13 @@ class CygwinCCompiler(UnixCCompiler): target_lang, ) + def runtime_library_dir_option(self, dir): + # cygwin doesn't support rpath. While in theory we could error + # out like MSVC does, code might expect it to work like on Unix, so + # just warn and hope for the best. + self.warn("don't know how to set runtime library search path on Windows") + return [] + # -- Miscellaneous methods ----------------------------------------- def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): @@ -325,6 +339,11 @@ class Mingw32CCompiler(CygwinCCompiler): # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() + def runtime_library_dir_option(self, dir): + raise DistutilsPlatformError( + "don't know how to set runtime library search path on Windows" + ) + # Because these compilers aren't configured in Python's pyconfig.h file by # default, we should at least warn the user if he is using an unmodified diff --git a/setuptools/_distutils/tests/test_build_py.py b/setuptools/_distutils/tests/test_build_py.py index 4585d799..eb01d81a 100644 --- a/setuptools/_distutils/tests/test_build_py.py +++ b/setuptools/_distutils/tests/test_build_py.py @@ -7,6 +7,7 @@ import unittest from distutils.command.build_py import build_py from distutils.core import Distribution from distutils.errors import DistutilsFileError +from unittest.mock import patch from distutils.tests import support from test.support import run_unittest @@ -167,6 +168,47 @@ class BuildPyTestCase( self.assertIn('byte-compiling is disabled', self.logs[0][1] % self.logs[0][2]) + @patch("distutils.command.build_py.log.warn") + def test_namespace_package_does_not_warn(self, log_warn): + """ + Originally distutils implementation did not account for PEP 420 + and included warns for package directories that did not contain + ``__init__.py`` files. + After the acceptance of PEP 420, these warnings don't make more sense + so we want to ensure there are not displayed to not confuse the users. + """ + # Create a fake project structure with a package namespace: + tmp = self.mkdtemp() + os.chdir(tmp) + os.makedirs("ns/pkg") + open("ns/pkg/module.py", "w").close() + + # Set up a trap if the undesirable effect is observed: + def _trap(msg, *args): + if "package init file" in msg and "not found" in msg: + raise AssertionError(f"Undesired warning: {msg!r} {args!r}") + + log_warn.side_effect = _trap + + # Configure the package: + attrs = { + "name": "ns.pkg", + "packages": ["ns", "ns.pkg"], + "script_name": "setup.py", + } + dist = Distribution(attrs) + + # Run code paths that would trigger the trap: + cmd = dist.get_command_obj("build_py") + cmd.finalize_options() + modules = cmd.find_all_modules() + assert len(modules) == 1 + module_path = modules[0][-1] + assert module_path.replace(os.sep, "/") == "ns/pkg/module.py" + + cmd.run() + # Test should complete successfully with no exception + def test_suite(): return unittest.TestLoader().loadTestsFromTestCase(BuildPyTestCase) diff --git a/setuptools/_distutils/tests/test_cygwinccompiler.py b/setuptools/_distutils/tests/test_cygwinccompiler.py index b3c164ed..7760436a 100644 --- a/setuptools/_distutils/tests/test_cygwinccompiler.py +++ b/setuptools/_distutils/tests/test_cygwinccompiler.py @@ -48,6 +48,12 @@ class CygwinCCompilerTestCase(support.TempdirManager, unittest.TestCase): self.assertTrue(os.path.exists(linkable_file)) self.assertEquals(linkable_file, "/usr/lib/lib{:s}.dll.a".format(link_name)) + @unittest.skipIf(sys.platform != "cygwin", "Not running on Cygwin") + def test_runtime_library_dir_option(self): + from distutils.cygwinccompiler import CygwinCCompiler + compiler = CygwinCCompiler() + self.assertEqual(compiler.runtime_library_dir_option('/foo'), []) + def test_check_config_h(self): # check_config_h looks for "GCC" in sys.version first |