Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
2a9f84e
feat: add async support for PostgreSQL janitor and loader
tboy1337 Mar 13, 2026
526ee6c
test: enhance async tests for Database Janitor and Loader
tboy1337 Mar 13, 2026
2258c81
fix: improve error handling for missing optional dependencies in asyn…
tboy1337 Mar 13, 2026
5c92310
fix: resolve double plugin registration, add asyncio_mode and default…
tboy1337 Mar 13, 2026
ea71a07
Revert "fix: resolve double plugin registration, add asyncio_mode and…
tboy1337 Mar 13, 2026
990496a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 13, 2026
fe8c553
fix: enhance async fixture and retry tests
tboy1337 Mar 13, 2026
1384100
Merge branch 'async' of https://github.com/tboy1337/pytest-postgresql…
tboy1337 Mar 13, 2026
f16583a
refactor: update connection handling in AsyncDatabaseJanitor
tboy1337 Mar 13, 2026
38a5ae4
fix: add space in SQL query for connection termination
tboy1337 Mar 13, 2026
bdca11e
refactor: improve PostgreSQLExecutor and AsyncDatabaseJanitor handling
tboy1337 Mar 14, 2026
2267c00
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2026
717e81f
revert: remove Windows-specific changes deferred to PR-1182
tboy1337 Mar 14, 2026
685cb57
fix: resolve merge conflicts by keeping HEAD (exclude Windows changes…
tboy1337 Mar 14, 2026
83c7bae
refactor: enhance SQL query handling in DatabaseJanitor and AsyncData…
tboy1337 Mar 14, 2026
e9911ea
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2026
c23b364
fix: improve error handling in postgresql_async fixture
tboy1337 Mar 14, 2026
17d37ea
Merge branch 'async' of https://github.com/tboy1337/pytest-postgresql…
tboy1337 Mar 14, 2026
bfbff75
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2026
e2d10f2
fix: enhance postgresql_async fixture to provide synchronous stub whe…
tboy1337 Mar 14, 2026
24ec05d
Resolve merge conflict in factories/client.py: drop redundant in-body…
tboy1337 Mar 14, 2026
b40ac9d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2026
257e61d
feat: add async testing support and improve documentation
tboy1337 Jun 21, 2026
16b8ce3
refactor: streamline temporary directory creation in postgresql_proc …
tboy1337 Jun 21, 2026
c633ff6
Merge branch 'main' from dbfixtures/pytest-postgresql into async
tboy1337 Jun 21, 2026
bab9403
Fix xdist CI failures and raise patch coverage for async changes.
tboy1337 Jun 21, 2026
f4bf1b9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 21, 2026
c6390a5
Replace mock coverage tests with integration tests for async paths.
tboy1337 Jun 21, 2026
4cf5706
Fix postgresql_oldest and Windows CI failures for async support.
tboy1337 Jun 21, 2026
50377e1
Replace mock AsyncDatabaseJanitor SQL tests with Postgres integration…
tboy1337 Jun 21, 2026
91b7305
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 21, 2026
96289b8
Fix mypy errors in janitor integration test helpers.
tboy1337 Jun 21, 2026
8c866fc
Update pytest-asyncio dependency to version 0.24 in Pipfile and pypro…
tboy1337 Jun 21, 2026
18f04d7
Enhance README and client.py documentation for async fixtures, specif…
tboy1337 Jun 21, 2026
7c28065
Update error message in test for pytest-asyncio version requirement t…
tboy1337 Jun 21, 2026
2a51cd2
Update pytest-postgresql plugin to set Windows event loop policy cond…
tboy1337 Jun 21, 2026
34c3d47
Refactor password handling in janitor tests to address linting warnin…
tboy1337 Jun 21, 2026
b87cef4
Refactor fixture scope handling in PostgreSQL factories by removing t…
tboy1337 Jun 22, 2026
c98d05b
Update README to remove unnecessary version details for async fixture…
tboy1337 Jun 22, 2026
c5270ff
Update pytest-asyncio dependency to version 1.4 across configuration …
tboy1337 Jun 22, 2026
470b4aa
Enhance README to clarify the handling of Windows event loop policy w…
tboy1337 Jun 22, 2026
c21daac
Refactor Windows event loop handling in pytest-postgresql plugin to i…
tboy1337 Jun 22, 2026
679d8b9
Refactor pytest-asyncio loop factory implementation in the Windows co…
tboy1337 Jun 22, 2026
9bdf215
Add support for optional pytest-asyncio import in plugin.py
tboy1337 Jun 22, 2026
9e86627
ci: re-trigger workflow after runner communication flake on 3.10
tboy1337 Jun 22, 2026
214179f
Refactor loader functions to remove maxsplit in regex for import path…
tboy1337 Jun 22, 2026
4adf2ed
Enhance README and plugin.py to clarify Windows event loop handling f…
tboy1337 Jun 27, 2026
2cb91f2
Merge remote-tracking branch 'dbfixtures/main' into async
tboy1337 Jul 3, 2026
b5c27f0
Address fizyk review: CI for async extra, consolidate build_loader
tboy1337 Jul 13, 2026
62208bb
ci: harden workflow permissions and checkout credentials
tboy1337 Jul 13, 2026
ab73a27
ci: run async-extra jobs without waiting on postgresql_18
tboy1337 Jul 13, 2026
e711381
ci: scope workflow permissions to individual jobs
tboy1337 Jul 13, 2026
012efbf
ci: drop actions:write and harden async pytest env; sort factories __…
tboy1337 Jul 13, 2026
274b938
fix(ci): use GHA expressions for async pytest paths on Windows
tboy1337 Jul 13, 2026
d27f5f0
fix: guard port lock cleanup when port selection fails early
tboy1337 Jul 13, 2026
b781b33
fix: ensure foreign port lock files are preserved on exhausted retries
tboy1337 Jul 13, 2026
38c8771
fix: suppress exception chaining in port selection error message
tboy1337 Jul 13, 2026
cd7dcbe
fix: enhance async fixture handling and improve Windows event loop co…
tboy1337 Jul 13, 2026
5635e1a
fix: enhance async fixture support and improve documentation
tboy1337 Jul 13, 2026
53e2eb2
fix: enhance async fixture documentation and improve janitor configur…
tboy1337 Jul 13, 2026
3c77031
fix: update license file reference and enhance documentation for asyn…
tboy1337 Jul 13, 2026
747deba
docs: update rendered mermaid diagram [skip ci]
tboy1337 Jul 13, 2026
7e9b6b3
fix: enhance async fixture behavior and improve documentation
tboy1337 Jul 13, 2026
13ef883
Merge branch 'async' of https://github.com/tboy1337/pytest-postgresql…
tboy1337 Jul 13, 2026
876eeac
fix: handle None isolation level in database connections
tboy1337 Jul 13, 2026
c97c49b
fix: correct typos and update PostgreSQL version references
tboy1337 Jul 13, 2026
c501f4c
refactor: streamline janitor configuration with shared protocol
tboy1337 Jul 13, 2026
5d1ff05
refactor: simplify PostgreSQL path detection and enhance test structure
tboy1337 Jul 13, 2026
2d4c4b4
docs: update rendered mermaid diagram [skip ci]
tboy1337 Jul 13, 2026
3b08c32
Merge branch 'main' from dbfixtures/pytest-postgresql into async
tboy1337 Jul 14, 2026
2666f8c
fix: resolve CI failures for mypy, port-lock test, and Windows initdb
tboy1337 Jul 14, 2026
d9d7fe4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 14, 2026
cd42e3e
fix: use initdb.exe on Windows and avoid xdist port collisions in tea…
tboy1337 Jul 14, 2026
12ed487
fix: stabilize xdist port-lock tests and Windows async CI initdb
tboy1337 Jul 14, 2026
fad62e2
ci: use separate Windows step for async test bootstrap
tboy1337 Jul 14, 2026
f1b2240
fix: unify Windows async CI pytest command with Linux
tboy1337 Jul 14, 2026
7fd6ac7
fix: prepare initdb parent directory on Windows without pre-creating …
tboy1337 Jul 14, 2026
4e8fa12
fix: restore pg_ctl initdb on Windows and bootstrap async CI session
tboy1337 Jul 14, 2026
2209ae1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 14, 2026
632df8d
fix: pass only locale env to initdb and order bootstrap tests first
tboy1337 Jul 14, 2026
d090b6c
fix: merge process env for initdb while unsetting inherited PGDATA
tboy1337 Jul 14, 2026
6cfef63
fix: make postgresql_proc a non-generator session fixture
tboy1337 Jul 14, 2026
ea269f7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 14, 2026
e5dabeb
fix: align Windows async CI initdb with main executor behavior
tboy1337 Jul 14, 2026
a3fae2c
fix: use flat Windows pgdata path outside pytest temp parents
tboy1337 Jul 14, 2026
4d2872d
fix: keep Windows postgres logs beside flat pgdata paths
tboy1337 Jul 14, 2026
d1a0e86
fix: default Windows asyncio tests to SelectorEventLoop
tboy1337 Jul 14, 2026
ca251ae
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 14, 2026
b4ec0b3
fix: satisfy mypy in port-lock tests and stabilize Windows plugin tests
tboy1337 Jul 14, 2026
23bca9a
fix: make janitor drop idempotent and stabilize legacy policy test
tboy1337 Jul 14, 2026
ccda153
fix: refactor Windows initdb command test to use monkeypatch
tboy1337 Jul 14, 2026
bcd5c8b
fix: enhance PostgreSQLExecutor environment handling and improve test…
tboy1337 Jul 14, 2026
d859a44
refactor: improve PostgreSQLExecutor initialization and enhance test …
tboy1337 Jul 14, 2026
2679b40
Fix CI failures for Windows pg_ctl log paths and docker async load test.
tboy1337 Jul 14, 2026
2697bda
ci: re-trigger workflows after stuck xdist runner on postgresql_18 (3…
tboy1337 Jul 14, 2026
6f64fef
Fix xdist teardown hang by skipping rmtree while PostgreSQL is running.
tboy1337 Jul 14, 2026
4a66e1c
fix: improve password handling in PostgreSQLExecutor initialization
tboy1337 Jul 14, 2026
4a23843
fix: improve async handling in janitor and update test structure
tboy1337 Jul 14, 2026
8c61f4f
ci: harden oldest-postgres workflow against xdist hangs
tboy1337 Jul 14, 2026
6f833af
ci: add 30-minute job timeout to all PostgreSQL test workflows
tboy1337 Jul 14, 2026
1e8ab5f
fix: enhance error handling and resource management in PostgreSQLExec…
tboy1337 Jul 14, 2026
3f921ed
fix: update initdb command options for Windows compatibility
tboy1337 Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions newsfragments/1235.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Added async PostgreSQL fixture support via ``postgresql_async`` factory and ``AsyncDatabaseJanitor``.
Added configurable fixture ``scope`` parameter to ``postgresql``, ``postgresql_async``, ``postgresql_proc``, and ``postgresql_noproc`` factories (defaults preserved: ``"function"`` for client fixtures, ``"session"`` for process fixtures).
Added optional ``async`` extra (``pip install pytest-postgresql[async]``) providing ``pytest-asyncio`` and ``aiofiles`` dependencies.
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ dependencies = [
]
requires-python = ">= 3.10"

[project.optional-dependencies]
async = [
"pytest-asyncio >= 0.21",
"aiofiles >= 23.0"
]

[project.urls]
"Source" = "https://github.com/dbfixtures/pytest-postgresql"
"Bug Tracker" = "https://github.com/dbfixtures/pytest-postgresql/issues"
Expand Down
4 changes: 2 additions & 2 deletions pytest_postgresql/factories/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
# along with pytest-postgresql. If not, see <http://www.gnu.org/licenses/>.
"""Fixture factories for postgresql fixtures."""

from pytest_postgresql.factories.client import postgresql
from pytest_postgresql.factories.client import postgresql, postgresql_async
from pytest_postgresql.factories.noprocess import postgresql_noproc
from pytest_postgresql.factories.process import PortType, postgresql_proc

__all__ = ("postgresql_proc", "postgresql_noproc", "postgresql", "PortType")
__all__ = ("postgresql_proc", "postgresql_noproc", "postgresql", "postgresql_async", "PortType")
87 changes: 82 additions & 5 deletions pytest_postgresql/factories/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,44 @@
# along with pytest-postgresql. If not, see <http://www.gnu.org/licenses/>.
"""Fixture factory for postgresql client."""

from typing import Callable, Iterator
from typing import AsyncIterator, Callable, Iterator

import psycopg
import pytest
from psycopg import Connection
from psycopg import AsyncConnection, Connection
from pytest import FixtureRequest

try:
import pytest_asyncio
except ImportError:
pytest_asyncio = None # type: ignore[assignment]

from pytest_postgresql.config import get_config
from pytest_postgresql.executor import PostgreSQLExecutor
from pytest_postgresql.executor_noop import NoopExecutor
from pytest_postgresql.janitor import DatabaseJanitor
from pytest_postgresql.janitor import AsyncDatabaseJanitor, DatabaseJanitor
from pytest_postgresql.types import FixtureScopeT


def postgresql(
process_fixture_name: str,
dbname: str | None = None,
isolation_level: "psycopg.IsolationLevel | None" = None,
scope: FixtureScopeT = "function",
Comment thread
tboy1337 marked this conversation as resolved.
Outdated
) -> Callable[[FixtureRequest], Iterator[Connection]]:
"""Return connection fixture factory for PostgreSQL.

:param process_fixture_name: name of the process fixture
:param dbname: database name
:param isolation_level: optional postgresql isolation level
defaults to server's default
:param scope: fixture scope; by default "function" which is recommended.
:returns: function which makes a connection to postgresql
"""

@pytest.fixture
@pytest.fixture(scope=scope)
def postgresql_factory(request: FixtureRequest) -> Iterator[Connection]:
"""Fixture factory for PostgreSQL.
"""Fixture connection factory for PostgreSQL.

:param request: fixture request object
:returns: postgresql client
Expand Down Expand Up @@ -85,3 +93,72 @@ def postgresql_factory(request: FixtureRequest) -> Iterator[Connection]:
db_connection.close()

return postgresql_factory


def postgresql_async(
process_fixture_name: str,
dbname: str | None = None,
isolation_level: "psycopg.IsolationLevel | None" = None,
scope: FixtureScopeT = "function",
) -> Callable[[FixtureRequest], AsyncIterator[AsyncConnection]]:
"""Return async connection fixture factory for PostgreSQL.

:param process_fixture_name: name of the process fixture
:param dbname: database name
:param isolation_level: optional postgresql isolation level
defaults to server's default
:param scope: fixture scope; by default "function" which is recommended.
:returns: function which makes an async connection to postgresql
"""
if pytest_asyncio is None:

@pytest.fixture(scope=scope)
def postgresql_async_factory(request: FixtureRequest) -> None:
"""Sync stub that raises ImportError when pytest-asyncio is absent."""
raise ImportError(
"pytest-asyncio is required for async fixtures. Install it with: pip install pytest-postgresql[async]"
)

return postgresql_async_factory # type: ignore[return-value]

@pytest_asyncio.fixture(scope=scope, loop_scope=scope)
async def postgresql_async_factory(request: FixtureRequest) -> AsyncIterator[AsyncConnection]:
"""Async connection fixture factory for PostgreSQL.

:param request: fixture request object
:returns: postgresql async client
"""
proc_fixture: PostgreSQLExecutor | NoopExecutor = request.getfixturevalue(process_fixture_name)
config = get_config(request)

pg_host = proc_fixture.host
pg_port = proc_fixture.port
pg_user = proc_fixture.user
pg_password = proc_fixture.password
pg_options = proc_fixture.options
pg_db = dbname or proc_fixture.dbname
janitor = AsyncDatabaseJanitor(
user=pg_user,
host=pg_host,
port=pg_port,
dbname=pg_db,
template_dbname=proc_fixture.template_dbname,
version=proc_fixture.version,
password=pg_password,
isolation_level=isolation_level,
)
if config.drop_test_database:
await janitor.drop()
async with janitor:
db_connection: AsyncConnection = await AsyncConnection.connect(
dbname=pg_db,
user=pg_user,
password=pg_password,
host=pg_host,
port=pg_port,
options=pg_options,
)
yield db_connection
await db_connection.close()

return postgresql_async_factory
5 changes: 4 additions & 1 deletion pytest_postgresql/factories/noprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pytest_postgresql.config import get_config
from pytest_postgresql.executor_noop import NoopExecutor
from pytest_postgresql.janitor import DatabaseJanitor
from pytest_postgresql.types import FixtureScopeT


def xdistify_dbname(dbname: str) -> str:
Expand All @@ -46,6 +47,7 @@ def postgresql_noproc(
options: str = "",
load: list[Callable | str | Path] | None = None,
depends_on: str | None = None,
scope: FixtureScopeT = "session",
) -> Callable[[FixtureRequest], Iterator[NoopExecutor]]:
"""Postgresql noprocess factory.

Expand All @@ -57,10 +59,11 @@ def postgresql_noproc(
:param options: Postgresql connection options
:param load: List of functions used to initialize database's template.
:param depends_on: Optional name of the fixture to depend on.
:param scope: fixture scope; by default "session" which is recommended.
:returns: function which makes a postgresql process
"""

@pytest.fixture(scope="session")
@pytest.fixture(scope=scope)
def postgresql_noproc_fixture(request: FixtureRequest) -> Iterator[NoopExecutor]:
"""Noop Process fixture for PostgreSQL.

Expand Down
5 changes: 4 additions & 1 deletion pytest_postgresql/factories/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from pytest_postgresql.exceptions import ExecutableMissingException
from pytest_postgresql.executor import PostgreSQLExecutor
from pytest_postgresql.janitor import DatabaseJanitor
from pytest_postgresql.types import FixtureScopeT

PortType = port_for.PortType # mypy requires explicit export

Expand Down Expand Up @@ -81,6 +82,7 @@ def postgresql_proc(
unixsocketdir: str | None = None,
postgres_options: str | None = None,
load: list[Callable | str | Path] | None = None,
scope: FixtureScopeT = "session",
) -> Callable[[FixtureRequest, TempPathFactory], Iterator[PostgreSQLExecutor]]:
"""Postgresql process factory.

Expand All @@ -101,10 +103,11 @@ def postgresql_proc(
:param unixsocketdir: directory to create postgresql's unixsockets
:param postgres_options: Postgres executable options for use by pg_ctl
:param load: List of functions used to initialize database's template.
:param scope: fixture scope; by default "session" which is recommended.
:returns: function which makes a postgresql process
"""

@pytest.fixture(scope="session")
@pytest.fixture(scope=scope)
def postgresql_proc_fixture(
request: FixtureRequest, tmp_path_factory: TempPathFactory
) -> Iterator[PostgreSQLExecutor]:
Expand Down
Loading