Skip to content

Commit 85db549

Browse files
committed
Allow to decide whether to use distutils or sysconfig with sysconfig._PIP_USE_SYSCONFIG
Fixes #10647
1 parent 4cdb516 commit 85db549

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

news/10647.feature.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Allow Python distributors to opt-out from or opt-in to the ``sysconfig``
2+
installation scheme backend by setting ``sysconfig._PIP_USE_SYSCONFIG``
3+
to ``True`` or ``False``.

src/pip/_internal/locations/__init__.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,22 @@
4545

4646
_PLATLIBDIR: str = getattr(sys, "platlibdir", "lib")
4747

48-
_USE_SYSCONFIG = sys.version_info >= (3, 10)
48+
49+
def _should_use_sysconfig() -> bool:
50+
"""
51+
This function determines the value of _USE_SYSCONFIG.
52+
By default, pip uses sysconfig on Python 3.10+.
53+
But Python distributors can override this decision by setting:
54+
sysconfig._PIP_USE_SYSCONFIG = True / False
55+
Rationale in https://github.com/pypa/pip/issues/10647
56+
"""
57+
if hasattr(sysconfig, "_PIP_USE_SYSCONFIG"):
58+
return bool(sysconfig._PIP_USE_SYSCONFIG) # type: ignore [attr-defined]
59+
return sys.version_info >= (3, 10)
60+
61+
62+
# This is a function for testability, but should be constant during any one run.
63+
_USE_SYSCONFIG = _should_use_sysconfig()
4964

5065

5166
def _looks_like_bpo_44860() -> bool:

tests/unit/test_locations.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
import os
77
import shutil
88
import sys
9+
import sysconfig
910
import tempfile
1011
from typing import Any, Dict
1112
from unittest.mock import Mock
1213

1314
import pytest
1415

15-
from pip._internal.locations import SCHEME_KEYS, get_scheme
16+
from pip._internal.locations import SCHEME_KEYS, _should_use_sysconfig, get_scheme
1617
from tests.lib.path import Path
1718

1819
if sys.platform == "win32":
@@ -82,6 +83,24 @@ def get_mock_getpwuid(self, uid: int) -> pwd.struct_passwd:
8283
result.pw_name = self.username
8384
return result
8485

86+
def test_default_should_use_sysconfig(
87+
self, monkeypatch: pytest.MonkeyPatch
88+
) -> None:
89+
monkeypatch.delattr(sysconfig, "_PIP_USE_SYSCONFIG", raising=False)
90+
if sys.version_info[:2] >= (3, 10):
91+
assert _should_use_sysconfig() is True
92+
else:
93+
assert _should_use_sysconfig() is False
94+
95+
@pytest.mark.parametrize("vendor_value", [True, False, None, "", 0, 1])
96+
def test_vendor_overriden_should_use_sysconfig(
97+
self, monkeypatch: pytest.MonkeyPatch, vendor_value: Any
98+
) -> None:
99+
monkeypatch.setattr(
100+
sysconfig, "_PIP_USE_SYSCONFIG", vendor_value, raising=False
101+
)
102+
assert _should_use_sysconfig() is bool(vendor_value)
103+
85104

86105
class TestDistutilsScheme:
87106
def test_root_modifies_appropriately(self) -> None:

0 commit comments

Comments
 (0)