Do not copy __weakref__ from original _cls_dict (#410)
self._cls_dict["__weakref__"] holds a reference to self._cls, preventing self._cls from being released after the new, slots-enabled class is returned. Fixes #407
This commit is contained in:
parent
6f3f4904be
commit
4c41099fb8
|
@ -0,0 +1 @@
|
|||
Fixed a reference leak where the original class would remain live after being replaced when ``slots=True`` is set.
|
|
@ -493,7 +493,7 @@ class _ClassBuilder(object):
|
|||
cd = {
|
||||
k: v
|
||||
for k, v in iteritems(self._cls_dict)
|
||||
if k not in tuple(self._attr_names) + ("__dict__",)
|
||||
if k not in tuple(self._attr_names) + ("__dict__", "__weakref__")
|
||||
}
|
||||
|
||||
# We only add the names of attributes that aren't inherited.
|
||||
|
|
|
@ -5,6 +5,7 @@ Tests for `attr._make`.
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import copy
|
||||
import gc
|
||||
import inspect
|
||||
import itertools
|
||||
import sys
|
||||
|
@ -1250,6 +1251,25 @@ class TestClassBuilder(object):
|
|||
|
||||
assert C() == copy.deepcopy(C())
|
||||
|
||||
def test_no_references_to_original(self):
|
||||
"""
|
||||
When subclassing a slots class, there are no stray references to the
|
||||
original class.
|
||||
"""
|
||||
|
||||
@attr.s(slots=True)
|
||||
class C(object):
|
||||
pass
|
||||
|
||||
@attr.s(slots=True)
|
||||
class C2(C):
|
||||
pass
|
||||
|
||||
# The original C2 is in a reference cycle, so force a collect:
|
||||
gc.collect()
|
||||
|
||||
assert [C2] == C.__subclasses__()
|
||||
|
||||
|
||||
class TestMakeCmp:
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue