Skip to content

Commit 644c530

Browse files
Pin remaining deepcopy and copy.copy paths for pickle-guard classes
The __reduce__ raise should already cover all three operations (pickle.dumps, copy.copy, copy.deepcopy — the latter two route through __reduce_ex__(2) which delegates to __reduce__). Only DqliteConnection / ConnectionPool had the full three-way matrix pinned; ClusterClient was missing deepcopy and DqliteProtocol was missing both copy.copy and copy.deepcopy. Pin the gaps so a future "raise from __reduce_ex__ only on protocol >= 2" regression or a custom __copy__ / __deepcopy__ accidentally added to one of these classes is caught. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a95d15e commit 644c530

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

tests/test_pickle_guards.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ def test_copy_copy_raises(self) -> None:
7676
with pytest.raises(TypeError, match="ClusterClient"):
7777
copy.copy(cluster)
7878

79+
def test_copy_deepcopy_raises(self) -> None:
80+
cluster = ClusterClient(node_store=MemoryNodeStore(["localhost:9001"]))
81+
with pytest.raises(TypeError, match="ClusterClient"):
82+
copy.deepcopy(cluster)
83+
7984

8085
class TestDqliteProtocolPickleGuard:
8186
def test_pickle_raises(self) -> None:
@@ -89,3 +94,27 @@ def test_pickle_raises(self) -> None:
8994
proto = DqliteProtocol(reader=reader, writer=writer)
9095
with pytest.raises(TypeError, match="DqliteProtocol"):
9196
pickle.dumps(proto)
97+
98+
def test_copy_copy_raises(self) -> None:
99+
import asyncio
100+
from unittest.mock import MagicMock
101+
102+
from dqliteclient.protocol import DqliteProtocol
103+
104+
reader = MagicMock(spec=asyncio.StreamReader)
105+
writer = MagicMock(spec=asyncio.StreamWriter)
106+
proto = DqliteProtocol(reader=reader, writer=writer)
107+
with pytest.raises(TypeError, match="DqliteProtocol"):
108+
copy.copy(proto)
109+
110+
def test_copy_deepcopy_raises(self) -> None:
111+
import asyncio
112+
from unittest.mock import MagicMock
113+
114+
from dqliteclient.protocol import DqliteProtocol
115+
116+
reader = MagicMock(spec=asyncio.StreamReader)
117+
writer = MagicMock(spec=asyncio.StreamWriter)
118+
proto = DqliteProtocol(reader=reader, writer=writer)
119+
with pytest.raises(TypeError, match="DqliteProtocol"):
120+
copy.deepcopy(proto)

0 commit comments

Comments
 (0)