Message374662
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) |
|
Date |
User |
Action |
Args |
2020-08-01 13:21:34 | jab | set | recipients:
+ jab, Joshua Oreman |
2020-08-01 13:21:34 | jab | set | messageid: <1596288094.67.0.530040881136.issue41451@roundup.psfhosted.org> |
2020-08-01 13:21:34 | jab | link | issue41451 messages |
2020-08-01 13:21:34 | jab | create | |
|