]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Errors can be pickled
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 28 Oct 2020 19:26:01 +0000 (20:26 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 28 Oct 2020 21:05:58 +0000 (22:05 +0100)
psycopg3/psycopg3/errors.py
tests/test_connection.py
tests/test_connection_async.py
tests/test_errors.py

index f69109a0bb59b0a9c241335a9741600f5ff7bb64..96279fc17f1df66507d17d4c076e1cf40b887b93 100644 (file)
@@ -18,7 +18,7 @@ DBAPI-defined Exceptions are defined in the following hierarchy::
 
 # Copyright (C) 2020 The Psycopg Team
 
-from typing import Any, Callable, Dict, Optional, Sequence, Type
+from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, Union
 from psycopg3.pq.proto import PGresult
 from psycopg3.pq.enums import DiagnosticField
 
@@ -50,6 +50,13 @@ class Error(Exception):
     def diag(self) -> "Diagnostic":
         return Diagnostic(self.pgresult, encoding=self._encoding)
 
+    def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
+        res = super().__reduce__()
+        if isinstance(res, tuple) and len(res) >= 3:
+            res[2]['pgresult'] = None
+
+        return res
+
 
 class InterfaceError(Error):
     """
index eb00c6b3d4073674b1736d4adfba7f3a432a07ac..2d741a020e344a7d76860fc7b9cb8634cc986f62 100644 (file)
@@ -31,10 +31,16 @@ def test_close(conn):
     conn.close()
     assert conn.closed
     assert conn.status == conn.ConnStatus.BAD
+
+    cur = conn.cursor()
+
     conn.close()
     assert conn.closed
     assert conn.status == conn.ConnStatus.BAD
 
+    with pytest.raises(psycopg3.InterfaceError):
+        cur.execute("select 1")
+
 
 def test_weakref(dsn):
     conn = psycopg3.connect(dsn)
index 0e23dc7516575f989c064114643f5e512d716b49..daa8aad034175de814f623b057659c2ebdbb4818 100644 (file)
@@ -34,10 +34,16 @@ async def test_close(aconn):
     await aconn.close()
     assert aconn.closed
     assert aconn.status == aconn.ConnStatus.BAD
+
+    cur = aconn.cursor()
+
     await aconn.close()
     assert aconn.closed
     assert aconn.status == aconn.ConnStatus.BAD
 
+    with pytest.raises(psycopg3.InterfaceError):
+        await cur.execute("select 1")
+
 
 async def test_weakref(dsn):
     conn = await psycopg3.AsyncConnection.connect(dsn)
index d7f58cf6978eedb650cd9f3ef0afc6bbdc7a5b87..b4b34750c5b313fd87088c62f1ffb78fc2d2ce4f 100644 (file)
@@ -1,4 +1,7 @@
+import pickle
+
 import pytest
+
 from psycopg3 import pq
 from psycopg3 import errors as e
 
@@ -103,3 +106,13 @@ def test_lookup():
 
     with pytest.raises(KeyError):
         e.lookup("XXXXX")
+
+
+def test_error_pickle(conn):
+    cur = conn.cursor()
+    with pytest.raises(e.DatabaseError) as excinfo:
+        cur.execute("select 1 from wat")
+
+    exc = pickle.loads(pickle.dumps(excinfo.value))
+    assert isinstance(exc, e.UndefinedTable)
+    assert exc.pgresult is None