0

The following code fails

from collections import namedtuple
import pickle

class Foo(namedtuple("_Foo", ["a", "b"])):
    def __new__(cls, **kwargs):
        self = super().__new__(cls, **kwargs)
        # some custom code
        return self

foo = Foo(a=1, b=2)
pickle.loads(pickle.dumps(foo))

with

Traceback (most recent call last):
  File "bar.py", line 10, in <module>
    pickle.loads(pickle.dumps(foo))
TypeError: __new__() takes 1 positional argument but 3 were given

It works if I remove the new __new__ implementation, but I want to have some custom code there. How do I need to change the implementation of __new__ to not have the error?

I'm running Python 3.5.

Rubick
  • 296
  • 3
  • 22
knub
  • 3,892
  • 8
  • 38
  • 63

1 Answers1

2

The reason is quite simple; in general, the C API passes stuff around as positional parameters, instead of named parameters. Therefore, you just need to provide for this with *args:

from collections import namedtuple
import pickle

class Foo(namedtuple("_Foo", ["a", "b"])):
    def __new__(cls, *args, **kwargs):
        self = super().__new__(cls, *args, **kwargs)
        # some custom code
        return self

foo = Foo(a=1, b=2)
pickle.loads(pickle.dumps(foo))
gmds
  • 19,325
  • 4
  • 32
  • 58