Open tlandschoff-scale opened 2 days ago
Did adding -v
(or maybe -vvv
) not provide the necessary information?
@pfmoore Obviously it can't because the information was already eaten in the _SETUPTOOLS_SHIM
. I also tried using the verbose output of pip when initially digging into this, to no avail.
Here is the output with -vvv
:
#8 0.791 Running command python setup.py egg_info
#8 0.863 ERROR: Can not execute `setup.py` since setuptools is not available in the build environment.
#8 0.882 error: subprocess-exited-with-error
#8 0.882
#8 0.882 × python setup.py egg_info did not run successfully.
#8 0.882 │ exit code: 1
#8 0.882 ╰─> See above for output.
#8 0.882
#8 0.882 note: This error originates from a subprocess, and is likely not a problem with pip.
#8 0.884 full command: /usr/local/bin/python -c '
#8 0.884 exec(compile('"'"''"'"''"'"'
#8 0.884 # This is <pip-setuptools-caller> -- a caller that pip uses to run setup.py
#8 0.884 #
#8 0.884 # - It imports setuptools before invoking setup.py, to enable projects that directly
#8 0.884 # import from `distutils.core` to work with newer packaging standards.
#8 0.884 # - It provides a clear error message when setuptools is not installed.
#8 0.884 # - It sets `sys.argv[0]` to the underlying `setup.py`, when invoking `setup.py` so
#8 0.884 # setuptools doesn'"'"'t think the script is `-c`. This avoids the following warning:
#8 0.884 # manifest_maker: standard file '"'"'-c'"'"' not found".
#8 0.884 # - It generates a shim setup.py, for handling setup.cfg-only projects.
#8 0.884 import os, sys, tokenize
#8 0.884
#8 0.884 try:
#8 0.884 import setuptools
#8 0.884 except ImportError as error:
#8 0.884 print(
#8 0.884 "ERROR: Can not execute `setup.py` since setuptools is not available in "
#8 0.884 "the build environment.",
#8 0.884 file=sys.stderr,
#8 0.884 )
#8 0.884 sys.exit(1)
#8 0.884
#8 0.884 __file__ = %r
#8 0.884 sys.argv[0] = __file__
#8 0.884
#8 0.884 if os.path.exists(__file__):
#8 0.884 filename = __file__
#8 0.884 with tokenize.open(__file__) as f:
#8 0.884 setup_py_code = f.read()
#8 0.884 else:
#8 0.884 filename = "<auto-generated setuptools caller>"
#8 0.884 setup_py_code = "from setuptools import setup; setup()"
#8 0.884
#8 0.884 exec(compile(setup_py_code, filename, "exec"))
#8 0.884 '"'"''"'"''"'"' % ('"'"'/src/setup.py'"'"',), "<pip-setuptools-caller>", "exec"))' egg_info --egg-base /tmp/pip-pip-egg-info-9743iszq
#8 0.884 cwd: /src/
#8 0.885 Preparing metadata (setup.py): finished with status 'error'
#8 0.929 Remote version of pip: 24.2
#8 0.930 Local version of pip: 24.2
#8 0.934 Was pip installed by pip? True
#8 0.938 error: metadata-generation-failed
#8 0.938
#8 0.938 × Encountered error while generating package metadata.
#8 0.938 ╰─> See above for output.
#8 0.938
#8 0.938 note: This is an issue with the package mentioned above, not pip.
#8 0.938 hint: See above for details.
#8 0.945 Exception information:
#8 0.945 Traceback (most recent call last):
#8 0.945 File "/usr/local/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_legacy.py", line 64, in generate_metadata
#8 0.945 call_subprocess(
#8 0.945 File "/usr/local/lib/python3.12/site-packages/pip/_internal/utils/subprocess.py", line 209, in call_subprocess
#8 0.945 raise error
#8 0.945 pip._internal.exceptions.InstallationSubprocessError: python setup.py egg_info exited with 1
#8 0.945
#8 0.945 The above exception was the direct cause of the following exception:
...
Ah, wait. This is in the legacy build path that uses setuptools when there's no pyproject.toml
. I'd suggest you add a pyproject.toml
to your project (specifying setuptools as the build backend). The handling (and reporting) of errors should be better in that case.
We're unlikely to do much with the legacy code path at this point, as it's been deprecated for some time.
Actually that is what we did: Add a pyproject.toml
. This fixed it for one package, but we have like 30 that are old enough to break in this way. :cry:
Still trying to find a way out of this mess, especially for allowing point releases on old release branches.
Close this if you like, my main goal was to document what might be going on here. Anyway, I think applying the trivial patch can not hurt. YMMV
Thanks. I guess the answer here is that if you don't have the resources to update your packages, you should probably be cautious about upgrading pip, as you'll find that newer versions of pip will gradually stop working with out of date packaging practices.
One thing you could try is --use-pep517
. That forces the use of the newer code path without requiring you to add a pyproject.toml
. It's something of a stopgap, as it was only ever intended as a transitional option, but it might get you out of trouble for now, at least.
Thanks for the pointer. Actually, not pip was the problem here but an updated setuptools, that actually requires a newer version of jaraco.functools.
I only created the issue here because I ran in the wrong direction due to the incomplete error information.
Kudos, Torsten
Description
tl;dr: pip hides the actual
ImportError
when importingsetuptools
, hampering diagnosis. Suggested patch below.A trivial problem in our setup lead into a lengthy search because of missing information. This can happen for legacy packages without build isolation configured via
pyproject.toml
. Consider this simplesetup.py
:Trying to pip install a package like that caused this error with pip:
Turns out that in the end, somehow
setuptools
andjaraco.functools
got incompatible in the environment, causing a lengthy error hunt. See below for how to reproduce.Suggested patch:
Other observations
Installing the same package in a fresh Python environment (which does not have setuptools at call) interestingly worked. To reproduce:
The output misled me to think that our internal package is actually using build isolation and has a
pyproject.toml
:Expected behavior
pip should expose the actual error that occurred when trying to import setuptools.
pip version
24.2
Python version
3.12.4
OS
Linux
How to Reproduce
Output
Code of Conduct