Skip to content

importing pip at runtime breaks Setuptools' distutils hack #978

@jaraco

Description

@jaraco

In jaraco/jaraco.develop#31 (comment), I learned that the pip outer detection is causing problems with the distutils hack.

build/src/build/env.py

Lines 156 to 176 in cc2d642

@functools.cached_property
def _has_valid_outer_pip(self) -> bool | None:
"""
This checks for a valid global pip. Returns None if pip is missing, False
if pip is too old, and True if it can be used.
"""
# Version to have added the `--python` option.
if not _has_dependency('pip', '22.3'): # pragma: no cover
return False
# `pip install --python` is nonfunctional on Gentoo debundled pip.
# Detect that by checking if pip._vendor` module exists. However,
# searching for pip could yield warnings from _distutils_hack,
# so silence them.
with warnings.catch_warnings():
warnings.simplefilter('ignore')
if importlib.util.find_spec('pip._vendor') is None:
return False # pragma: no cover
return True

By importing pip._vendor, build is triggering the condition that the distutils_hack uses to infer that it's running under pip (and thus should disable itself per pypa/pip#8761). Later, when setuptools is imported, it fails its assertion that distutils should be loaded locally. See the aforementioned comment for more details.

I'm trying to figure out the right fix here.

For years, Setuptools has been able to rely on the import of pip modules to detect if pip is running or not, but now that build is importing pip, it's breaking that assumption. With 35d86b8, that's no longer the case.

I can imagine how Setuptools could add additional detection logic to avoid disabling its behavior when build is importing pip, but even if I released that change today, it'll take some time to work through the ecosystem (e.g. show up in virtualenv).

My instinct is that build is violating packaging expectations, as pip is never meant to be imported, but by searching for the spec for pip._vendor, it's implicitly importing pip. But also, I can't think of a better way to honor the Gentoo use-case (#861).

What do you think, @henryiii ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions