[Python-3000] Pickle 3 and keyword arguments in __new__ after *

3 views
Skip to first unread message

Zaur Shibzoukhov

unread,
Dec 2, 2008, 5:41:46 AM12/2/08
to pytho...@python.org
This is a case:

class C(object):
def __new__(cls, *, b):
inst = super().__new__(cls)
inst.b = b
return inst

>>> c = C(b=17)
>>> image = pickle.dumps(c, protocol=3)
>>> c = pickle.loads(image)
Traceback (most recent call last):
File "test_new.py", line 17, in <module>
c = pickle.loads(image)
File "D:\Python30\lib\pickle.py", line 1329, in loads
return Unpickler(file, encoding=encoding, errors=errors).load()
TypeError: __new__() needs keyword-only argument b

Do we need to improve pickle protocol in order to allow instance
creation functions get keyword arguments too?

Best regards,
Zaur
_______________________________________________
Python-3000 mailing list
Pytho...@python.org
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: http://mail.python.org/mailman/options/python-3000/python-3000-garchive-63646%40googlegroups.com

Amaury Forgeot d'Arc

unread,
Dec 2, 2008, 8:10:28 AM12/2/08
to Zaur Shibzoukhov, pytho...@python.org
Hello,

Zaur Shibzoukhov wrote:
> This is a case:
>
> class C(object):
> def __new__(cls, *, b):
> inst = super().__new__(cls)
> inst.b = b
> return inst
>
>>>> c = C(b=17)
>>>> image = pickle.dumps(c, protocol=3)
>>>> c = pickle.loads(image)
> Traceback (most recent call last):
> File "test_new.py", line 17, in <module>
> c = pickle.loads(image)
> File "D:\Python30\lib\pickle.py", line 1329, in loads
> return Unpickler(file, encoding=encoding, errors=errors).load()
> TypeError: __new__() needs keyword-only argument b
>
> Do we need to improve pickle protocol in order to allow instance
> creation functions get keyword arguments too?

Note that you have a similar error even when the argument is a regular one:

class C(object):
def __new__(cls, b):


inst = super().__new__(cls)
inst.b = b
return inst

>>> c = C(b=17)
>>> image = pickle.dumps(c, protocol=3)
>>> c = pickle.loads(image)
Traceback (most recent call last):

File "c:\temp\t.py", line 11, in <module>
c = pickle.loads(image)
File "c:\Python30\lib\pickle.py", line 1329, in loads
return Unpickler(file, encoding=encoding, errors=errors).load()
TypeError: __new__() takes exactly 2 positional arguments (1 given)

A __getnewargs__ method is needed. In this case, it should return (self.b,).

Now, I would like to translate your question to "Is there an
equivalent of __getnewargs__ that can pass keyword arguments to
__new__?". The only solution I could find involves a global factory
function that calls the constructor, but does not use keyword
arguments:

class C(object):
def __new__(cls, *, b):

inst = super(C, cls).__new__(cls)


inst.b = b
return inst

def __reduce__(self):
return build_C, (self.b,)
def build_C(b):
return C(b=b)

Is there a more object-oriented way?

--
Amaury Forgeot d'Arc

Reply all
Reply to author
Forward
0 new messages