Skip to content

Commit d65d3f6

Browse files
A5rocksjakkdl
andauthored
Allow pickling Cancelled (#3250)
* Allow pickling `Cancelled` * Add newsfragment * Use `collections.abc.Callable` not `typing.Callable` * Fix coverage * Generalize __reduce__ * Address PR review Co-authored-by: jakkdl <[email protected]> * Add a test for coverage reasons * Revert generalization It's too much complexity to do it correctly. * Ensure that we get any extra cases that need pickling * Remove now-unnecessary new `__new__` --------- Co-authored-by: jakkdl <[email protected]>
1 parent 9135b3d commit d65d3f6

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

newsfragments/3248.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow pickling `trio.Cancelled`, as they can show up when you want to pickle something else. This does not rule out pickling other ``NoPublicConstructor`` objects -- create an issue if necessary.

src/trio/_core/_exceptions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
15
from trio._util import NoPublicConstructor, final
26

7+
if TYPE_CHECKING:
8+
from collections.abc import Callable
9+
310

411
class TrioInternalError(Exception):
512
"""Raised by :func:`run` if we encounter a bug in Trio, or (possibly) a
@@ -63,6 +70,9 @@ class Cancelled(BaseException, metaclass=NoPublicConstructor):
6370
def __str__(self) -> str:
6471
return "Cancelled"
6572

73+
def __reduce__(self) -> tuple[Callable[[], Cancelled], tuple[()]]:
74+
return (Cancelled._create, ())
75+
6676

6777
class BusyResourceError(Exception):
6878
"""Raised when a task attempts to use a resource that some other task is

src/trio/_core/_tests/test_run.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import contextvars
44
import functools
55
import gc
6+
import pickle
67
import sys
78
import threading
89
import time
@@ -2235,6 +2236,13 @@ def test_Cancelled_subclass() -> None:
22352236
type("Subclass", (_core.Cancelled,), {})
22362237

22372238

2239+
# https://github.com/python-trio/trio/issues/3248
2240+
def test_Cancelled_pickle() -> None:
2241+
cancelled = _core.Cancelled._create()
2242+
cancelled = pickle.loads(pickle.dumps(cancelled))
2243+
assert isinstance(cancelled, _core.Cancelled)
2244+
2245+
22382246
def test_CancelScope_subclass() -> None:
22392247
with pytest.raises(TypeError):
22402248
type("Subclass", (_core.CancelScope,), {})

0 commit comments

Comments
 (0)