From 949193ffe6385b4823bc954ac7e317df5403578f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Jul 2022 11:52:07 -0400 Subject: [PATCH] Add support for Homebrew on Python 3.9 instead of relying on distutils.cfg as found in the stdlib. Fixes pypa/distutils#152. --- distutils/command/_framework_compat.py | 52 ++++++++++++++++++++++++++ distutils/command/install.py | 9 ++++- 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 distutils/command/_framework_compat.py diff --git a/distutils/command/_framework_compat.py b/distutils/command/_framework_compat.py new file mode 100644 index 00000000..e032603a --- /dev/null +++ b/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/distutils/command/install.py b/distutils/command/install.py index 0660406f..7d9054e3 100644 --- a/distutils/command/install.py +++ b/distutils/command/install.py @@ -17,6 +17,7 @@ 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 @@ '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 @@ def finalize_options(self): 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()