Skip to content

Commit

Permalink
Best-effort avoiding RecursionError in gc callback
Browse files Browse the repository at this point in the history
  • Loading branch information
jobh committed May 14, 2024
1 parent eb49b7d commit 8d23490
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions hypothesis-python/src/hypothesis/internal/conjecture/junkdrawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,20 @@ def _gc_callback(phase, _info): # pragma: no cover # called outside coverage b
def gc_cumulative_time() -> float:
global _gc_initialized
if not _gc_initialized:
# Indirection via lambda to simplify monkeypatching of the callback fn
# - gc.callbacks can't be reassigned and hence is not suitable for
# monkeypatching directly. Don't remove this lambda without considering
# implications in tests/conftest.py.
gc.callbacks.insert(0, lambda *args: _gc_callback(*args))

def gc_callback(phase, info):
# There's not much that can fail here, but to avoid flakiness
# if collection is triggered near the recursion limit we temporarily
# bump to ensure there's headroom. Assuming the limit wasn't already
# exceeded by calling *this* method of course, but there's nothing we
# can do about that.
orig_recursionlimit = sys.getrecursionlimit()
sys.setrecursionlimit(orig_recursionlimit + 5)
try:
_gc_callback(phase, info)
finally:
sys.setrecursionlimit(orig_recursionlimit)

gc.callbacks.insert(0, gc_callback)
_gc_initialized = True
return _gc_cumulative_time

0 comments on commit 8d23490

Please sign in to comment.