class KwargsNewMetaclass(type):
"""
This metaclass reimplements __reduce__ so that it tries to call
__getnewargs_ex__. If that doesn't work, it falls back to __getnewargs__.
In the first case, it will pass the keyword arguments to object.__new__.
It also exposes a kwargs_new static method that can be overridden for
use by __reduce__.
"""
@staticmethod
def kwargs_new(cls, new_kwargs, *new_args):
retval = cls.__new__(cls, *new_args, **new_kwargs)
retval.__init__(*new_args, **new_kwargs)
return retval
def __new__(cls, name, bases, classdict):
result = super().__new__(cls, name, bases, classdict)
def __reduce__(self):
try:
getnewargs_ex = self.__getnewargs_ex__
except AttributeError:
new_args, new_kwargs = (self.__getnewargs__(), {})
else:
new_args, new_kwargs = getnewargs_ex()
return (self.kwargs_new(cls),
(type(self), new_kwargs,) + tuple(new_args),
self.__getstate__())
result.__reduce__ = __reduce__
return result
On Sunday, March 23, 2014 6:20:41 PM UTC-4, Neil Girdhar wrote:
Currently
__reduce__ returns up to five things:
(1) self.__new__ (or a substitute)
(4) an iterator of values for appending to a sequence
(5) an iterator of key-value pairs for setting on a string.
(1) a tuple of positional arguments for
__new__(2) a dict of keyword arguments for
__new__
Therefore, I am proposing that __reduce__ return somehow these keyword arguments for __new__.
Best,
Neil