From efdce2a966078ff0ed181bae78349e5210c418d7 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 27 Dec 2020 17:56:18 +0100 Subject: [PATCH] Module psycopg3_c.pq_cython renamed to psycopg3_c.pq psycopg3_c files reorganised in directories. Still unable to split and localise pxd files, but now it's already cleaner. Travis keeps failing in funny ways, so skipping fork tests (they pass ok locally). --- .travis.yml | 5 ++++ psycopg3/psycopg3/pq/__init__.py | 4 +-- psycopg3_c/psycopg3_c/.gitignore | 2 +- psycopg3_c/psycopg3_c/_psycopg3.pyx | 13 ++++++--- psycopg3_c/psycopg3_c/_psycopg3/__init__.pxd | 9 +++++++ .../psycopg3_c/{ => _psycopg3}/adapt.pyx | 7 ++--- .../psycopg3_c/{ => _psycopg3}/generators.pyx | 26 +++++++++--------- .../psycopg3_c/{ => _psycopg3}/oids.pxd | 0 .../psycopg3_c/{ => _psycopg3}/transform.pyx | 6 +---- psycopg3_c/psycopg3_c/adapt.pxd | 14 ---------- .../psycopg3_c/{pq_cython.pxd => pq.pxd} | 0 .../psycopg3_c/{pq_cython.pyx => pq.pyx} | 4 +-- psycopg3_c/psycopg3_c/pq/__init__.pxd | 9 +++++++ psycopg3_c/psycopg3_c/pq/__init__.py | 0 psycopg3_c/psycopg3_c/pq/conninfo.pyx | 2 +- psycopg3_c/psycopg3_c/pq/escaping.pyx | 2 +- psycopg3_c/psycopg3_c/pq/pgcancel.pyx | 2 +- psycopg3_c/psycopg3_c/pq/pgconn.pyx | 27 +++++++++---------- psycopg3_c/psycopg3_c/pq/pgresult.pyx | 2 +- psycopg3_c/psycopg3_c/{ => types}/endian.pxd | 0 psycopg3_c/psycopg3_c/types/numeric.pyx | 3 +-- psycopg3_c/psycopg3_c/types/singletons.pyx | 1 - psycopg3_c/psycopg3_c/types/text.pyx | 4 +-- psycopg3_c/setup.py | 9 ++++--- tests/conftest.py | 6 +++++ tests/pq/test_pgconn.py | 2 +- tests/test_concurrency.py | 3 +-- tests/types/test_network.py | 8 ++---- tests/types/test_uuid.py | 8 ++---- tools/build_wheels.sh | 2 +- tools/update_oids.py | 14 +++++----- 31 files changed, 97 insertions(+), 97 deletions(-) create mode 100644 psycopg3_c/psycopg3_c/_psycopg3/__init__.pxd rename psycopg3_c/psycopg3_c/{ => _psycopg3}/adapt.pyx (95%) rename psycopg3_c/psycopg3_c/{ => _psycopg3}/generators.pyx (82%) rename psycopg3_c/psycopg3_c/{ => _psycopg3}/oids.pxd (100%) rename psycopg3_c/psycopg3_c/{ => _psycopg3}/transform.pyx (98%) delete mode 100644 psycopg3_c/psycopg3_c/adapt.pxd rename psycopg3_c/psycopg3_c/{pq_cython.pxd => pq.pxd} (100%) rename psycopg3_c/psycopg3_c/{pq_cython.pyx => pq.pyx} (99%) create mode 100644 psycopg3_c/psycopg3_c/pq/__init__.pxd delete mode 100644 psycopg3_c/psycopg3_c/pq/__init__.py rename psycopg3_c/psycopg3_c/{ => types}/endian.pxd (100%) diff --git a/.travis.yml b/.travis.yml index 3b8e4b559..2d6d729f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,9 @@ matrix: - PGVER=9.5 - PSYCOPG3_IMPL=c - PGPORT=5432 + # skip tests failing on importing psycopg3_c.pq on subprocess + # they only fail on Travis, work ok locally under tox too. + - PYTEST_ADDOPTS="-m 'not subprocess'" - python: 3.6 addons: @@ -62,6 +65,7 @@ matrix: - PGVER=10 - PSYCOPG3_IMPL=c - PGPORT=5432 + - PYTEST_ADDOPTS="-m 'not subprocess'" - python: 3.7 addons: @@ -90,6 +94,7 @@ matrix: - PGVER=12 - PSYCOPG3_IMPL=c - PGPORT=5433 + - PYTEST_ADDOPTS="-m 'not subprocess'" - python: 3.8 addons: diff --git a/psycopg3/psycopg3/pq/__init__.py b/psycopg3/psycopg3/pq/__init__.py index 1d53c2c48..89c4a9476 100644 --- a/psycopg3/psycopg3/pq/__init__.py +++ b/psycopg3/psycopg3/pq/__init__.py @@ -52,7 +52,7 @@ def import_from_libpq() -> None: if not impl or impl == "c": try: # TODO: extension module not recognised by mypy? - from psycopg3_c import pq_cython as module # type: ignore + from psycopg3_c import pq as module # type: ignore except Exception as e: if not impl: logger.debug("C pq wrapper not available: %s", e) @@ -64,7 +64,7 @@ def import_from_libpq() -> None: # 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 + from psycopg3_binary import pq as module # type: ignore except Exception as e: if not impl: logger.debug("C pq wrapper not available: %s", e) diff --git a/psycopg3_c/psycopg3_c/.gitignore b/psycopg3_c/psycopg3_c/.gitignore index d11859b0b..20bb0e25b 100644 --- a/psycopg3_c/psycopg3_c/.gitignore +++ b/psycopg3_c/psycopg3_c/.gitignore @@ -1,4 +1,4 @@ /*.so _psycopg3.c -pq_cython.c +pq.c *.html diff --git a/psycopg3_c/psycopg3_c/_psycopg3.pyx b/psycopg3_c/psycopg3_c/_psycopg3.pyx index bf5ae1760..4e32e9db5 100644 --- a/psycopg3_c/psycopg3_c/_psycopg3.pyx +++ b/psycopg3_c/psycopg3_c/_psycopg3.pyx @@ -1,5 +1,5 @@ """ -psycopg3._psycopg3 optimization module. +psycopg3_c._psycopg3 optimization module. The module contains optimized C code used in preference to Python code if a compiler is available. @@ -7,9 +7,14 @@ if a compiler is available. # Copyright (C) 2020 The Psycopg Team +from psycopg3_c cimport pq +from psycopg3_c.pq cimport libpq +from psycopg3_c._psycopg3 cimport oids + +include "_psycopg3/adapt.pyx" +include "_psycopg3/generators.pyx" +include "_psycopg3/transform.pyx" + include "types/numeric.pyx" include "types/singletons.pyx" include "types/text.pyx" -include "generators.pyx" -include "adapt.pyx" -include "transform.pyx" diff --git a/psycopg3_c/psycopg3_c/_psycopg3/__init__.pxd b/psycopg3_c/psycopg3_c/_psycopg3/__init__.pxd new file mode 100644 index 000000000..a9ff42399 --- /dev/null +++ b/psycopg3_c/psycopg3_c/_psycopg3/__init__.pxd @@ -0,0 +1,9 @@ +""" +psycopg3_c.pq cython module. + +This file is necessary to allow c-importing pxd files from this directory. +""" + +# Copyright (C) 2020 The Psycopg Team + +from psycopg3_c._psycopg3 cimport oids diff --git a/psycopg3_c/psycopg3_c/adapt.pyx b/psycopg3_c/psycopg3_c/_psycopg3/adapt.pyx similarity index 95% rename from psycopg3_c/psycopg3_c/adapt.pyx rename to psycopg3_c/psycopg3_c/_psycopg3/adapt.pyx index 5f644375c..c6460e1be 100644 --- a/psycopg3_c/psycopg3_c/adapt.pyx +++ b/psycopg3_c/psycopg3_c/_psycopg3/adapt.pyx @@ -19,10 +19,7 @@ from cpython.bytes cimport PyBytes_AsStringAndSize from cpython.bytearray cimport PyByteArray_FromStringAndSize, PyByteArray_Resize from cpython.bytearray cimport PyByteArray_AS_STRING -from psycopg3_c cimport oids -from psycopg3_c.pq cimport libpq -from psycopg3_c.adapt cimport cloader_func, get_context_func -from psycopg3_c.pq_cython cimport Escaping, _buffer_as_string_and_size +from psycopg3_c.pq cimport _buffer_as_string_and_size from psycopg3 import errors as e from psycopg3.pq import Format @@ -36,7 +33,7 @@ cdef class CDumper: cdef object src cdef public libpq.Oid oid cdef readonly object connection - cdef PGconn _pgconn + cdef pq.PGconn _pgconn def __init__(self, src: type, context: Optional["AdaptContext"] = None): self.src = src diff --git a/psycopg3_c/psycopg3_c/generators.pyx b/psycopg3_c/psycopg3_c/_psycopg3/generators.pyx similarity index 82% rename from psycopg3_c/psycopg3_c/generators.pyx rename to psycopg3_c/psycopg3_c/_psycopg3/generators.pyx index 6eee221be..d68130341 100644 --- a/psycopg3_c/psycopg3_c/generators.pyx +++ b/psycopg3_c/psycopg3_c/_psycopg3/generators.pyx @@ -8,23 +8,21 @@ import logging from typing import List from psycopg3 import errors as e +from psycopg3.pq import proto, error_message, PQerror from psycopg3.proto import PQGen from psycopg3.waiting import Wait, Ready -from psycopg3 import pq -from psycopg3_c.pq cimport libpq -from psycopg3_c.pq_cython cimport PGconn, PGresult cdef object WAIT_W = Wait.W cdef object WAIT_R = Wait.R cdef object WAIT_RW = Wait.RW cdef int READY_R = Ready.R -def connect(conninfo: str) -> PQGenConn[pq.proto.PGconn]: +def connect(conninfo: str) -> PQGenConn[proto.PGconn]: """ Generator to create a database connection without blocking. """ - cdef PGconn conn = PGconn.connect_start(conninfo.encode("utf8")) + cdef pq.PGconn conn = pq.PGconn.connect_start(conninfo.encode("utf8")) logger.debug("connection started, status %s", conn.status.name) cdef libpq.PGconn *pgconn_ptr = conn.pgconn_ptr cdef int conn_status = libpq.PQstatus(pgconn_ptr) @@ -33,7 +31,7 @@ def connect(conninfo: str) -> PQGenConn[pq.proto.PGconn]: while 1: if conn_status == libpq.CONNECTION_BAD: raise e.OperationalError( - f"connection is bad: {pq.error_message(conn)}" + f"connection is bad: {error_message(conn)}" ) poll_status = libpq.PQconnectPoll(pgconn_ptr) @@ -46,7 +44,7 @@ def connect(conninfo: str) -> PQGenConn[pq.proto.PGconn]: yield (libpq.PQsocket(pgconn_ptr), WAIT_W) elif poll_status == libpq.PGRES_POLLING_FAILED: raise e.OperationalError( - f"connection failed: {pq.error_message(conn)}" + f"connection failed: {error_message(conn)}" ) else: raise e.InternalError(f"unexpected poll status: {poll_status}") @@ -55,7 +53,7 @@ def connect(conninfo: str) -> PQGenConn[pq.proto.PGconn]: return conn -def execute(PGconn pgconn) -> PQGen[List[pq.proto.PGresult]]: +def execute(pq.PGconn pgconn) -> PQGen[List[proto.PGresult]]: """ Generator sending a query and returning results without blocking. @@ -66,7 +64,7 @@ def execute(PGconn pgconn) -> PQGen[List[pq.proto.PGresult]]: Return the list of results returned by the database (whether success or error). """ - results: List[pq.proto.PGresult] = [] + results: List[proto.PGresult] = [] cdef libpq.PGconn *pgconn_ptr = pgconn.pgconn_ptr cdef int status cdef libpq.PGnotify *notify @@ -85,8 +83,8 @@ def execute(PGconn pgconn) -> PQGen[List[pq.proto.PGresult]]: # PGconn buffer and passed to Python later. cires = libpq.PQconsumeInput(pgconn_ptr) if 1 != cires: - raise pq.PQerror( - f"consuming input failed: {pq.error_message(pgconn)}") + raise PQerror( + f"consuming input failed: {error_message(pgconn)}") continue # Fetching the result @@ -97,8 +95,8 @@ def execute(PGconn pgconn) -> PQGen[List[pq.proto.PGresult]]: ibres = libpq.PQisBusy(pgconn_ptr) if 1 != cires: - raise pq.PQerror( - f"consuming input failed: {pq.error_message(pgconn)}") + raise PQerror( + f"consuming input failed: {error_message(pgconn)}") if ibres: yield WAIT_R continue @@ -120,7 +118,7 @@ def execute(PGconn pgconn) -> PQGen[List[pq.proto.PGresult]]: pgres = libpq.PQgetResult(pgconn_ptr) if pgres is NULL: break - results.append(PGresult._from_ptr(pgres)) + results.append(pq.PGresult._from_ptr(pgres)) status = libpq.PQresultStatus(pgres) if status in (libpq.PGRES_COPY_IN, libpq.PGRES_COPY_OUT, libpq.PGRES_COPY_BOTH): diff --git a/psycopg3_c/psycopg3_c/oids.pxd b/psycopg3_c/psycopg3_c/_psycopg3/oids.pxd similarity index 100% rename from psycopg3_c/psycopg3_c/oids.pxd rename to psycopg3_c/psycopg3_c/_psycopg3/oids.pxd diff --git a/psycopg3_c/psycopg3_c/transform.pyx b/psycopg3_c/psycopg3_c/_psycopg3/transform.pyx similarity index 98% rename from psycopg3_c/psycopg3_c/transform.pyx rename to psycopg3_c/psycopg3_c/_psycopg3/transform.pyx index e6d47b0c7..8dd12c692 100644 --- a/psycopg3_c/psycopg3_c/transform.pyx +++ b/psycopg3_c/psycopg3_c/_psycopg3/transform.pyx @@ -16,10 +16,6 @@ from cpython.object cimport PyObject, PyObject_CallFunctionObjArgs from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple -from psycopg3_c cimport oids -from psycopg3_c.pq cimport libpq -from psycopg3_c.pq_cython cimport PGresult - from psycopg3 import errors as e from psycopg3.pq import Format @@ -59,7 +55,7 @@ cdef class Transformer: cdef dict _dumpers_cache cdef dict _text_loaders cdef dict _binary_loaders - cdef PGresult _pgresult + cdef pq.PGresult _pgresult cdef int _nfields, _ntuples cdef list _row_loaders diff --git a/psycopg3_c/psycopg3_c/adapt.pxd b/psycopg3_c/psycopg3_c/adapt.pxd deleted file mode 100644 index 3c8a8772a..000000000 --- a/psycopg3_c/psycopg3_c/adapt.pxd +++ /dev/null @@ -1,14 +0,0 @@ -""" -C definitions of the adaptation system. -""" - -# Copyright (C) 2020 The Psycopg Team - -from cpython.object cimport PyObject - -# The type of a function reading a result from the database and returning -# a Python object. -ctypedef object (*cloader_func)(const char *data, size_t length, void *context) - -# Take in input a Loader instance and return a context for a `cloader_func`. -ctypedef void * (*get_context_func)(object conn) diff --git a/psycopg3_c/psycopg3_c/pq_cython.pxd b/psycopg3_c/psycopg3_c/pq.pxd similarity index 100% rename from psycopg3_c/psycopg3_c/pq_cython.pxd rename to psycopg3_c/psycopg3_c/pq.pxd diff --git a/psycopg3_c/psycopg3_c/pq_cython.pyx b/psycopg3_c/psycopg3_c/pq.pyx similarity index 99% rename from psycopg3_c/psycopg3_c/pq_cython.pyx rename to psycopg3_c/psycopg3_c/pq.pyx index 761bcd5c2..c3018ce51 100644 --- a/psycopg3_c/psycopg3_c/pq_cython.pyx +++ b/psycopg3_c/psycopg3_c/pq.pyx @@ -6,11 +6,9 @@ libpq Python wrapper using cython bindings. from psycopg3_c.pq cimport libpq -from psycopg3.pq.misc import PQerror, error_message - from psycopg3.pq import ConnStatus, PollingStatus, ExecStatus from psycopg3.pq import TransactionStatus, Ping, DiagnosticField, Format - +from psycopg3.pq.misc import PQerror, error_message __impl__ = 'c' diff --git a/psycopg3_c/psycopg3_c/pq/__init__.pxd b/psycopg3_c/psycopg3_c/pq/__init__.pxd new file mode 100644 index 000000000..e6e497c11 --- /dev/null +++ b/psycopg3_c/psycopg3_c/pq/__init__.pxd @@ -0,0 +1,9 @@ +""" +psycopg3_c.pq cython module. + +This file is necessary to allow c-importing pxd files from this directory. +""" + +# Copyright (C) 2020 The Psycopg Team + +from psycopg3_c.pq cimport libpq diff --git a/psycopg3_c/psycopg3_c/pq/__init__.py b/psycopg3_c/psycopg3_c/pq/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/psycopg3_c/psycopg3_c/pq/conninfo.pyx b/psycopg3_c/psycopg3_c/pq/conninfo.pyx index af32256e7..cd7c8d9e5 100644 --- a/psycopg3_c/psycopg3_c/pq/conninfo.pyx +++ b/psycopg3_c/psycopg3_c/pq/conninfo.pyx @@ -1,5 +1,5 @@ """ -psycopg3_c.pq_cython.Conninfo object implementation. +psycopg3_c.pq.Conninfo object implementation. """ # Copyright (C) 2020 The Psycopg Team diff --git a/psycopg3_c/psycopg3_c/pq/escaping.pyx b/psycopg3_c/psycopg3_c/pq/escaping.pyx index 6a6498a77..e2f2dd172 100644 --- a/psycopg3_c/psycopg3_c/pq/escaping.pyx +++ b/psycopg3_c/psycopg3_c/pq/escaping.pyx @@ -1,5 +1,5 @@ """ -psycopg3_c.pq_cython.Escaping object implementation. +psycopg3_c.pq.Escaping object implementation. """ # Copyright (C) 2020 The Psycopg Team diff --git a/psycopg3_c/psycopg3_c/pq/pgcancel.pyx b/psycopg3_c/psycopg3_c/pq/pgcancel.pyx index 0933cf699..07e24853b 100644 --- a/psycopg3_c/psycopg3_c/pq/pgcancel.pyx +++ b/psycopg3_c/psycopg3_c/pq/pgcancel.pyx @@ -1,5 +1,5 @@ """ -psycopg3_c.pq_cython.PGcancel object implementation. +psycopg3_c.pq.PGcancel object implementation. """ # Copyright (C) 2020 The Psycopg Team diff --git a/psycopg3_c/psycopg3_c/pq/pgconn.pyx b/psycopg3_c/psycopg3_c/pq/pgconn.pyx index 0cf4ab2d9..f07ac79e0 100644 --- a/psycopg3_c/psycopg3_c/pq/pgconn.pyx +++ b/psycopg3_c/psycopg3_c/pq/pgconn.pyx @@ -1,5 +1,5 @@ """ -psycopg3_c.pq_cython.PGconn object implementation. +psycopg3_c.pq.PGconn object implementation. """ # Copyright (C) 2020 The Psycopg Team @@ -10,7 +10,6 @@ from cpython.bytes cimport PyBytes_AsString import logging -from psycopg3_c.pq.libpq cimport Oid from psycopg3.pq.misc import PGnotify, connection_summary logger = logging.getLogger('psycopg3') @@ -212,7 +211,7 @@ cdef class PGconn: _ensure_pgconn(self) cdef int cnparams - cdef Oid *ctypes + cdef libpq.Oid *ctypes cdef char *const *cvalues cdef int *clengths cdef int *cformats @@ -242,7 +241,7 @@ cdef class PGconn: _ensure_pgconn(self) cdef int cnparams - cdef Oid *ctypes + cdef libpq.Oid *ctypes cdef char *const *cvalues cdef int *clengths cdef int *cformats @@ -272,9 +271,9 @@ cdef class PGconn: cdef int i cdef int nparams = len(param_types) if param_types else 0 - cdef Oid *atypes = NULL + cdef libpq.Oid *atypes = NULL if nparams: - atypes = PyMem_Malloc(nparams * sizeof(Oid)) + atypes = PyMem_Malloc(nparams * sizeof(libpq.Oid)) for i in range(nparams): atypes[i] = param_types[i] @@ -301,7 +300,7 @@ cdef class PGconn: _ensure_pgconn(self) cdef int cnparams - cdef Oid *ctypes + cdef libpq.Oid *ctypes cdef char *const *cvalues cdef int *clengths cdef int *cformats @@ -331,9 +330,9 @@ cdef class PGconn: cdef int i cdef int nparams = len(param_types) if param_types else 0 - cdef Oid *atypes = NULL + cdef libpq.Oid *atypes = NULL if nparams: - atypes = PyMem_Malloc(nparams * sizeof(Oid)) + atypes = PyMem_Malloc(nparams * sizeof(libpq.Oid)) for i in range(nparams): atypes[i] = param_types[i] @@ -358,7 +357,7 @@ cdef class PGconn: _ensure_pgconn(self) cdef int cnparams - cdef Oid *ctypes + cdef libpq.Oid *ctypes cdef char *const *cvalues cdef int *clengths cdef int *cformats @@ -523,7 +522,7 @@ cdef void notice_receiver(void *arg, const libpq.PGresult *res_ptr) with gil: res.pgresult_ptr = NULL # avoid destroying the pgresult_ptr -cdef (int, Oid *, char * const*, int *, int *) _query_params_args( +cdef (int, libpq.Oid *, char * const*, int *, int *) _query_params_args( list param_values: Optional[Sequence[Optional[bytes]]], param_types: Optional[Sequence[int]], list param_formats: Optional[Sequence[Format]], @@ -570,9 +569,9 @@ cdef (int, Oid *, char * const*, int *, int *) _query_params_args( aparams[i] = ptr alenghts[i] = length - cdef Oid *atypes = NULL + cdef libpq.Oid *atypes = NULL if tparam_types: - atypes = PyMem_Malloc(nparams * sizeof(Oid)) + atypes = PyMem_Malloc(nparams * sizeof(libpq.Oid)) for i in range(nparams): atypes[i] = tparam_types[i] @@ -586,7 +585,7 @@ cdef (int, Oid *, char * const*, int *, int *) _query_params_args( cdef void _clear_query_params( - Oid *ctypes, char *const *cvalues, int *clenghst, int *cformats + libpq.Oid *ctypes, char *const *cvalues, int *clenghst, int *cformats ): PyMem_Free(ctypes) PyMem_Free(cvalues) diff --git a/psycopg3_c/psycopg3_c/pq/pgresult.pyx b/psycopg3_c/psycopg3_c/pq/pgresult.pyx index 909d6dd1c..7c8caf8b3 100644 --- a/psycopg3_c/psycopg3_c/pq/pgresult.pyx +++ b/psycopg3_c/psycopg3_c/pq/pgresult.pyx @@ -1,5 +1,5 @@ """ -psycopg3_c.pq_cython.PGresult object implementation. +psycopg3_c.pq.PGresult object implementation. """ # Copyright (C) 2020 The Psycopg Team diff --git a/psycopg3_c/psycopg3_c/endian.pxd b/psycopg3_c/psycopg3_c/types/endian.pxd similarity index 100% rename from psycopg3_c/psycopg3_c/endian.pxd rename to psycopg3_c/psycopg3_c/types/endian.pxd diff --git a/psycopg3_c/psycopg3_c/types/numeric.pyx b/psycopg3_c/psycopg3_c/types/numeric.pyx index 075ad91ef..f52447015 100644 --- a/psycopg3_c/psycopg3_c/types/numeric.pyx +++ b/psycopg3_c/psycopg3_c/types/numeric.pyx @@ -9,8 +9,7 @@ from cpython.long cimport PyLong_FromString, PyLong_FromLong, PyLong_AsLongLong from cpython.long cimport PyLong_FromLongLong, PyLong_FromUnsignedLong from cpython.float cimport PyFloat_FromDouble -from psycopg3_c cimport oids -from psycopg3_c.endian cimport be16toh, be32toh, be64toh, htobe64 +from endian cimport be16toh, be32toh, be64toh, htobe64 cdef extern from "Python.h": # work around https://github.com/cython/cython/issues/3909 diff --git a/psycopg3_c/psycopg3_c/types/singletons.pyx b/psycopg3_c/psycopg3_c/types/singletons.pyx index c77463d85..1a383cd0d 100644 --- a/psycopg3_c/psycopg3_c/types/singletons.pyx +++ b/psycopg3_c/psycopg3_c/types/singletons.pyx @@ -5,7 +5,6 @@ Cython adapters for boolean. # Copyright (C) 2020 The Psycopg Team from psycopg3.pq import Format -from psycopg3_c cimport oids cdef class BoolDumper(CDumper): diff --git a/psycopg3_c/psycopg3_c/types/text.pyx b/psycopg3_c/psycopg3_c/types/text.pyx index a7d7c019e..5c21096ef 100644 --- a/psycopg3_c/psycopg3_c/types/text.pyx +++ b/psycopg3_c/psycopg3_c/types/text.pyx @@ -8,9 +8,7 @@ from cpython.bytes cimport PyBytes_AsString, PyBytes_AsStringAndSize from cpython.unicode cimport PyUnicode_Decode, PyUnicode_DecodeUTF8 from cpython.unicode cimport PyUnicode_AsUTF8String, PyUnicode_AsEncodedString -from psycopg3_c cimport oids -from psycopg3_c.pq cimport libpq -from psycopg3_c.pq_cython cimport Escaping +from psycopg3_c.pq cimport Escaping cdef class _StringDumper(CDumper): diff --git a/psycopg3_c/setup.py b/psycopg3_c/setup.py index aedc7fb45..87c185fc8 100644 --- a/psycopg3_c/setup.py +++ b/psycopg3_c/setup.py @@ -55,7 +55,10 @@ class psycopg3_build_ext(build_ext): if cythonize is not None: for ext in self.distribution.ext_modules: - ext.sources[0] = os.path.splitext(ext.sources[0])[0] + ".pyx" + for i in range(len(ext.sources)): + base, fext = os.path.splitext(ext.sources[i]) + if fext == ".c": + ext.sources[i] = base + ".pyx" self.distribution.ext_modules = cythonize( self.distribution.ext_modules, @@ -78,8 +81,8 @@ pgext = Extension( ) pqext = Extension( - "psycopg3_c.pq_cython", - ["psycopg3_c/pq_cython.c"], + "psycopg3_c.pq", + ["psycopg3_c/pq.c"], libraries=["pq"], include_dirs=[], ) diff --git a/tests/conftest.py b/tests/conftest.py index 6598cabdf..7b1670859 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,3 +9,9 @@ def pytest_configure(config): config.addinivalue_line( "markers", "slow: this test is kinda slow (skip with -m 'not slow')" ) + + # There are troubles on travis with these kind of tests and I cannot + # catch the exception for my life. + config.addinivalue_line( + "markers", "subprocess: the test import psycopg3 after subprocess" + ) diff --git a/tests/pq/test_pgconn.py b/tests/pq/test_pgconn.py index cc579a60e..fece93f3c 100644 --- a/tests/pq/test_pgconn.py +++ b/tests/pq/test_pgconn.py @@ -202,7 +202,7 @@ def test_host(pgconn): pgconn.host -# TODO: to implement in pq_cython +# TODO: to implement in psycopg3_c.pq @pytest.mark.xfail @pytest.mark.libpq(">= 12") def test_hostaddr(pgconn): diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 8dde58286..193896423 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -60,6 +60,7 @@ def test_commit_concurrency(conn): @pytest.mark.slow +@pytest.mark.subprocess def test_multiprocess_close(dsn, tmpdir): # Check the problem reported in psycopg2#829 # Subprocess gcs the copy of the fd after fork so it closes connection. @@ -95,8 +96,6 @@ t.join() f.write(module) env = dict(os.environ) env["PYTHONPATH"] = str(tmpdir + os.pathsep + env.get("PYTHONPATH", "")) - # TODO: debug this. Importing c module fails on travis in this scenario - env.pop("PSYCOPG3_IMPL", None) out = sp.check_output( [sys.executable, "-c", script], stderr=sp.STDOUT, env=env ).decode("utf8", "replace") diff --git a/tests/types/test_network.py b/tests/types/test_network.py index 3d3bbf4aa..76e37e6b2 100644 --- a/tests/types/test_network.py +++ b/tests/types/test_network.py @@ -1,4 +1,3 @@ -import os import sys import ipaddress import subprocess as sp @@ -92,6 +91,7 @@ def binary_check(fmt): pytest.xfail("inet binary not implemented") +@pytest.mark.subprocess def test_lazy_load(dsn): script = f"""\ import sys @@ -110,8 +110,4 @@ conn.close() assert 'ipaddress' in sys.modules """ - # TODO: debug this. Importing c module fails on travis in this scenario - env = dict(os.environ) - env.pop("PSYCOPG3_IMPL", None) - - sp.check_call([sys.executable, "-s", "-c", script], env=env) + sp.check_call([sys.executable, "-s", "-c", script]) diff --git a/tests/types/test_uuid.py b/tests/types/test_uuid.py index a231041c3..438361314 100644 --- a/tests/types/test_uuid.py +++ b/tests/types/test_uuid.py @@ -1,4 +1,3 @@ -import os import sys from uuid import UUID import subprocess as sp @@ -25,6 +24,7 @@ def test_uuid_load(conn, fmt_out): assert cur.fetchone()[0] == UUID(val) +@pytest.mark.subprocess def test_lazy_load(dsn): script = f"""\ import sys @@ -41,8 +41,4 @@ conn.close() assert 'uuid' in sys.modules """ - # TODO: debug this. Importing c module fails on travis in this scenario - env = dict(os.environ) - env.pop("PSYCOPG3_IMPL", None) - - sp.check_call([sys.executable, "-c", script], env=env) + sp.check_call([sys.executable, "-c", script]) diff --git a/tools/build_wheels.sh b/tools/build_wheels.sh index 3b1a86b9b..6941a73a2 100755 --- a/tools/build_wheels.sh +++ b/tools/build_wheels.sh @@ -46,7 +46,7 @@ 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 + /psycopg3_binary/psycopg3_binary/pq.pyx find /psycopg3_binary/ -name \*.pyx -or -name \*.pxd -or -name \*.py \ | xargs sed -i 's/\bpsycopg3_c\b/psycopg3_binary/' diff --git a/tools/update_oids.py b/tools/update_oids.py index 0cbbea4af..67c995667 100755 --- a/tools/update_oids.py +++ b/tools/update_oids.py @@ -5,10 +5,12 @@ Update the maps of builtin types and names. You can update this file by executing it, using the PG* env var to connect """ -import os import re import subprocess as sp from typing import List +from pathlib import Path + +ROOT = Path(__file__).parent.parent version_sql = """ @@ -42,18 +44,18 @@ select format('%s_OID = %s', upper(typname), oid) def update_python_oids() -> None: queries = [version_sql, py_oids_sql] - fn = os.path.dirname(__file__) + "/../psycopg3/psycopg3/oids.py" + fn = ROOT / "psycopg3/psycopg3/oids.py" update_file(fn, queries) def update_cython_oids() -> None: queries = [version_sql, cython_oids_sql] - fn = os.path.dirname(__file__) + "/../psycopg3_c/psycopg3_c/oids.pxd" + fn = ROOT / "psycopg3_c/psycopg3_c/_psycopg3/oids.pxd" update_file(fn, queries) -def update_file(fn: str, queries: List[str]) -> None: - with open(fn, "rb") as f: +def update_file(fn: Path, queries: List[str]) -> None: + with fn.open("rb") as f: lines = f.read().splitlines() new = [] @@ -71,7 +73,7 @@ def update_file(fn: str, queries: List[str]) -> None: ] lines[istart + 1 : iend] = new - with open(fn, "wb") as f: + with fn.open("wb") as f: f.write(b"\n".join(lines)) f.write(b"\n") -- 2.47.2