Some way to run "enough" gc for test suites that need to make sure destructors have run
Created originally on Bitbucket by njs (Nathaniel Smith)
It turns out that sometimes in test suites you need to pump the garbage collector manually. For example, to test a __del__
method, you might create an object, drop the reference to it, and then do some kind of check that whatever the __del__
method was supposed to do has actually happened.
In CPython, you can usually just call gc.collect
once and you're good. But in pypy this requires calling gc.collect
multiple times. (No-one's sure exactly how many. I guess in principle pypy might require arbitrarily many calls to match CPython's behavior, if there's a long chain of non-cyclic garbage with destructors?)
A number of projects have hit this and had to implement workarounds. For example:
- https://github.com/numpy/numpy/pull/12594#discussion_r276077803
- https://github.com/python-trio/trio/blob/5aab6b56eb53bb0ce3b3002a239f8c6db36c4ff7/trio/_core/tests/tutil.py#L40-L51
It would be nice if there were a better solution than calling gc.collect()
repeatedly until you stop getting test failures, and if each project didn't have to figure this out from scratch.
It would be even nicer if gc.collect()
just did this, so that people wouldn't have to implement workarounds when porting to pypy :-). But if you need to make it something slightly different, that's OK too. Extra points for making it compatible with CPython, like using the gc.collect(generation=...)
argument or something.