Skip to content

Commit

Permalink
Use posix_prefix for Apple's system Python
Browse files Browse the repository at this point in the history
  • Loading branch information
uranusjr committed Aug 6, 2021
1 parent 3ecc391 commit 41a8442
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/pip/_internal/locations/_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@


# Notes on _infer_* functions.
# Unfortunately ``_get_default_scheme()`` is private, so there's no way to
# ask things like "what is the '_prefix' scheme on this platform". These
# Unfortunately ``get_default_scheme()`` didn't exist before 3.10, so there's no
# way to ask things like "what is the '_prefix' scheme on this platform". These
# functions try to answer that with some heuristics while accounting for ad-hoc
# platforms not covered by CPython's default sysconfig implementation. If the
# ad-hoc implementation does not fully implement sysconfig, we'll fall back to
Expand All @@ -27,6 +27,32 @@
_PREFERRED_SCHEME_API = getattr(sysconfig, "get_preferred_scheme", None)


def _should_use_osx_framework_prefix() -> bool:
"""Check for Apple's ``osx_framework_library`` scheme.
Python distributed by Apple's Command Line Tools has this special scheme
that's used when:
* This is a framework build.
* We are installing into the system prefix.
This does not account for ``pip install --prefix`` (also means we're not
installing to the system prefix), which should use ``posix_prefix``, but
logic here means ``_infer_prefix()`` outputs ``osx_framework_library``. But
since ``prefix`` is not available for ``sysconfig.get_default_scheme()``,
which is the stdlib replacement for ``_infer_prefix()``, presumably Apple
wouldn't be able to magically switch between ``osx_framework_library`` and
``posix_prefix``. ``_infer_prefix()`` returning ``osx_framework_library``
means its behavior is consistent whether we use the stdlib implementation
or our own, and we deal with this special case in ``get_scheme()`` instead.
"""
return (
"osx_framework_library" in _AVAILABLE_SCHEMES
and not running_under_virtualenv()
and is_osx_framework()
)


def _infer_prefix() -> str:
"""Try to find a prefix scheme for the current platform.
Expand All @@ -43,8 +69,7 @@ def _infer_prefix() -> str:
"""
if _PREFERRED_SCHEME_API:
return _PREFERRED_SCHEME_API("prefix")
os_framework_global = is_osx_framework() and not running_under_virtualenv()
if os_framework_global and "osx_framework_library" in _AVAILABLE_SCHEMES:
if _should_use_osx_framework_prefix():
return "osx_framework_library"
implementation_suffixed = f"{sys.implementation.name}_{os.name}"
if implementation_suffixed in _AVAILABLE_SCHEMES:
Expand Down Expand Up @@ -130,6 +155,12 @@ def get_scheme(
else:
scheme_name = _infer_prefix()

# Special case: When installing into a custom prefix, use posix_prefix
# instead of osx_framework_library. See _should_use_osx_framework_prefix()
# docstring for details.
if prefix is not None and scheme_name == "osx_framework_library":
scheme_name = "posix_prefix"

if home is not None:
variables = {k: home for k in _HOME_KEYS}
elif prefix is not None:
Expand Down

0 comments on commit 41a8442

Please sign in to comment.