Joshua Bronson <jabron...@gmail.com> added the comment:

Thanks so much, @oremanj! Indeed, merely subscripting the class triggers the 
bug, and your 'del slots' workaround does the trick!

For completeness, there is an updated (yet more minimal) repro below/attached.


"""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()
        >>> example
        <__main__.MyGeneric object at ...>
        >>> example._other
        <__main__.MyGeneric object at ...>
        >>> example._other._other
        <weakref at ...; to 'MyGeneric' at ...>
        >>> 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 = ref(self)
        self._other = 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()


# Merely the following is enough to trigger the bug on Python 3.6:
MyGeneric[T]

# This works around the issue if run first (thanks @oremanj):
del MyGeneric.__slots__  # does not actually 'unslot' the class


if __name__ == "__main__":
    import doctest
    doctest.testmod(optionflags=doctest.ELLIPSIS)

----------
Added file: https://bugs.python.org/file49357/bpo41451-repro-min+workaround.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41451>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to