coleifer / pysqlite3

SQLite3 DB-API 2.0 driver from Python 3, packaged separately, with improvements
zlib License
192 stars 53 forks source link

Installation with `pip` succeeds with a failed build when using legacy installation #45

Closed SnoopJ closed 1 year ago

SnoopJ commented 1 year ago

NOTE: I am filing this issue on behalf of a user who asked for help with this bug in #python on the Libera.chat IRC network

When installing pysqlite3 with a pip that will invoke setup.py directly (i.e. in an environment that does not provide wheel), the exception handler in setup.py will swallow any exception that occurs during a failed build, and the installation will succeed in error, leaving the user scratching their head wondering why the "successful" installation is not functional.

Worse yet, even when the build failure is reported, the reason for the failure is not reported.

Reproduction

An easy way to reproduce this issue is to try to install pysqlite3 in an environment that does not have the necessary headers. Here's a sequence that reproduces the issue in a fresh ubuntu:20.04 Docker image:

$ apt update && apt install python3 python3-pip
# ...
$ python3 -m pip install pysqlite3
Collecting pysqlite3
  Downloading pysqlite3-0.4.8.tar.gz (40 kB)
     |████████████████████████████████| 40 kB 769 kB/s 
Building wheels for collected packages: pysqlite3
  Building wheel for pysqlite3 (setup.py) ... done
  WARNING: Legacy build of wheel for 'pysqlite3' created no files.
  Command arguments: /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-b1ara_c6/pysqlite3/setup.py'"'"'; __file__='"'"'/tmp/pip-install-b1ara_c6/pysqlite3/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-q4c8lv38
  Command output: [use --verbose to show]
  Running setup.py clean for pysqlite3
Failed to build pysqlite3
Installing collected packages: pysqlite3
    Running setup.py install for pysqlite3 ... done
Successfully installed pysqlite3
$ python3 -c "import pysqlite3"  # despite the report of a successful installation, pysqlite3 is not available
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'pysqlite3'

Note that this output does indicate Failed to build pysqlite3 and issues a warning that no files were created, but it fails to error.

If we run the install with pip's verbosity turned up, we get more information about what went wrong (in this case, we don't have Python.h)

$ python3 -m pip install -v pysqlite3
# ...
Building wheels for collected packages: pysqlite3
  Created temporary directory: /tmp/pip-wheel-lozvneh0
  Building wheel for pysqlite3 (setup.py) ...   Destination directory: /tmp/pip-wheel-lozvneh0
  Running command /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-9kwwm8h5/pysqlite3/setup.py'"'"'; __file__='"'"'/tmp/pip-install-9kwwm8h5/pysqlite3/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-lozvneh0
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-3.8
  creating build/lib.linux-x86_64-3.8/pysqlite3
  copying pysqlite3/dbapi2.py -> build/lib.linux-x86_64-3.8/pysqlite3
  copying pysqlite3/__init__.py -> build/lib.linux-x86_64-3.8/pysqlite3
  running build_ext
  Builds a C extension linking against libsqlite3 library
  building 'pysqlite3._sqlite3' extension
  creating build/temp.linux-x86_64-3.8
  creating build/temp.linux-x86_64-3.8/src
  x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DMODULE_NAME="pysqlite3.dbapi2" -I/usr/include -I/usr/include/python3.8 -c src/module.c -o build/temp.linux-x86_64-3.8/src/module.o
  In file included from src/module.c:24:
  src/connection.h:34:10: fatal error: sqlite3.h: No such file or directory
     34 | #include "sqlite3.h"
        |          ^~~~~~~~~~~
  compilation terminated.
  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
coleifer commented 1 year ago

Thanks @SnoopJ - I will get this addressed asap. Excellent issue report, by the way.

SnoopJ commented 1 year ago

I didn't look too hard at setup.py but I think if you "just" re-raise the exception it should fix the issue.

That is, assuming there isn't a reason not to do that :sweat_smile:

coleifer commented 1 year ago

Verified that this is fixed, version 0.5.0 is up on pypi now.