pip install . suddenly started failing for many packages. Since setuptools just got a new version and pip didn't, and setuptools appears in the error, I'm guessing it's related to setuptools 50. Apologies if this turns out to be wrong.
This can be seen in any number of repositories, such as https://github.com/dHannasch/tox-sitepackages-example.
This doesn't appear to be quite the same as https://github.com/pypa/setuptools/issues/2352.
I don't fully understand all the implications of https://github.com/pypa/setuptools/issues/2350, but SETUPTOOLS_USE_DISTUTILS=stdlib has no effect on this (ditto SETUPTOOLS_USE_DISTUTILS=1), so I think this is a separate issue.
Travis log:
$ python -m pip install .
Processing /home/travis/build/dHannasch/tox-sitepackages-example
Installing build dependencies ... \/done
Getting requirements to build wheel ... done
ERROR: Exception:
Traceback (most recent call last):
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/cli/base_command.py", line 216, in _main
status = self.run(options, args)
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/cli/req_command.py", line 182, in wrapper
return func(self, options, args)
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 325, in run
reqs, check_supported_wheels=not options.target_dir
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/resolution/legacy/resolver.py", line 183, in resolve
discovered_reqs.extend(self._resolve_one(requirement_set, req))
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/resolution/legacy/resolver.py", line 388, in _resolve_one
abstract_dist = self._get_abstract_dist_for(req_to_install)
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/resolution/legacy/resolver.py", line 340, in _get_abstract_dist_for
abstract_dist = self.preparer.prepare_linked_requirement(req)
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/operations/prepare.py", line 483, in prepare_linked_requirement
req, self.req_tracker, self.finder, self.build_isolation,
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/operations/prepare.py", line 91, in _get_prepared_distribution
abstract_dist.prepare_distribution_metadata(finder, build_isolation)
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/distributions/sdist.py", line 38, in prepare_distribution_metadata
self._setup_isolation(finder)
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_internal/distributions/sdist.py", line 96, in _setup_isolation
reqs = backend.get_requires_for_build_wheel()
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py", line 161, in get_requires_for_build_wheel
'config_settings': config_settings
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py", line 265, in _call_hook
raise BackendUnavailable(data.get('traceback', ''))
pip._vendor.pep517.wrappers.BackendUnavailable: Traceback (most recent call last):
File "/home/travis/build/dHannasch/tox-sitepackages-example/py38/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py", line 86, in _build_backend
obj = import_module(mod_path)
File "/opt/python/3.7.1/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/opt/python/3.7.1/lib/python3.7/site-packages/setuptools/__init__.py", line 5, in <module>
import distutils.core
File "/tmp/pip-build-env-co0toouh/overlay/lib/python3.7/site-packages/_distutils_hack/__init__.py", line 82, in create_module
return importlib.import_module('._distutils', 'setuptools')
File "/opt/python/3.7.1/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
ModuleNotFoundError: No module named 'setuptools._distutils'
This one doesn't happen for every package, I haven't quite narrowed it down but I think it's related to having a pyproject.toml or setup_requires, but that might only be because having a build environment is what causes setuptools 50 to be installed in the first place.
I had same issue. Removing pyproject.toml from the library which failed to install pass through it
That's true, and a useful workaround, but I think that's just because with no pyproject.toml, setuptools 50 doesn't get installed in the first place.
So anyone can avoid this problem for now by specifying setuptools<50 in their pyproject.toml, but the fact that that works probably isn't relevant for debugging setuptools, sadly. Oh well.
E.g.
[build-system]
requires = [
"setuptools>=30.3.0,<50",
"wheel",
"pytest-runner",
"setuptools_scm>=3.3.1",
]
So, setuptools 50.0 is fundamentally broken and breaks the entire Python ecosystem – both open-source and not. Well, isn't that special. Heads need rolling (especially those currently attached to the still-functioning torsos of managerial project leads). Until the community tastes sweet vengeance, the following is a slightly saner solution than @dHannasch's excellent starting point:
[build-system]
requires = [
"setuptools!=50.0",
"wheel",
]
That is to say, downstream projects should probably only blacklist the specific version of setuptools known to catastrophically fail under the fairly safe assumption that the next stable release will either hopefully revert or perhaps even correctly fix the breakage.
I can confirm the above circumvention behaves as expected in a project just maliciously blind-sided by this packaging horror show. Passing tox-based tests or it didn't happen, of course.
Die, setuptools 50.0! Die! :drop_of_blood:
How to resolve this issue? please give us at least a temporary solution.
@shakthifuture Setting environment variable SETUPTOOLS_USE_DISTUTILS=stdlib is a workaround, e.g.:
$ export SETUPTOOLS_USE_DISTUTILS=stdlib
$ pip3 install […]
@simmel thank you, it working.
I'm unable to replicate the reported issue. When I attempt to install the reported package, it fails to install on another dependency:
~ $ pip-run git+https://github.com/dHannasch/tox-sitepackages-example
Collecting git+https://github.com/dHannasch/tox-sitepackages-example
Cloning https://github.com/dHannasch/tox-sitepackages-example to /private/var/folders/qs/5jptvz2x7_gblx4kc3qj005800n8zm/T/pip-req-build-zqwijlld
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting click
Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
ERROR: Could not find a version that satisfies the requirement detectron2 (from tox-sitepackages-example==0.0.1.dev15) (from versions: none)
ERROR: No matching distribution found for detectron2 (from tox-sitepackages-example==0.0.1.dev15)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/bin/pip-run", line 10, in <module>
sys.exit(run())
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pip_run/__init__.py", line 18, in run
with deps.load(*deps.not_installed(pip_args)) as home:
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 113, in __enter__
return next(self.gen)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pip_run/deps.py", line 52, in load
_installable(args) and subprocess.check_call(cmd)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/subprocess.py", line 364, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '('/Library/Frameworks/Python.framework/Versions/3.8/bin/python3.8', '-m', 'pip', 'install', '-t', '/var/folders/qs/5jptvz2x7_gblx4kc3qj005800n8zm/T/pip-run-1ued9qw2', 'git+https://github.com/dHannasch/tox-sitepackages-example')' returned non-zero exit status 1.
Is there an example I could follow to replicate the failure?
I've confirmed that setuptools 50 isn't strictly implicated. The tempora project uses a similar pyproject.toml and building it from source on Setuptools 50 works fine:
draft $ pip-run -q setuptools==50 -- -m pip-run --no-binary :all: tempora
Collecting tempora
Using cached tempora-4.0.0.tar.gz (47 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting jaraco.functools>=1.20
Using cached jaraco.functools-3.0.1.tar.gz (16 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting pytz
Using cached pytz-2020.1.tar.gz (311 kB)
Collecting more-itertools
Using cached more-itertools-8.5.0.tar.gz (86 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Skipping wheel build for pytz, due to binaries being disabled for it.
Building wheels for collected packages: tempora, jaraco.functools, more-itertools
Building wheel for tempora (PEP 517) ... done
Created wheel for tempora: filename=tempora-4.0.0-py3-none-any.whl size=14543 sha256=fd76c8109f80e78da6acd5120ffb4ef2205383ce00566f183fcca6108c1737be
Stored in directory: /Users/jaraco/Library/Caches/pip/wheels/de/73/95/5e7770fb0490fd6999ae7c4d1479fff7c179a3a9ee4389dec9
Building wheel for jaraco.functools (PEP 517) ... done
Created wheel for jaraco.functools: filename=jaraco.functools-3.0.1-py3-none-any.whl size=6716 sha256=5823cc422ea45a8d33396d23de223b7a5420ad965935770c3f2daa6a1da22264
Stored in directory: /Users/jaraco/Library/Caches/pip/wheels/1f/c1/05/44ca6985d8e7c479c8074846f609769a77ccd275193bddc3b2
Building wheel for more-itertools (PEP 517) ... done
Created wheel for more-itertools: filename=more_itertools-8.5.0-py3-none-any.whl size=40626 sha256=b02870ffc1ec4b5a462c576f1c0b79683c65d774ec8013264184f96d03531d19
Stored in directory: /Users/jaraco/Library/Caches/pip/wheels/89/6c/f0/c53ee96fbb1ef463ac154481e99ce2146921078d30845a89b3
Successfully built tempora jaraco.functools more-itertools
Installing collected packages: more-itertools, jaraco.functools, pytz, tempora
Running setup.py install for pytz ... done
Successfully installed jaraco.functools-3.0.1 more-itertools-8.5.0 pytz-2020.1 tempora-4.0.0
>>> Python 3.8.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
^D
The error message ModuleNotFoundError: No module named 'setuptools._distutils' suggests to me that there's some condition under which an older version of setuptools (earlier than 48) is present, but somehow the distutils hack is also present.
Please let me know what steps might be needed to create the environment in which your builds fail. If possible, put them together in a Dockerfile (preferred) or script that reproduces the issue. Thanks.
This Dockerfile is somewhat convoluted, but this is the simplest way I've found to reproduce this problem so far:
FROM ubuntu:20.04
WORKDIR /root
RUN apt-get update && \
apt-get install python3-dev python3-setuptools python3-venv python3-wheel gcc \
libssl-dev libffi-dev -y && \
python3 -m venv --system-site-packages venv
ENV PATH /root/venv/bin:$PATH
RUN pip install --no-binary=:all: cryptography
EDIT: The installation succeeds if you set SETUPTOOLS_USE_DISTUTILS=stdlib
I've been able to consistently reproduce this with a virtualenv created with --system-site-packages where setuptools < 50 is installed in the system site packages directory. I filed https://github.com/pypa/virtualenv/issues/1934 for it ~because the behavior differs between virtualenv and venv~. Update: Scratch that, after seeing https://github.com/pypa/setuptools/issues/2353#issuecomment-685177014 I tried reproducing it with venv instead of virtualenv again and succeeded, so it's not in any way specific to virtualenv as opposed to venv. In any event the reproduction test case from that issue should still be useful.
Clearly there is some case where an isolated build isn't being properly isolated, and it's managing to pick up a different setuptools than the one that was installed for the isolated build.
OK - I'm in no way an expert on PEP-517, but I think the bug here is in pip, not setuptools - or maybe there's one bug in each.
If a pyproject.toml contains something like:
[build-system]
requires = ["setuptools"]
then pip installs the latest version of setuptools into a temp directory with a name like (for instance):
/tmp/pip-build-env-5v90m1w9/overlay/lib/python3.8/site-packages
After it does that, it eventually calls the get_requires_for_build_wheel hook, in a new subprocess. In that subprocess, if pip was run inside a virtualenv created with --system-site-packages, then sys.path is something like:
['/home/matt/some_venv/lib/python3.8/site-packages/pip/_vendor/pep517',
'/tmp/pip-build-env-5v90m1w9/site',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/usr/local/lib/python3.8/dist-packages',
'/usr/lib/python3/dist-packages',
'/tmp/pip-build-env-5v90m1w9/overlay/lib/python3.8/site-packages',
'/tmp/pip-build-env-5v90m1w9/normal/lib/python3.8/site-packages']
The overlay directory is _after_ the system site packages directory, which means that any build dependencies installed by pip because they were required by the pyproject.toml are later in the search path than the ones that were already installed in the site-packages directory.
I think there's one bug in each here: the _distutils_hack probably shouldn't do anything if there's a _different_ setuptools ahead of it in sys.path - whichever setuptools is earliest in the module search path should be completely responsible for everything; a .pth file from later in the search path shouldn't be screwing it up. And, pip probably shouldn't be calling the hook in an environment where already-installed modules are taking precedence over modules specifically required by the pyproject.toml - the whole point of an isolated build is to isolate you from what's installed system-wide.
There is, in fact, an old pip issue for exactly this bug. https://github.com/pypa/pip/issues/6264#issuecomment-685230919.
Yeah, we've had a suspicion about the pip as well. We then tried downgrading to v18.1 and it worked here!
FYI, the AWS lambdas running Python were also broken.
Follow this temporary workaround https://stackoverflow.com/questions/63683262/modulenotfounderror-no-module-named-setuptools-distutils/63683921#63683921
I was able to replicate the error without venv and with a simple python-only package:
FROM jaraco/multipy-tox
RUN pip install 'setuptools<40'
ENV SETUPTOOLS_USE_DISTUTILS local
RUN pip install --no-binary=:all: tempora
It replicates very similar conditions as those reported in this comment.
The issue doesn't require venv. The issue can be replicated with this Dockerfile:
FROM ubuntu:focal
RUN apt update
RUN apt upgrade -y
RUN apt install -y python3.8 python3.8-distutils wget
RUN ln -s $(which python3.8) /usr/local/bin/python
RUN wget -q https://bootstrap.pypa.io/get-pip.py
RUN python3.8 get-pip.py
RUN pip install -U pip
RUN pip install 'setuptools<40'
ENV SETUPTOOLS_USE_DISTUTILS local
RUN pip install --no-binary=:all: tempora
Thanks for finding the issue in pip. The issue seems to be entirely a manifestation of incomplete isolation and conflicting setuptools versions. I'll close this issue in favor of addressing the root cause in pip (pypa/pip#6264).
For me this issue is fixed in setuptools 50.1, see PR #2376.
I had same issue. Removing pyproject.toml from the library which failed to install pass through it
man you've just saved my life :smile:
Most helpful comment
@shakthifuture Setting environment variable
SETUPTOOLS_USE_DISTUTILS=stdlibis a workaround, e.g.: