Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to decide whether to use distutils or sysconfig with sysconfig._PIP_USE_SYSCONFIG #10654

Merged
merged 1 commit into from
Nov 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions news/10647.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Allow Python distributors to opt-out from or opt-in to the ``sysconfig``
hroncok marked this conversation as resolved.
Show resolved Hide resolved
installation scheme backend by setting ``sysconfig._PIP_USE_SYSCONFIG``
to ``True`` or ``False``.
17 changes: 16 additions & 1 deletion src/pip/_internal/locations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,22 @@

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

_USE_SYSCONFIG = sys.version_info >= (3, 10)

def _should_use_sysconfig() -> bool:
"""
This function determines the value of _USE_SYSCONFIG.
By default, pip uses sysconfig on Python 3.10+.
But Python distributors can override this decision by setting:
sysconfig._PIP_USE_SYSCONFIG = True / False
Rationale in https://github.com/pypa/pip/issues/10647
"""
if hasattr(sysconfig, "_PIP_USE_SYSCONFIG"):
return bool(sysconfig._PIP_USE_SYSCONFIG) # type: ignore [attr-defined]
return sys.version_info >= (3, 10)


# This is a function for testability, but should be constant during any one run.
_USE_SYSCONFIG = _should_use_sysconfig()


def _looks_like_bpo_44860() -> bool:
Expand Down
21 changes: 20 additions & 1 deletion tests/unit/test_locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import os
import shutil
import sys
import sysconfig
import tempfile
from typing import Any, Dict
from unittest.mock import Mock

import pytest

from pip._internal.locations import SCHEME_KEYS, get_scheme
from pip._internal.locations import SCHEME_KEYS, _should_use_sysconfig, get_scheme
from tests.lib.path import Path

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

def test_default_should_use_sysconfig(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.delattr(sysconfig, "_PIP_USE_SYSCONFIG", raising=False)
if sys.version_info[:2] >= (3, 10):
assert _should_use_sysconfig() is True
else:
assert _should_use_sysconfig() is False

@pytest.mark.parametrize("vendor_value", [True, False, None, "", 0, 1])
def test_vendor_overriden_should_use_sysconfig(
self, monkeypatch: pytest.MonkeyPatch, vendor_value: Any
) -> None:
monkeypatch.setattr(
sysconfig, "_PIP_USE_SYSCONFIG", vendor_value, raising=False
)
assert _should_use_sysconfig() is bool(vendor_value)


class TestDistutilsScheme:
def test_root_modifies_appropriately(self) -> None:
Expand Down