diff options
| author | Jan-Jaap Driessen <jdriessen@minddistrict.com> | 2020-10-01 13:05:12 +0200 |
|---|---|---|
| committer | Jan-Jaap Driessen <jdriessen@minddistrict.com> | 2020-10-01 13:05:12 +0200 |
| commit | ca5b7e0c8dceb13d4d2a7d86e49558e2c75fa2dc (patch) | |
| tree | 72c455bcc46e24dbe42f67edb84d9805e025f579 /src | |
| parent | 3fc878eb00deb9e2988ef651c74e09e39dd9d49a (diff) | |
| parent | 93efea7577701231f7d196755436872b649fe1de (diff) | |
| download | zope-interface-ca5b7e0c8dceb13d4d2a7d86e49558e2c75fa2dc.tar.gz | |
Merge branch 'master' of github.com:zopefoundation/zope.interface into master
Diffstat (limited to 'src')
| -rw-r--r-- | src/zope/interface/_zope_interface_coptimizations.c | 2 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_declarations.py | 29 |
2 files changed, 31 insertions, 0 deletions
diff --git a/src/zope/interface/_zope_interface_coptimizations.c b/src/zope/interface/_zope_interface_coptimizations.c index 346e7f2..374311e 100644 --- a/src/zope/interface/_zope_interface_coptimizations.c +++ b/src/zope/interface/_zope_interface_coptimizations.c @@ -350,6 +350,7 @@ Spec_traverse(Spec* self, visitproc visit, void* arg) { Py_VISIT(self->_implied); Py_VISIT(self->_dependents); + Py_VISIT(self->_bases); Py_VISIT(self->_v_attrs); Py_VISIT(self->__iro__); Py_VISIT(self->__sro__); @@ -361,6 +362,7 @@ Spec_clear(Spec* self) { Py_CLEAR(self->_implied); Py_CLEAR(self->_dependents); + Py_CLEAR(self->_bases); Py_CLEAR(self->_v_attrs); Py_CLEAR(self->__iro__); Py_CLEAR(self->__sro__); diff --git a/src/zope/interface/tests/test_declarations.py b/src/zope/interface/tests/test_declarations.py index c8678b5..9ef192a 100644 --- a/src/zope/interface/tests/test_declarations.py +++ b/src/zope/interface/tests/test_declarations.py @@ -1078,6 +1078,35 @@ class Test_implementer(Test_classImplements): self.assertIsNone(spec.inherit,) self.assertIs(foo.__implemented__, spec) # pylint:disable=no-member + def test_does_not_leak_on_unique_classes(self): + # Make sure nothing is hanging on to the class or Implements + # object after they go out of scope. There was briefly a bug + # in 5.x that caused SpecificationBase._bases (in C) to not be + # traversed or cleared. + # https://github.com/zopefoundation/zope.interface/issues/216 + import gc + from zope.interface.interface import InterfaceClass + IFoo = InterfaceClass('IFoo') + + begin_count = len(gc.get_objects()) + + for _ in range(1900): + class TestClass(object): + pass + + self._callFUT(TestClass, IFoo) + + gc.collect() + + end_count = len(gc.get_objects()) + + # How many new objects might still be around? In all currently + # tested interpreters, there aren't any, so our counts should + # match exactly. When the bug existed, in a steady state, the loop + # would grow by two objects each iteration + fudge_factor = 0 + self.assertLessEqual(end_count, begin_count + fudge_factor) + class Test_implementer_only(Test_classImplementsOnly): |
