Skip to content

Commit 92921f9

Browse files
committed
Suppress location warning on abiflag differences
1 parent c106a03 commit 92921f9

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

src/pip/_internal/locations/__init__.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import pathlib
55
import sys
66
import sysconfig
7-
from typing import List, Optional
7+
from typing import Dict, Iterator, List, Optional, Tuple
88

99
from pip._internal.models.scheme import SCHEME_KEYS, Scheme
10+
from pip._internal.utils.compat import WINDOWS
1011

1112
from . import _distutils, _sysconfig
1213
from .base import (
@@ -41,30 +42,53 @@
4142
_MISMATCH_LEVEL = logging.WARNING
4243

4344

45+
def _looks_like_red_hat_patched_platlib_purelib(scheme: Dict[str, str]) -> bool:
46+
platlib = scheme["platlib"]
47+
if "/lib64/" not in platlib:
48+
return False
49+
unpatched = platlib.replace("/lib64/", "/lib/")
50+
return unpatched.replace("$platbase/", "$base/") == scheme["purelib"]
51+
52+
4453
@functools.lru_cache(maxsize=None)
4554
def _looks_like_red_hat_patched() -> bool:
4655
"""Red Hat patches platlib in unix_prefix and unix_home, but not purelib.
4756
4857
This is the only way I can see to tell a Red Hat-patched Python.
4958
"""
50-
from distutils.command.install import INSTALL_SCHEMES as SCHEMES
59+
from distutils.command.install import INSTALL_SCHEMES # type: ignore
5160

52-
return (
53-
k in SCHEMES
54-
and "lib64" in SCHEMES[k]["platlib"]
55-
and SCHEMES[k]["platlib"].replace("lib64", "lib") == SCHEMES[k]["purelib"]
61+
return all(
62+
k in INSTALL_SCHEMES
63+
and _looks_like_red_hat_patched_platlib_purelib(INSTALL_SCHEMES[k])
5664
for k in ("unix_prefix", "unix_home")
5765
)
5866

5967

6068
@functools.lru_cache(maxsize=None)
6169
def _looks_like_debian_patched() -> bool:
6270
"""Debian adds two additional schemes."""
63-
from distutils.command.install import INSTALL_SCHEMES
71+
from distutils.command.install import INSTALL_SCHEMES # type: ignore
6472

6573
return "deb_system" in INSTALL_SCHEMES and "unix_local" in INSTALL_SCHEMES
6674

6775

76+
def _fix_abiflags(parts: Tuple[str]) -> Iterator[str]:
77+
ldversion = sysconfig.get_config_var("LDVERSION")
78+
abiflags: str = getattr(sys, "abiflags", None)
79+
80+
# LDVERSION does not end with sys.abiflags. Just return the path unchanged.
81+
if not ldversion or not abiflags or not ldversion.endswith(abiflags):
82+
yield from parts
83+
return
84+
85+
# Strip sys.abiflags from LDVERSION-based path components.
86+
for part in parts:
87+
if part.endswith(ldversion):
88+
part = part[: (0 - len(abiflags))]
89+
yield part
90+
91+
6892
def _default_base(*, user: bool) -> str:
6993
if user:
7094
base = sysconfig.get_config_var("userbase")
@@ -177,14 +201,26 @@ def get_scheme(
177201
# instead of site-packages, but the /usr/local check should cover it.
178202
skip_linux_system_special_case = (
179203
not (user or home or prefix)
180-
and old_v.parts[1:3] == ("user", "local")
204+
and old_v.parts[1:3] == ("usr", "local")
205+
and len(new_v.parts) > 1
181206
and new_v.parts[1] == "usr"
182-
and new_v.parts[2] != "local"
207+
and (len(new_v.parts) < 3 or new_v.parts[2] != "local")
183208
and (_looks_like_red_hat_patched() or _looks_like_debian_patched())
184209
)
185210
if skip_linux_system_special_case:
186211
continue
187212

213+
# On Python 3.7 and earlier, sysconfig does not include sys.abiflags in
214+
# the "pythonX.Y" part of the path, but distutils does.
215+
skip_sysconfig_abiflag_bug = (
216+
sys.version_info < (3, 8)
217+
and not WINDOWS
218+
and k in ("headers", "platlib", "purelib")
219+
and tuple(_fix_abiflags(old_v.parts)) == new_v.parts
220+
)
221+
if skip_sysconfig_abiflag_bug:
222+
continue
223+
188224
warned.append(_warn_if_mismatch(old_v, new_v, key=f"scheme.{k}"))
189225

190226
if any(warned):

src/pip/_internal/locations/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import os
23
import site
34
import sys
@@ -46,5 +47,6 @@ def get_src_prefix() -> str:
4647
user_site = site.USER_SITE
4748

4849

50+
@functools.lru_cache(maxsize=None)
4951
def is_osx_framework() -> bool:
5052
return bool(sysconfig.get_config_var("PYTHONFRAMEWORK"))

0 commit comments

Comments
 (0)