Title: Fix pickling exceptions with multiple arguments
Type: behavior Stage:
Components: Interpreter Core Versions: Python 2.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Kirill Matsaberydze, alexandre.vassalotti, benoit-pierre, georg.brandl, jason.coombs, orivej, sbt, slallum, zseil
Priority: normal Keywords:

Created on 2018-01-28 16:15 by slallum, last changed 2018-10-29 19:30 by benoit-pierre.

Messages (3)
msg310963 - (view) Author: Ofer (slallum) Date: 2018-01-28 16:15
Pickling exceptions fails when a custom exception class requires multiple arguments.

import pickle
class MultipleArgumentsError(Exception):
    def __init__(self, a, b):
        self.a = a
        self.b = b

pickle.loads(pickle.dumps(MultipleArgumentsError('a', 'b')))

this code produces the following error:

Traceback (most recent call last):
  File "/tmp/", line 8, in <module>
    pickle.loads(pickle.dumps(MultipleArgumentsError('a', 'b')))
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 1388, in loads
    return Unpickler(file).load()
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 864, in load
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 1139, in load_reduce
    value = func(*args)
TypeError: __init__() takes exactly 3 arguments (2 given)

The same error occurs when using a built-in module like subprocess:
>>> import subprocess, pickle
>>> try:
...   subprocess.check_call(['python', '-c', 'raise SystemExit(1)'])
... except Exception as e:
...   pickle.loads(pickle.dumps(e))

Related issue:
msg315225 - (view) Author: Kirill Matsaberydze (Kirill Matsaberydze) Date: 2018-04-12 15:07
Hi, I encounter similar behavior in python 3.6.5 with following code:

import pickle
class CustomException(Exception):
    def __init__(self, arg1, arg2):
        msg = "Custom message {} {}".format(arg1, arg2)

obj_dump = pickle.dumps(CustomException("arg1", "arg2"))
obj = pickle.loads(obj_dump)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'arg2'

So it looks like it not only python 2.7 problem
msg315230 - (view) Author: Jason R. Coombs (jason.coombs) * (Python committer) Date: 2018-04-12 16:42
Kirill, see in the related issue for one possible way to work around the issue on Python 3.
Date User Action Args
2018-10-29 19:30:34benoit-pierresetnosy: + benoit-pierre
2018-10-11 14:42:40orivejsetnosy: + orivej
2018-04-12 16:42:31jason.coombssetmessages: + msg315230
2018-04-12 15:07:01Kirill Matsaberydzesetnosy: + Kirill Matsaberydze
messages: + msg315225
2018-01-28 16:15:55slallumcreate