"""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 >>> 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)