From: Daniele Varrazzo Date: Sun, 22 Nov 2020 21:51:20 +0000 (+0000) Subject: Create the psycopg3-binary package X-Git-Tag: 3.0.dev0~328 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e5ee69982515d752f908afd9b759c856cf0ab9a;p=thirdparty%2Fpsycopg.git Create the psycopg3-binary package --- diff --git a/README.rst b/README.rst index 82f21bcfe..dd1635ae4 100644 --- a/README.rst +++ b/README.rst @@ -49,5 +49,5 @@ and to run the tests:: tox -c psycopg3_c -s Please look at the commands definitions in the ``tox.ini`` files if you want -to run some of them interacively: the dependency should be already in your +to run some of them interactively: the dependency should be already in your virtualenv. diff --git a/psycopg3/psycopg3/pq/__init__.py b/psycopg3/psycopg3/pq/__init__.py index fa21c491b..8ebee38d5 100644 --- a/psycopg3/psycopg3/pq/__init__.py +++ b/psycopg3/psycopg3/pq/__init__.py @@ -39,15 +39,33 @@ Escaping: Type[proto.Escaping] def import_from_libpq() -> None: """ Import pq objects implementation from the best libpw wrapper available. + + If an implementation is requested try to import only it, otherwise + try to import the best implementation available. """ + # import these names into the module on success as side effect global __impl__, version, PGconn, PGresult, Conninfo, Escaping impl = os.environ.get("PSYCOPG3_IMPL", "").lower() + module = None + # The best implementation: fast but requires the system libpq installed if not impl or impl == "c": try: # TODO: extension module not recognised by mypy? - from psycopg3_c import pq_cython # type: ignore + from psycopg3_c import pq_cython as module # type: ignore + except Exception as e: + if not impl: + logger.debug("C pq wrapper not available: %s", e) + else: + raise ImportError( + f"requested pq implementation '{impl}' not available" + ) from e + + # Second best implementation: fast and stand-alone + if not module and (not impl or impl == "binary"): + try: + from psycopg3_binary import pq_cython as module # type: ignore except Exception as e: if not impl: logger.debug("C pq wrapper not available: %s", e) @@ -55,18 +73,11 @@ def import_from_libpq() -> None: raise ImportError( f"requested pq implementation '{impl}' not available" ) from e - else: - __impl__ = pq_cython.__impl__ - version = pq_cython.version - PGconn = pq_cython.PGconn - PGresult = pq_cython.PGresult - Conninfo = pq_cython.Conninfo - Escaping = pq_cython.Escaping - return - - if not impl or impl == "python": + + # Pure Python implementation, slow and requires the system libpq installed. + if not module and (not impl or impl == "python"): try: - from . import pq_ctypes + from . import pq_ctypes as module # type: ignore[no-redef] except Exception as e: if not impl: logger.debug("python pq wrapper not available: %s", e) @@ -74,16 +85,15 @@ def import_from_libpq() -> None: raise ImportError( f"requested pq implementation '{impl}' not available" ) from e - else: - __impl__ = pq_ctypes.__impl__ - version = pq_ctypes.version - PGconn = pq_ctypes.PGconn - PGresult = pq_ctypes.PGresult - Conninfo = pq_ctypes.Conninfo - Escaping = pq_ctypes.Escaping - return - - if impl: + + if module: + __impl__ = module.__impl__ + version = module.version + PGconn = module.PGconn + PGresult = module.PGresult + Conninfo = module.Conninfo + Escaping = module.Escaping + elif impl: raise ImportError(f"requested pq impementation '{impl}' unknown") else: raise ImportError("no pq wrapper available") diff --git a/psycopg3/setup.py b/psycopg3/setup.py index 858438b00..b0fe3b0bc 100644 --- a/psycopg3/setup.py +++ b/psycopg3/setup.py @@ -23,7 +23,14 @@ with open("psycopg3/version.py") as f: version = m.group(1) extras_require = { - "c": [f"psycopg3-c == {version}"], + # Install the C extension module (requires dev tools) + "c": [ + f"psycopg3-c == {version}", + ], + # Install the stand-alone C extension module + "binary": [ + f"psycopg3-binary == {version}", + ], "test": [ "pytest >= 6, < 6.1", "pytest-asyncio >= 0.14.0, < 0.15", diff --git a/tests/fix_pq.py b/tests/fix_pq.py index 24d8d8e44..551032bff 100644 --- a/tests/fix_pq.py +++ b/tests/fix_pq.py @@ -36,8 +36,18 @@ def libpq(): """Return a ctypes wrapper to access the libpq.""" import ctypes.util - libname = ctypes.util.find_library("pq") - return ctypes.pydll.LoadLibrary(libname) + try: + # Not available when testing the binary package + libname = ctypes.util.find_library("pq") + assert libname, "libpq libname not found" + return ctypes.pydll.LoadLibrary(libname) + except Exception as e: + from psycopg3 import pq + + if pq.__impl__ == "binary": + pytest.skip(f"can't load libpq for testing: {e}") + else: + raise def check_libpq_version(got, want): diff --git a/tools/build_wheels.sh b/tools/build_wheels.sh index 548ac8c2a..9ce948189 100755 --- a/tools/build_wheels.sh +++ b/tools/build_wheels.sh @@ -41,10 +41,19 @@ export PATH="/usr/pgsql-13/bin/:$PATH" # Using --global-option="-L/usr/pgsql-13/lib/" disables wheels, so no-go. cp -avr /usr/pgsql-13/lib/* /usr/lib/ +# Patch a copy of the c package to name it -binary +cp -r /psycopg3/psycopg3_c /psycopg3_binary +mv /psycopg3_binary/{psycopg3_c,psycopg3_binary}/ +sed -i 's/psycopg3-c/psycopg3-binary/' /psycopg3_binary/setup.cfg +sed -i "s/__impl__[[:space:]]*=.*/__impl__ = 'binary'/" \ + /psycopg3_binary/psycopg3_binary/pq_cython.pyx +find /psycopg3_binary/ -name \*.pyx -or -name \*.pxd -or -name \*.py \ + | xargs sed -i 's/\bpsycopg3_c\b/psycopg3_binary/' + # Compile wheels for PYBIN in /opt/python/*/bin; do if [[ $PYBIN =~ "cp35" ]]; then continue; fi - "${PYBIN}/pip" wheel /psycopg3/psycopg3_c/ --no-deps -w /tmpwheels/ + "${PYBIN}/pip" wheel /psycopg3_binary/ --no-deps -w /tmpwheels/ done # Bundle external shared libraries into the wheels @@ -63,6 +72,6 @@ rm -v /usr/pgsql-13/lib/libpq.* # Install packages and test for PYBIN in /opt/python/*/bin/; do if [[ $PYBIN =~ "cp35" ]]; then continue; fi - "${PYBIN}/pip" install psycopg3[c,test]==$version -f /psycopg3/wheels - PSYCOPG3_IMPL=c "${PYBIN}/pytest" /psycopg3/tests -m "not slow" + "${PYBIN}/pip" install psycopg3[binary,test]==$version -f /psycopg3/wheels + PSYCOPG3_IMPL=binary "${PYBIN}/pytest" /psycopg3/tests -m "not slow" done