Skip to content

Commit f4910d2

Browse files
authored
Merge pull request #10218 from uranusjr/locations-distutils-cfg-warning
2 parents a5b3e1b + 4c45c64 commit f4910d2

File tree

2 files changed

+57
-18
lines changed

2 files changed

+57
-18
lines changed

src/pip/_internal/locations/__init__.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from pip._internal.models.scheme import SCHEME_KEYS, Scheme
1010
from pip._internal.utils.compat import WINDOWS
11+
from pip._internal.utils.deprecation import deprecated
1112

1213
from . import _distutils, _sysconfig
1314
from .base import (
@@ -99,16 +100,20 @@ def _default_base(*, user: bool) -> str:
99100

100101

101102
@functools.lru_cache(maxsize=None)
102-
def _warn_if_mismatch(old: pathlib.Path, new: pathlib.Path, *, key: str) -> bool:
103-
if old == new:
104-
return False
103+
def _warn_mismatched(old: pathlib.Path, new: pathlib.Path, *, key: str) -> None:
105104
issue_url = "https://github.com/pypa/pip/issues/10151"
106105
message = (
107106
"Value for %s does not match. Please report this to <%s>"
108107
"\ndistutils: %s"
109108
"\nsysconfig: %s"
110109
)
111110
logger.log(_MISMATCH_LEVEL, message, key, issue_url, old, new)
111+
112+
113+
def _warn_if_mismatch(old: pathlib.Path, new: pathlib.Path, *, key: str) -> bool:
114+
if old == new:
115+
return False
116+
_warn_mismatched(old, new, key=key)
112117
return True
113118

114119

@@ -157,12 +162,15 @@ def get_scheme(
157162
)
158163

159164
base = prefix or home or _default_base(user=user)
160-
warned = []
165+
warning_contexts = []
161166
for k in SCHEME_KEYS:
162167
# Extra join because distutils can return relative paths.
163168
old_v = pathlib.Path(base, getattr(old, k))
164169
new_v = pathlib.Path(getattr(new, k))
165170

171+
if old_v == new_v:
172+
continue
173+
166174
# distutils incorrectly put PyPy packages under ``site-packages/python``
167175
# in the ``posix_home`` scheme, but PyPy devs said they expect the
168176
# directory name to be ``pypy`` instead. So we treat this as a bug fix
@@ -221,10 +229,38 @@ def get_scheme(
221229
if skip_sysconfig_abiflag_bug:
222230
continue
223231

224-
warned.append(_warn_if_mismatch(old_v, new_v, key=f"scheme.{k}"))
232+
warning_contexts.append((old_v, new_v, f"scheme.{k}"))
225233

226-
if any(warned):
227-
_log_context(user=user, home=home, root=root, prefix=prefix)
234+
if not warning_contexts:
235+
return old
236+
237+
# Check if this path mismatch is caused by distutils config files. Those
238+
# files will no longer work once we switch to sysconfig, so this raises a
239+
# deprecation message for them.
240+
default_old = _distutils.distutils_scheme(
241+
dist_name,
242+
user,
243+
home,
244+
root,
245+
isolated,
246+
prefix,
247+
ignore_config_files=True,
248+
)
249+
if any(default_old[k] != getattr(old, k) for k in SCHEME_KEYS):
250+
deprecated(
251+
"Configuring installation scheme with distutils config files "
252+
"is deprecated and will no longer work in the near future. If you "
253+
"are using a Homebrew or Linuxbrew Python, please see discussion "
254+
"at https://github.com/Homebrew/homebrew-core/issues/76621",
255+
replacement=None,
256+
gone_in=None,
257+
)
258+
return old
259+
260+
# Post warnings about this mismatch so user can report them back.
261+
for old_v, new_v, key in warning_contexts:
262+
_warn_mismatched(old_v, new_v, key=key)
263+
_log_context(user=user, home=home, root=root, prefix=prefix)
228264

229265
return old
230266

src/pip/_internal/locations/_distutils.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
logger = logging.getLogger(__name__)
2222

2323

24-
def _distutils_scheme(
24+
def distutils_scheme(
2525
dist_name: str,
2626
user: bool = False,
2727
home: str = None,
2828
root: str = None,
2929
isolated: bool = False,
3030
prefix: str = None,
31+
*,
32+
ignore_config_files: bool = False,
3133
) -> Dict[str, str]:
3234
"""
3335
Return a distutils install scheme
@@ -39,15 +41,16 @@ def _distutils_scheme(
3941
dist_args["script_args"] = ["--no-user-cfg"]
4042

4143
d = Distribution(dist_args)
42-
try:
43-
d.parse_config_files()
44-
except UnicodeDecodeError:
45-
# Typeshed does not include find_config_files() for some reason.
46-
paths = d.find_config_files() # type: ignore
47-
logger.warning(
48-
"Ignore distutils configs in %s due to encoding errors.",
49-
", ".join(os.path.basename(p) for p in paths),
50-
)
44+
if not ignore_config_files:
45+
try:
46+
d.parse_config_files()
47+
except UnicodeDecodeError:
48+
# Typeshed does not include find_config_files() for some reason.
49+
paths = d.find_config_files() # type: ignore
50+
logger.warning(
51+
"Ignore distutils configs in %s due to encoding errors.",
52+
", ".join(os.path.basename(p) for p in paths),
53+
)
5154
obj: Optional[DistutilsCommand] = None
5255
obj = d.get_command_obj("install", create=True)
5356
assert obj is not None
@@ -121,7 +124,7 @@ def get_scheme(
121124
:param prefix: indicates to use the "prefix" scheme and provides the
122125
base directory for the same
123126
"""
124-
scheme = _distutils_scheme(dist_name, user, home, root, isolated, prefix)
127+
scheme = distutils_scheme(dist_name, user, home, root, isolated, prefix)
125128
return Scheme(
126129
platlib=scheme["platlib"],
127130
purelib=scheme["purelib"],

0 commit comments

Comments
 (0)