Author jab
Recipients jab
Date 2020-08-01.04:39:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1596256765.81.0.716596997426.issue41451@roundup.psfhosted.org>
In-reply-to
Content
Whittled this down to an even more minimal repro:


"""Repro for Python 3.6 slots + weakref + typing.Generic subclass bug."""

from typing import Generic, TypeVar
from weakref import ref


T = TypeVar("T")

class MyGeneric(Generic[T]):
    """MyGeneric works as expected.

        >>> example = MyGeneric()
        >>> from pickle import dumps, loads
        >>> pickled = dumps(example)
        >>> roundtripped = loads(pickled)
        >>> roundtripped
        <__main__.MyGeneric object at ...>

    """

    __slots__ = ("_other", "__weakref__")

    def __init__(self) -> None:
        self._init_other()

    def _init_other(self) -> None:
        other = self.__class__.__new__(self.__class__)
        other._other = self
        self._other = ref(other)

    def __getstate__(self) -> dict:
        """Needed to enable pickling due to use of __slots__ and weakrefs."""
        return {}

    def __setstate__(self, _) -> None:
        """Needed because use of __slots__ would prevent unpickling otherwise."""
        self._init_other()


# So far so good, but now let's make a subclass.
# The following class definition works on Python > 3.6, but fails on 3.6 with
# TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0
class FailsInPy36(MyGeneric[T]):
    """Minimal repro.

        >>> repro = FailsInPy36()
        >>> repro
        <__main__.FailsInPy36 object at ...>

    """


if __name__ == "__main__":
    import doctest
    doctest.testmod(optionflags=doctest.ELLIPSIS)
History
Date User Action Args
2020-08-01 04:39:25jabsetrecipients: + jab
2020-08-01 04:39:25jabsetmessageid: <1596256765.81.0.716596997426.issue41451@roundup.psfhosted.org>
2020-08-01 04:39:25jablinkissue41451 messages
2020-08-01 04:39:25jabcreate