|
1 | 1 | import gc |
2 | | -import logging |
3 | 2 | import os |
4 | 3 | import subprocess |
5 | 4 | from pathlib import Path |
| 5 | +import pickle |
| 6 | +import warnings |
6 | 7 |
|
7 | 8 | import pytest |
8 | 9 |
|
9 | 10 | from traceback import ( |
10 | 11 | extract_tb, |
11 | 12 | print_exception, |
12 | | - format_exception, |
13 | 13 | ) |
14 | 14 | from traceback import _cause_message # type: ignore |
15 | 15 | import sys |
@@ -555,3 +555,36 @@ def test_apport_excepthook_monkeypatch_interaction(): |
555 | 555 | ["--- 1 ---", "KeyError", "--- 2 ---", "ValueError"], |
556 | 556 | stdout, |
557 | 557 | ) |
| 558 | + |
| 559 | + |
| 560 | +@pytest.mark.parametrize("protocol", range(0, pickle.HIGHEST_PROTOCOL + 1)) |
| 561 | +def test_pickle_multierror(protocol) -> None: |
| 562 | + # use trio.MultiError to make sure that pickle works through the deprecation layer |
| 563 | + import trio |
| 564 | + |
| 565 | + my_except = ZeroDivisionError() |
| 566 | + |
| 567 | + try: |
| 568 | + 1 / 0 |
| 569 | + except ZeroDivisionError as e: |
| 570 | + my_except = e |
| 571 | + |
| 572 | + # MultiError will collapse into different classes depending on the errors |
| 573 | + for cls, errors in ( |
| 574 | + (ZeroDivisionError, [my_except]), |
| 575 | + (NonBaseMultiError, [my_except, ValueError()]), |
| 576 | + (MultiError, [BaseException(), my_except]), |
| 577 | + ): |
| 578 | + with warnings.catch_warnings(): |
| 579 | + warnings.simplefilter("ignore", TrioDeprecationWarning) |
| 580 | + me = trio.MultiError(errors) # type: ignore[attr-defined] |
| 581 | + dump = pickle.dumps(me, protocol=protocol) |
| 582 | + load = pickle.loads(dump) |
| 583 | + assert repr(me) == repr(load) |
| 584 | + assert me.__class__ == load.__class__ == cls |
| 585 | + |
| 586 | + assert me.__dict__.keys() == load.__dict__.keys() |
| 587 | + for me_val, load_val in zip(me.__dict__.values(), load.__dict__.values()): |
| 588 | + # tracebacks etc are not preserved through pickling for the default |
| 589 | + # exceptions, so we only check that the repr stays the same |
| 590 | + assert repr(me_val) == repr(load_val) |
0 commit comments