Skip to content

Special attributes are not preserved for some builtin Exceptions (e.g. SystemExit) #87

@VmirGerts

Description

@VmirGerts

Hello :)
Thank you for maintaining this library!

Starting from version "3.2.0", the special "code" attribute of the SystemExit exception is not preserved after unpickling.
Raised from a sub-process, this can lead to a wrong exit code of a whole program.

Example (Ubuntu24.04, Python 3.12):

cat test_exit_code_multiprocessing.py

from concurrent.futures import ProcessPoolExecutor
import tblib.pickling_support

def _function_raising_exit(_x: int) -> None:
    raise SystemExit(42)

def test_exit_code():
    tblib.pickling_support.install()
    with ProcessPoolExecutor() as pool:
        return list(pool.map(_function_raising_exit, [1]))

if __name__ == "__main__":
    test_exit_code()

python test_exit_code_multiprocessing.py
echo $? --> is 0 instead of 42

For completeness, here is also a test which checks this behavior (similar to test_oserror from the repo):

def test_systemexit_error(clear_dispatch_table):
    try:
        raise SystemExit(42)
    except SystemExit as e:
        exc = e

    tblib.pickling_support.install(exc)
    exc = pickle.loads(pickle.dumps(exc))

    assert isinstance(exc, SystemExit)
    assert exc.code == 42
    assert exc.__traceback__ is not None

Note: There are also further builtin exceptions with special attributes which are also not preserved after unpickling.
I created here a draft PR with a few test cases and a proposal on how to fix it:
#86

Not sure if I overlooked some corner cases, but I hope it helps to find the best solution on how to fix it =)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions