Since Mypy 1.20 the SQLite cache is used by default. This highlights
Mypy concurrency issues running pre-commit in the CI, which are known to
the project devs but which we practically never encountered using the
file-based cache. See https://github.com/python/mypy/issues/21136.
The alternative solution of avoiding parallel Mypy runs in pre-commit
using `require_serial: false`, reveals other issues such as
https://github.com/python/mypy/issues/17362.
An alternative which would probably work could be to pass no file names
to mypy and re-mypy the entire codebase at every commit using
`pass_filenames: false`. See https://github.com/python/mypy/issues/13916.
This for me seems about 25% slower when changing a single file.
This commit restores the 1.19 behaviour of using the file-based cache,
which was working adequately for us. In the future we may decide to move
to `pass_filenames: false`.
Eric Buehl [Wed, 18 Mar 2026 17:30:54 +0000 (10:30 -0700)]
fix: premature ConnectionTimeout
When time.monotonic() returns a large value (e.g. on a long-running system, or when patched by a time-mocking library) causes ConnectionTimeout to fire immediately.
Gabor Gevay [Wed, 18 Feb 2026 10:06:25 +0000 (11:06 +0100)]
Fix ValueError when server sends ErrorResponse during Sync after Parse
When using prepared statements, psycopg sends Parse+Sync via
PQsendPrepare and assumes libpq returns exactly one PGresult.
However, the PostgreSQL wire protocol allows ErrorResponse during
Sync processing (e.g., when an implicit transaction commit fails).
In this case, libpq returns two PGresult objects — one for the
successful ParseComplete and one for the ErrorResponse — causing
a ValueError: "too many values to unpack (expected 1)".
This commit handles multiple results from PQsendPrepare by
iterating over all returned results and checking each for errors,
consistent with how the non-prepare execute path already works.
Varun Chawla [Tue, 10 Feb 2026 08:11:28 +0000 (00:11 -0800)]
fix: correct typo in tstrings error message and fix sql.rst docs
- Fix error message in _tstrings.py: reference nonexistent "sql.Composite"
corrected to "sql.Composable" (the actual base class)
- Fix docs/api/sql.rst: remove incorrect escape_identifier() example that
passed a str where bytes is required (closes #421)
- Fix typo "re-exoprts" -> "re-exports" in conninfo.py
Co-Authored-By: Claude Opus 4.6
Note: this MR is AI slop which has been pushed by the author without
even considering if it was correct. Corrected by a human being in the
next commit on this branch.
This PR adds critical sections to the PGconn class so that
race condition between calling into the libpq bindings and
calling `close` which sets the `_pgconn_ptr` to NULL are
eliminated.
Also add one high-level and one low-level tests that trigger TSAN
warnings without this PR.
Erik Wienhold [Wed, 14 Jan 2026 13:42:18 +0000 (14:42 +0100)]
fix: retain pgconn on OperationalError
When multiple connection attempts fail, a new OperationalError with the
combined attempt errors is raised without retaining the pgconn attribute
of the original attempt errors. Fix this by assigning the pgconn from
the last attempt error.
dependabot[bot] [Thu, 1 Jan 2026 07:10:50 +0000 (07:10 +0000)]
chore(deps): bump the actions group with 2 updates
Bumps the actions group with 2 updates: [actions/cache](https://github.com/actions/cache) and [actions/upload-artifact](https://github.com/actions/upload-artifact).
Updates `actions/cache` from 4 to 5
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)
Updates `actions/upload-artifact` from 5 to 6
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)
dependabot[bot] [Mon, 1 Dec 2025 07:39:07 +0000 (07:39 +0000)]
chore(deps): bump the actions group with 2 updates
Bumps the actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel).
Updates `actions/checkout` from 5 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)
Updates `pypa/cibuildwheel` from 3.2.1 to 3.3.0
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.2.1...v3.3.0)
fix(adapters): avoid race condition when replacing class name with itself
Another thread may be switched to between the dmap.pop(fqn) instruction
and the dmap[scls] one, typically at program startup when multiple
threads are making their "first" queries.
fix: mark external libpq C functions as noexcept nogil
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.
Avoid installing Mypy as part of the tests extra: installation fails
because a binary librt is not available. As a consequence, avoid running
Mypy-based tests in test CI jobs on PyPy.
The functions are exported by the psycopg.sql module but are primarily
useful for template strings support, to allow building SQL queries
dynamically using t-strings.
instead of gettgin an error such as "COPY cannot be used with this method".
Please check https://github.com/psycopg/psycopg/issues/71#issuecomment-3393722855
for the description of the db configuration required to make this command work.
No further support for logical replication is planned at this moment, but this
change allows to play with replication without needing to go down at libpq
level to execute replication commands.
Daniele Varrazzo [Sat, 22 Nov 2025 17:06:08 +0000 (18:06 +0100)]
fix: improve set_result() proposal:
- make it async on async cursors (consistently with `results()`,
inconsistently with `nextset()`, but the latter being sync on async
cursors was a design mistake);
- raise IndexError, consistently with sequences, better error message;
- fix test, which were simply broken and the OP didn't bother to fix
them;
- documentation improved.
Daniele Varrazzo [Fri, 21 Nov 2025 10:36:39 +0000 (11:36 +0100)]
fix(pool): trap CancelledError more consistently in the pool codebase
Include also places that were left out such as the rollback and the task
scheduling.
Note that we are relaxing the exception handler we had set up to fix the
problem with cancelled clients on wait (#509): we only had to trap
CancelledError additionally but we started managing the whole
BaseException. I don't think that trapping KeyboardException or
SystemExit without re-raising is a good idea (I think that, for
robustness, we should, but then things become very verbose and not
necessarily correct).
Daniele Varrazzo [Wed, 19 Nov 2025 23:51:43 +0000 (00:51 +0100)]
fix(pool): manage CancelledError in some exception handling path
If a CancelledError was raised during check the connection would have
been lost. The exception would have bubbled up but likely users are
using some framework swallowing it because nobody reporting the "lost
connections" issue actually reported the CancelledError.
dependabot[bot] [Fri, 7 Nov 2025 11:50:14 +0000 (11:50 +0000)]
chore(deps): bump the actions group with 2 updates
Bumps the actions group with 2 updates: [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) and [actions/upload-artifact](https://github.com/actions/upload-artifact).
Updates `pypa/cibuildwheel` from 3.2.0 to 3.2.1
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.2.0...v3.2.1)
Updates `actions/upload-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)
Daniele Varrazzo [Mon, 27 Oct 2025 01:14:35 +0000 (01:14 +0000)]
refactor: use make_instance instead of use_keywords
This model is more similar to psycopg2 and allow more freedom to define
how to return a class. There could be a mix of positional and keyword
arguments for example.
Sean Stewart [Tue, 15 Oct 2024 21:50:51 +0000 (17:50 -0400)]
feat: support loading composite types with keyword arguments
Changes:
1. Add `KeywordComposite*` classes to support loading composite types with keyword arguments.
2. Some optimizations for the `*BinaryLoader`.
- Use a generator to unpack (oid, value) pairs.
- Use a membership check instead of `KeyError` to optimize hot loops when looking up transformers.
3. Generics for the `*InstanceLoader` so mypy can better-track output results.
---
Co-authored by Daniele Varrazzo, mostly rebasing the feature on the
refactoring happening in the composite loading in #1175 and applying
some suggested PR changes.
refactor: cleaner inheritance in record/composite loaders
- Avoid a common base class to reuse the code, use module-level
functions.
- Make the inheritance lines of text and binary loaders similar.
- Add documentation and notes.
This refactoring is in preparation of the implementation of these
loaders in C, to clarify and simplify things. See #1175.