ionelmc / python-tblib

Serialization library for Exceptions and Tracebacks.
BSD 2-Clause "Simplified" License
164 stars 33 forks source link

Implicit Exception chains are not pickled. #60

Open bernardpazio opened 4 years ago

bernardpazio commented 4 years ago

Explicit exceptions those given with the from syntax when raising an exception are pickled, however ones which are called with out this are not.

excepted:

def chain_exception():
    try:
        raise Exception('Foo')
    except Exception as ex:
        try:
            raise Exception('Bar')
        except Exception as e:
            raise Exception('explict') from e

chain_exception()
Exception chain ``` Traceback (most recent call last): File "", line 5, in chain_exception raise Exception('Foo') Exception: Foo During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 8, in chain_exception raise Exception('Bar') Exception: Bar The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/bert/.conda/envs/dask-dev/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3343, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "", line 12, in chain_exception() File "", line 10, in chain_exception raise Exception('explict') from e Exception: explict ```

after pickling:

import pickle
import tblib.pickling_support
tblib.pickling_support.install()

try:
    chain_exception()
except Exception as e:
    pickled_e = pickle.dumps(e, protocol=pickle.HIGHEST_PROTOCOL)

raise pickled_e
Exception chain ``` Traceback (most recent call last): File "", line 8, in chain_exception raise Exception('Bar') Exception: Bar The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/bert/.conda/envs/dask-dev/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3343, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "", line 8, in raise pickle.loads(pickled_e) File "", line 2, in chain_exception() File "", line 10, in chain_exception raise Exception('explict') from e Exception: explict ```

I believe this is simply due to the fact that __cause__ attribute is pickled but the __context__ one is not. See PEP 3134 for further details on this.