Skip to content

Commit d919f64

Browse files
Re-export parse_address and migrate fork-guard tests to pid-cache patch
Three small cycle-21 follow-ups: - ``parse_address`` was promoted to public in cycle 21 but never added to ``dqliteclient.__init__.py``'s ``__all__``. Cross-package consumers still had to reach into ``dqliteclient.connection``, re-introducing the cross-package private-API drift the rename was meant to close. Re-export it. - Fork-guard tests across the client and dbapi patched ``dqliteclient.connection.os.getpid``, ``dqliteclient.pool.os.getpid``, ``dqliteclient.cluster.os.getpid``, ``dqlitedbapi.connection.os.getpid``, and ``dqlitedbapi.aio.connection.os.getpid``. Cycle 21 moved every hot-path pid check from ``os.getpid()`` to a cached module attribute (``dqliteclient.connection._current_pid``) refreshed by ``os.register_at_fork``. The patches were dead code — the tests passed only because they also mutated ``_creator_pid`` directly. Migrate every patch to ``patch("dqliteclient.connection._current_pid", ...)`` so the test exercises the production read path it claims to. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9837cff commit d919f64

5 files changed

Lines changed: 12 additions & 6 deletions

src/dqliteclient/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"""
1111

1212
from dqliteclient.cluster import ClusterClient, RedirectPolicy, allowlist_policy
13-
from dqliteclient.connection import DqliteConnection
13+
from dqliteclient.connection import DqliteConnection, parse_address
1414
from dqliteclient.exceptions import (
1515
ClusterError,
1616
ClusterPolicyError,
@@ -48,6 +48,7 @@
4848
"OperationalError",
4949
"ProtocolError",
5050
"RedirectPolicy",
51+
"parse_address",
5152
"__version__",
5253
"allowlist_policy",
5354
"connect",

tests/test_cluster_client_fork_guard.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ async def test_find_leader_after_fork_raises_interface_error() -> None:
2929
cluster._creator_pid = fake_parent_pid
3030

3131
with (
32-
patch("dqliteclient.cluster.os.getpid", return_value=fake_parent_pid + 1),
32+
patch("dqliteclient.connection._current_pid", fake_parent_pid + 1),
3333
pytest.raises(InterfaceError, match="fork"),
3434
):
3535
await cluster.find_leader()

tests/test_connection_after_fork_raises.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test_dqlite_connection_close_after_fork_drops_inherited_state() -> None:
131131
conn._creator_pid = fake_parent_pid
132132

133133
async def run() -> None:
134-
with patch("dqliteclient.connection.os.getpid", return_value=fake_parent_pid + 1):
134+
with patch("dqliteclient.connection._current_pid", fake_parent_pid + 1):
135135
await conn.close()
136136

137137
asyncio.run(run())

tests/test_pool_close_fork_during_parent_close.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ async def test_close_with_pid_mismatch_returns_even_when_closed_with_pending_eve
6161

6262
# Bound the await so a regression manifests as a clean failure
6363
# instead of a hung test.
64-
with patch("dqliteclient.pool.os.getpid", return_value=fake_parent_pid + 1):
64+
with patch("dqliteclient.connection._current_pid", fake_parent_pid + 1):
6565
await asyncio.wait_for(pool.close(), timeout=1.0)
6666

6767
# Local state flipped, no wait happened.
@@ -80,7 +80,7 @@ async def test_close_with_pid_mismatch_returns_even_when_closed_with_no_event()
8080
fake_parent_pid = pool._creator_pid + 1
8181
pool._creator_pid = fake_parent_pid
8282

83-
with patch("dqliteclient.pool.os.getpid", return_value=fake_parent_pid + 1):
83+
with patch("dqliteclient.connection._current_pid", fake_parent_pid + 1):
8484
await asyncio.wait_for(pool.close(), timeout=1.0)
8585

8686
assert pool._closed is True

tests/test_transaction_fork_diagnostic.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ async def test_transaction_after_fork_raises_fork_diagnostic_not_cross_task() ->
4040
fake_parent_pid = conn._creator_pid + 1
4141
conn._creator_pid = fake_parent_pid
4242

43+
# Patch the module-level pid cache so the misuse guard observes a
44+
# fresh-process pid different from ``_creator_pid``. Cycle 21 moved
45+
# the hot-path pid check from ``os.getpid()`` to a cached module
46+
# attribute updated via ``os.register_at_fork``; patching
47+
# ``os.getpid`` would be dead code.
4348
with (
44-
patch("dqliteclient.connection.os.getpid", return_value=fake_parent_pid + 1),
49+
patch("dqliteclient.connection._current_pid", fake_parent_pid + 1),
4550
pytest.raises(InterfaceError, match="fork") as excinfo,
4651
):
4752
async with conn.transaction():

0 commit comments

Comments
 (0)