[Python-ideas] Make __reduce__ to correspond to __getnewargs_ex__

Neil Girdhar mistersheik at gmail.com
Sat Jun 7 21:39:31 CEST 2014


Any comments on this?  I ended up making reduce work using a metaclass:

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__ 
> <http://docs.python.org/3.4/library/pickle.html#object.__reduce__> 
> returns up to five things:
>
> (1) self.__new__ (or a substitute)
> (2) the result of __getnewargs__ 
> <http://docs.python.org/3.4/library/pickle.html#object.__getnewargs__>, 
> which returns a tuple of positional arguments for __new__ 
> <http://docs.python.org/3.4/reference/datamodel.html#object.__new__>,
> (3) the result of __getstate__ 
> <http://docs.python.org/3.4/library/pickle.html#object.__getstate__>, 
> which returns an object to be passed to __setstate__ 
> <http://docs.python.org/3.4/library/pickle.html#object.__setstate__>
> (4) an iterator of values for appending to a sequence
> (5) an iterator of key-value pairs for setting on a string.
>
> Python 3.4 added the very useful (for me) __getnewargs_ex__ 
> <http://docs.python.org/3.4/library/pickle.html#object.__getnewargs_ex__>, 
> which returns a pair:
> (1) a tuple of positional arguments for __new__ 
> <http://docs.python.org/3.4/reference/datamodel.html#object.__new__>
> (2) a dict of keyword arguments for __new__ 
> <http://docs.python.org/3.4/reference/datamodel.html#object.__new__>
>
> Therefore, I am proposing that __reduce__ return somehow these keyword 
> arguments for __new__.
>
> Best,
> Neil
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140607/50686f85/attachment.html>


More information about the Python-ideas mailing list