This is a truly popular question here at SO, but none of the many answers I have looked at, clearly explain what this error really mean, and why it occurs.
One source of confusion, is that when (for example) you do pip install pycparser
, you first get the error:
Failed building wheel for pycparser
which is then followed by the message that the package was:
Successfully installed pycparser-2.19
.
# pip3 install pycparser
Collecting pycparser
Using cached https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz
Building wheels for collected packages: pycparser
Running setup.py bdist_wheel for pycparser ... error
Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-g_v28hpp/pycparser/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/pip-wheel-__w_f6p0 --python-tag cp36:
Traceback (most recent call last):
File "<string>", line 1, in <module>
...
File "/usr/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2349, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
ModuleNotFoundError: No module named 'wheel.bdist_wheel'
----------------------------------------
Failed building wheel for pycparser
Running setup.py clean for pycparser
Failed to build pycparser
Installing collected packages: pycparser
Running setup.py install for pycparser ... done
Successfully installed pycparser-2.19
What is going on here?
(I would like to understand how something can fail but still get installed and whether you can trust this package functioning correctly?)
So far the best partial explanation I have found is this.
pip
doesn't find a wheel for the requirement, it downloads the source dist and tries to build a wheel from it locally. on success, the wheel is stored inpip
's cache for future reinstalls. on wheel build failure,pip
switches to the legacy installation from source dist (invokingpython setup.py install
). – Titleholderwheel
package sopip
is unable to build wheels from source dists. if you want to explicitly disable building wheels, use the--no-binary
flag:pip install somepkg --no-binary=somepkg
. Or usepip install somepkg --no-binary=:all:
, but beware that this will disable wheels for every package selected for installation, including dependencies; if there is no source dist available for some packagepip
needs to install, the installation will fail. – Titleholder--no-binary
instructs pip to only download and use source distributions. The flag to prevent it to build a local binary wheel is indeed--no-cache-dir
. – Calleanwheels
(0.32.2) so that is not the problem. But maybe thepycparser
package doesn't have a wheel (*.whl
) associated? But how can I check this a-priori? – Autoroute.tar.gz
file is there and it is the source distribution on PyPI (a wheel would have a.whl
extension) – Calleanpip install docopt --no-binary=docopt
, the output clearly states:Skipping bdist_wheel for docopt, due to binaries being disabled for it.
When turning the verbose mode on, it's clear that the installation is done viasetup.py install
. the relevant spot inpip
's sources. – Titleholder--no-cache-dir
to implicitly disable wheel building; kinda suprprising to learn that. Always thought--no-cache-dir
only ignores the local cache dir (for both reading and writing), so one can use that for rebuilding the local wheel instead of taking the cached one. Learned something new today! – Titleholderpython-src/curve25519/curve25519module.c:3:10: fatal error: Python.h: No such file or directory
. In my case the problem was fixed by installingpython-dev
: #54687040 – Outlawrypython setup.py install >& pip.log
. – Autoroute