]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: mark external libpq C functions as noexcept nogil
authorLysandros Nikolaou <lisandrosnik@gmail.com>
Fri, 28 Nov 2025 14:05:04 +0000 (15:05 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 5 Dec 2025 13:19:22 +0000 (14:19 +0100)
Add noexcept nogil declarations to libpq bindings and endian conversion
functions. This improves things for when we start using critical
sections inside Cython-defines types. It's also more accurate this way,
instead of only marking the APIs that are explicitly used in a nogil
block.

psycopg_c/psycopg_c/_psycopg/endian.pxd
psycopg_c/psycopg_c/pq/libpq.pxd

index e9f0cb3329f0d58f018aaf7eb910040e29c50fde..3650f10087579f8f500c7be21a98dc3fe6ea18d0 100644 (file)
@@ -147,17 +147,17 @@ cdef extern from * nogil:
 
 #endif
     """
-    cdef uint16_t htobe16(uint16_t host_16bits)
-    cdef uint16_t htole16(uint16_t host_16bits)
-    cdef uint16_t be16toh(uint16_t big_endian_16bits)
-    cdef uint16_t le16toh(uint16_t little_endian_16bits)
-
-    cdef uint32_t htobe32(uint32_t host_32bits)
-    cdef uint32_t htole32(uint32_t host_32bits)
-    cdef uint32_t be32toh(uint32_t big_endian_32bits)
-    cdef uint32_t le32toh(uint32_t little_endian_32bits)
-
-    cdef uint64_t htobe64(uint64_t host_64bits)
-    cdef uint64_t htole64(uint64_t host_64bits)
-    cdef uint64_t be64toh(uint64_t big_endian_64bits)
-    cdef uint64_t le64toh(uint64_t little_endian_64bits)
+    cdef uint16_t htobe16(uint16_t host_16bits) noexcept nogil
+    cdef uint16_t htole16(uint16_t host_16bits) noexcept nogil
+    cdef uint16_t be16toh(uint16_t big_endian_16bits) noexcept nogil
+    cdef uint16_t le16toh(uint16_t little_endian_16bits) noexcept nogil
+
+    cdef uint32_t htobe32(uint32_t host_32bits) noexcept nogil
+    cdef uint32_t htole32(uint32_t host_32bits) noexcept nogil
+    cdef uint32_t be32toh(uint32_t big_endian_32bits) noexcept nogil
+    cdef uint32_t le32toh(uint32_t little_endian_32bits) noexcept nogil
+
+    cdef uint64_t htobe64(uint64_t host_64bits) noexcept nogil
+    cdef uint64_t htole64(uint64_t host_64bits) noexcept nogil
+    cdef uint64_t be64toh(uint64_t big_endian_64bits) noexcept nogil
+    cdef uint64_t le64toh(uint64_t little_endian_64bits) noexcept nogil
index b23059ec50331944e953f525302a6c88c6041b86..973687203ccdf98dc360f190bb1f53c53ea9ccec 100644 (file)
@@ -113,44 +113,47 @@ cdef extern from "libpq-fe.h":
         PGRES_TUPLES_CHUNK
 
     # 33.1. Database Connection Control Functions
-    PGconn *PQconnectdb(const char *conninfo)
-    PGconn *PQconnectStart(const char *conninfo)
-    PostgresPollingStatusType PQconnectPoll(PGconn *conn) nogil
-    PQconninfoOption *PQconndefaults()
-    PQconninfoOption *PQconninfo(PGconn *conn)
-    PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg)
-    void PQfinish(PGconn *conn)
-    void PQreset(PGconn *conn)
-    int PQresetStart(PGconn *conn)
-    PostgresPollingStatusType PQresetPoll(PGconn *conn)
-    PGPing PQping(const char *conninfo)
+    PGconn *PQconnectdb(const char *conninfo) noexcept nogil
+    PGconn *PQconnectStart(const char *conninfo) noexcept nogil
+    PostgresPollingStatusType PQconnectPoll(PGconn *conn) noexcept nogil
+    PQconninfoOption *PQconndefaults() noexcept nogil
+    PQconninfoOption *PQconninfo(PGconn *conn) noexcept nogil
+    PQconninfoOption *PQconninfoParse(const char *conninfo,
+                                      char **errmsg) noexcept nogil
+    void PQfinish(PGconn *conn) noexcept nogil
+    void PQreset(PGconn *conn) noexcept nogil
+    int PQresetStart(PGconn *conn) noexcept nogil
+    PostgresPollingStatusType PQresetPoll(PGconn *conn) noexcept nogil
+    PGPing PQping(const char *conninfo) noexcept nogil
 
     # 33.2. Connection Status Functions
-    char *PQdb(const PGconn *conn)
-    char *PQuser(const PGconn *conn)
-    char *PQpass(const PGconn *conn)
-    char *PQhost(const PGconn *conn)
-    char *PQhostaddr(const PGconn *conn)
-    char *PQport(const PGconn *conn)
-    char *PQtty(const PGconn *conn)
-    char *PQoptions(const PGconn *conn)
-    ConnStatusType PQstatus(const PGconn *conn)
-    PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
-    const char *PQparameterStatus(const PGconn *conn, const char *paramName)
-    int PQprotocolVersion(const PGconn *conn)
-    int PQfullProtocolVersion(const PGconn *conn)
-    int PQserverVersion(const PGconn *conn)
-    char *PQerrorMessage(const PGconn *conn)
-    int PQsocket(const PGconn *conn) nogil
-    int PQbackendPID(const PGconn *conn)
-    int PQconnectionNeedsPassword(const PGconn *conn)
-    int PQconnectionUsedPassword(const PGconn *conn)
-    int PQconnectionUsedGSSAPI(const PGconn *conn)
-    int PQsslInUse(PGconn *conn)   # TODO: const in PG 12 docs - verify/report
+    char *PQdb(const PGconn *conn) noexcept nogil
+    char *PQuser(const PGconn *conn) noexcept nogil
+    char *PQpass(const PGconn *conn) noexcept nogil
+    char *PQhost(const PGconn *conn) noexcept nogil
+    char *PQhostaddr(const PGconn *conn) noexcept nogil
+    char *PQport(const PGconn *conn) noexcept nogil
+    char *PQtty(const PGconn *conn) noexcept nogil
+    char *PQoptions(const PGconn *conn) noexcept nogil
+    ConnStatusType PQstatus(const PGconn *conn) noexcept nogil
+    PGTransactionStatusType PQtransactionStatus(const PGconn *conn) noexcept nogil
+    const char *PQparameterStatus(const PGconn *conn,
+                                  const char *paramName) noexcept nogil
+    int PQprotocolVersion(const PGconn *conn) noexcept nogil
+    int PQfullProtocolVersion(const PGconn *conn) noexcept nogil
+    int PQserverVersion(const PGconn *conn) noexcept nogil
+    char *PQerrorMessage(const PGconn *conn) noexcept nogil
+    int PQsocket(const PGconn *conn) noexcept nogil
+    int PQbackendPID(const PGconn *conn) noexcept nogil
+    int PQconnectionNeedsPassword(const PGconn *conn) noexcept nogil
+    int PQconnectionUsedPassword(const PGconn *conn) noexcept nogil
+    int PQconnectionUsedGSSAPI(const PGconn *conn) noexcept nogil
+    # TODO PQsslInUse: const in PG 12 docs - verify/report
+    int PQsslInUse(PGconn *conn) noexcept nogil
     # TODO: PQsslAttribute, PQsslAttributeNames, PQsslStruct, PQgetssl
 
     # 33.3. Command Execution Functions
-    PGresult *PQexec(PGconn *conn, const char *command) nogil
+    PGresult *PQexec(PGconn *conn, const char *command) noexcept nogil
     PGresult *PQexecParams(PGconn *conn,
                            const char *command,
                            int nParams,
@@ -158,72 +161,81 @@ cdef extern from "libpq-fe.h":
                            const char * const *paramValues,
                            const int *paramLengths,
                            const int *paramFormats,
-                           int resultFormat) nogil
+                           int resultFormat) noexcept nogil
     PGresult *PQprepare(PGconn *conn,
                         const char *stmtName,
                         const char *query,
                         int nParams,
-                        const Oid *paramTypes) nogil
+                        const Oid *paramTypes) noexcept nogil
     PGresult *PQexecPrepared(PGconn *conn,
                              const char *stmtName,
                              int nParams,
                              const char * const *paramValues,
                              const int *paramLengths,
                              const int *paramFormats,
-                             int resultFormat) nogil
-    PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName) nogil
-    PGresult *PQdescribePortal(PGconn *conn, const char *portalName) nogil
-    PGresult *PQclosePrepared(PGconn *conn, const char *stmtName) nogil
-    PGresult *PQclosePortal(PGconn *conn, const char *portalName) nogil
-    ExecStatusType PQresultStatus(const PGresult *res) nogil
+                             int resultFormat) noexcept nogil
+    PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName) noexcept nogil
+    PGresult *PQdescribePortal(PGconn *conn, const char *portalName) noexcept nogil
+    PGresult *PQclosePrepared(PGconn *conn, const char *stmtName) noexcept nogil
+    PGresult *PQclosePortal(PGconn *conn, const char *portalName) noexcept nogil
+    ExecStatusType PQresultStatus(const PGresult *res) noexcept nogil
     # PQresStatus: not needed, we have pretty enums
-    char *PQresultErrorMessage(const PGresult *res) nogil
+    char *PQresultErrorMessage(const PGresult *res) noexcept nogil
     # TODO: PQresultVerboseErrorMessage
-    char *PQresultErrorField(const PGresult *res, int fieldcode) nogil
-    void PQclear(PGresult *res) nogil
+    char *PQresultErrorField(const PGresult *res, int fieldcode) noexcept nogil
+    void PQclear(PGresult *res) noexcept nogil
 
     # 33.3.2. Retrieving Query Result Information
-    int PQntuples(const PGresult *res)
-    int PQnfields(const PGresult *res)
-    char *PQfname(const PGresult *res, int column_number)
-    int PQfnumber(const PGresult *res, const char *column_name)
-    Oid PQftable(const PGresult *res, int column_number)
-    int PQftablecol(const PGresult *res, int column_number)
-    int PQfformat(const PGresult *res, int column_number)
-    Oid PQftype(const PGresult *res, int column_number)
-    int PQfmod(const PGresult *res, int column_number)
-    int PQfsize(const PGresult *res, int column_number)
-    int PQbinaryTuples(const PGresult *res)
-    char *PQgetvalue(const PGresult *res, int row_number, int column_number)
-    int PQgetisnull(const PGresult *res, int row_number, int column_number)
-    int PQgetlength(const PGresult *res, int row_number, int column_number)
-    int PQnparams(const PGresult *res)
-    Oid PQparamtype(const PGresult *res, int param_number)
+    int PQntuples(const PGresult *res) noexcept nogil
+    int PQnfields(const PGresult *res) noexcept nogil
+    char *PQfname(const PGresult *res, int column_number) noexcept nogil
+    int PQfnumber(const PGresult *res, const char *column_name) noexcept nogil
+    Oid PQftable(const PGresult *res, int column_number) noexcept nogil
+    int PQftablecol(const PGresult *res, int column_number) noexcept nogil
+    int PQfformat(const PGresult *res, int column_number) noexcept nogil
+    Oid PQftype(const PGresult *res, int column_number) noexcept nogil
+    int PQfmod(const PGresult *res, int column_number) noexcept nogil
+    int PQfsize(const PGresult *res, int column_number) noexcept nogil
+    int PQbinaryTuples(const PGresult *res) noexcept nogil
+    char *PQgetvalue(const PGresult *res,
+                     int row_number,
+                     int column_number) noexcept nogil
+    int PQgetisnull(const PGresult *res,
+                    int row_number,
+                    int column_number) noexcept nogil
+    int PQgetlength(const PGresult *res,
+                    int row_number,
+                    int column_number) noexcept nogil
+    int PQnparams(const PGresult *res) noexcept nogil
+    Oid PQparamtype(const PGresult *res, int param_number) noexcept nogil
     # PQprint: pretty useless
 
     # 33.3.3. Retrieving Other Result Information
-    char *PQcmdStatus(PGresult *res)
-    char *PQcmdTuples(PGresult *res)
-    Oid PQoidValue(const PGresult *res)
+    char *PQcmdStatus(PGresult *res) noexcept nogil
+    char *PQcmdTuples(PGresult *res) noexcept nogil
+    Oid PQoidValue(const PGresult *res) noexcept nogil
 
     # 33.3.4. Escaping Strings for Inclusion in SQL Commands
-    char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length)
-    char *PQescapeLiteral(PGconn *conn, const char *str, size_t length)
+    char *PQescapeIdentifier(PGconn *conn,
+                             const char *str,
+                             size_t length) noexcept nogil
+    char *PQescapeLiteral(PGconn *conn, const char *str, size_t length) noexcept nogil
     size_t PQescapeStringConn(PGconn *conn,
                               char *to, const char *from_, size_t length,
-                              int *error)
-    size_t PQescapeString(char *to, const char *from_, size_t length)
+                              int *error) noexcept nogil
+    size_t PQescapeString(char *to, const char *from_, size_t length) noexcept nogil
     unsigned char *PQescapeByteaConn(PGconn *conn,
                                      const unsigned char *src,
                                      size_t from_length,
-                                     size_t *to_length)
+                                     size_t *to_length) noexcept nogil
     unsigned char *PQescapeBytea(const unsigned char *src,
                                  size_t from_length,
-                                 size_t *to_length)
-    unsigned char *PQunescapeBytea(const unsigned char *src, size_t *to_length)
+                                 size_t *to_length) noexcept nogil
+    unsigned char *PQunescapeBytea(const unsigned char *src,
+                                   size_t *to_length) noexcept nogil
 
     # 33.4. Asynchronous Command Processing
-    int PQsendQuery(PGconn *conn, const char *command) nogil
+    int PQsendQuery(PGconn *conn, const char *command) noexcept nogil
     int PQsendQueryParams(PGconn *conn,
                           const char *command,
                           int nParams,
@@ -231,78 +243,84 @@ cdef extern from "libpq-fe.h":
                           const char * const *paramValues,
                           const int *paramLengths,
                           const int *paramFormats,
-                          int resultFormat) nogil
+                          int resultFormat) noexcept nogil
     int PQsendPrepare(PGconn *conn,
                       const char *stmtName,
                       const char *query,
                       int nParams,
-                      const Oid *paramTypes) nogil
+                      const Oid *paramTypes) noexcept nogil
     int PQsendQueryPrepared(PGconn *conn,
                             const char *stmtName,
                             int nParams,
                             const char * const *paramValues,
                             const int *paramLengths,
                             const int *paramFormats,
-                            int resultFormat) nogil
-    int PQsendDescribePrepared(PGconn *conn, const char *stmtName) nogil
-    int PQsendDescribePortal(PGconn *conn, const char *portalName) nogil
-    int PQsendClosePrepared(PGconn *conn, const char *stmtName) nogil
-    int PQsendClosePortal(PGconn *conn, const char *portalName) nogil
-    PGresult *PQgetResult(PGconn *conn) nogil
-    int PQconsumeInput(PGconn *conn) nogil
-    int PQisBusy(PGconn *conn) nogil
-    int PQsetnonblocking(PGconn *conn, int arg) nogil
-    int PQisnonblocking(const PGconn *conn)
-    int PQflush(PGconn *conn) nogil
+                            int resultFormat) noexcept nogil
+    int PQsendDescribePrepared(PGconn *conn, const char *stmtName) noexcept nogil
+    int PQsendDescribePortal(PGconn *conn, const char *portalName) noexcept nogil
+    int PQsendClosePrepared(PGconn *conn, const char *stmtName) noexcept nogil
+    int PQsendClosePortal(PGconn *conn, const char *portalName) noexcept nogil
+    PGresult *PQgetResult(PGconn *conn) noexcept nogil
+    int PQconsumeInput(PGconn *conn) noexcept nogil
+    int PQisBusy(PGconn *conn) noexcept nogil
+    int PQsetnonblocking(PGconn *conn, int arg) noexcept nogil
+    int PQisnonblocking(const PGconn *conn) noexcept nogil
+    int PQflush(PGconn *conn) noexcept nogil
 
     # 32.6. Retrieving Query Results in Chunks
-    int PQsetSingleRowMode(PGconn *conn)
-    int PQsetChunkedRowsMode(PGconn *conn, int chunkSize)
+    int PQsetSingleRowMode(PGconn *conn) noexcept nogil
+    int PQsetChunkedRowsMode(PGconn *conn, int chunkSize) noexcept nogil
 
     # 34.7. Canceling Queries in Progress
-    PGcancelConn *PQcancelCreate(PGconn *conn)
-    int PQcancelStart(PGcancelConn *cancelConn)
-    int PQcancelBlocking(PGcancelConn *cancelConn)
-    PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn) nogil
-    ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn)
-    int PQcancelSocket(PGcancelConn *cancelConn)
-    char *PQcancelErrorMessage(const PGcancelConn *cancelConn)
-    void PQcancelReset(PGcancelConn *cancelConn)
-    void PQcancelFinish(PGcancelConn *cancelConn)
-    PGcancel *PQgetCancel(PGconn *conn)
-    void PQfreeCancel(PGcancel *cancel)
-    int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
+    PGcancelConn *PQcancelCreate(PGconn *conn) noexcept nogil
+    int PQcancelStart(PGcancelConn *cancelConn) noexcept nogil
+    int PQcancelBlocking(PGcancelConn *cancelConn) noexcept nogil
+    PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn) noexcept nogil
+    ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn) noexcept nogil
+    int PQcancelSocket(PGcancelConn *cancelConn) noexcept nogil
+    char *PQcancelErrorMessage(const PGcancelConn *cancelConn) noexcept nogil
+    void PQcancelReset(PGcancelConn *cancelConn) noexcept nogil
+    void PQcancelFinish(PGcancelConn *cancelConn) noexcept nogil
+    PGcancel *PQgetCancel(PGconn *conn) noexcept nogil
+    void PQfreeCancel(PGcancel *cancel) noexcept nogil
+    int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize) noexcept nogil
 
     # 33.8. Asynchronous Notification
-    PGnotify *PQnotifies(PGconn *conn) nogil
+    PGnotify *PQnotifies(PGconn *conn) noexcept nogil
 
     # 33.9. Functions Associated with the COPY Command
-    int PQputCopyData(PGconn *conn, const char *buffer, int nbytes) nogil
-    int PQputCopyEnd(PGconn *conn, const char *errormsg) nogil
-    int PQgetCopyData(PGconn *conn, char **buffer, int async) nogil
+    int PQputCopyData(PGconn *conn, const char *buffer, int nbytes) noexcept nogil
+    int PQputCopyEnd(PGconn *conn, const char *errormsg) noexcept nogil
+    int PQgetCopyData(PGconn *conn, char **buffer, int async) noexcept nogil
 
     # 33.10. Control Functions
-    void PQtrace(PGconn *conn, FILE *stream)
-    void PQsetTraceFlags(PGconn *conn, int flags)
-    void PQuntrace(PGconn *conn)
+    void PQtrace(PGconn *conn, FILE *stream) noexcept nogil
+    void PQsetTraceFlags(PGconn *conn, int flags) noexcept nogil
+    void PQuntrace(PGconn *conn) noexcept nogil
 
     # 33.11. Miscellaneous Functions
-    void PQfreemem(void *ptr) nogil
-    void PQconninfoFree(PQconninfoOption *connOptions)
-    char *PQencryptPasswordConn(
-        PGconn *conn, const char *passwd, const char *user, const char *algorithm)
-    PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd)
-    PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
-    int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs)
-    int PQlibVersion()
+    void PQfreemem(void *ptr) noexcept nogil
+    void PQconninfoFree(PQconninfoOption *connOptions) noexcept nogil
+    char *PQencryptPasswordConn(PGconn *conn,
+                                const char *passwd,
+                                const char *user,
+                                const char *algorithm) noexcept nogil
+    PGresult *PQchangePassword(PGconn *conn,
+                               const char *user,
+                               const char *passwd) noexcept nogil
+    PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status) noexcept nogil
+    int PQsetResultAttrs(PGresult *res,
+                         int numAttributes,
+                         PGresAttDesc *attDescs) noexcept nogil
+    int PQlibVersion() noexcept nogil
 
     # 33.12. Notice Processing
     ctypedef void (*PQnoticeReceiver)(void *arg, const PGresult *res)
     PQnoticeReceiver PQsetNoticeReceiver(
-        PGconn *conn, PQnoticeReceiver prog, void *arg)
+        PGconn *conn, PQnoticeReceiver prog, void *arg) noexcept nogil
 
     # 33.18. SSL Support
-    void PQinitOpenSSL(int do_ssl, int do_crypto)
+    void PQinitOpenSSL(int do_ssl, int do_crypto) noexcept nogil
 
     # 34.5 Pipeline Mode
 
@@ -311,11 +329,11 @@ cdef extern from "libpq-fe.h":
         PQ_PIPELINE_ON
         PQ_PIPELINE_ABORTED
 
-    PGpipelineStatus PQpipelineStatus(const PGconn *conn)
-    int PQenterPipelineMode(PGconn *conn)
-    int PQexitPipelineMode(PGconn *conn)
-    int PQpipelineSync(PGconn *conn)
-    int PQsendFlushRequest(PGconn *conn)
+    PGpipelineStatus PQpipelineStatus(const PGconn *conn) noexcept nogil
+    int PQenterPipelineMode(PGconn *conn) noexcept nogil
+    int PQexitPipelineMode(PGconn *conn) noexcept nogil
+    int PQpipelineSync(PGconn *conn) noexcept nogil
+    int PQsendFlushRequest(PGconn *conn) noexcept nogil
 
 cdef extern from *:
     """