Skip to content

Commit

Permalink
Manual GC in tests on PyPy
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Nov 4, 2021
1 parent 735b4af commit 3802a00
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions hypothesis-python/tests/cover/test_random_module.py
Expand Up @@ -13,18 +13,29 @@
#
# END HEADER

import gc
import random

import pytest

from hypothesis import find, given, register_random, reporting, strategies as st
from hypothesis.errors import InvalidArgument
from hypothesis.internal import entropy
from hypothesis.internal.compat import PYPY
from hypothesis.internal.entropy import deterministic_PRNG

from tests.common.utils import capture_out


def gc_on_pypy():
# CPython uses reference counting, so objects (without circular refs)
# are collected immediately on `del`, breaking weak references.
# PyPy doesn't, so we use this function in tests before counting the
# surviving references to ensure that they're deterministic.
if PYPY:
gc.collect()


def test_can_seed_random():
with capture_out() as out:
with reporting.with_reporter(reporting.default):
Expand Down Expand Up @@ -54,12 +65,14 @@ def test_cannot_register_non_Random():


def test_registering_a_Random_is_idempotent():
gc_on_pypy()
n_registered = len(entropy.RANDOMS_TO_MANAGE)
r = random.Random()
register_random(r)
register_random(r)
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered + 1
del r
gc_on_pypy()
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered


Expand Down Expand Up @@ -136,6 +149,7 @@ def test_find_does_not_pollute_state():


def test_evil_prng_registration_nonsense():
gc_on_pypy()
n_registered = len(entropy.RANDOMS_TO_MANAGE)
r1, r2, r3 = random.Random(1), random.Random(2), random.Random(3)
s2 = r2.getstate()
Expand All @@ -146,16 +160,19 @@ def test_evil_prng_registration_nonsense():
register_random(r1)
k = max(entropy.RANDOMS_TO_MANAGE) # get a handle to check if r1 still exists
register_random(r2)
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered + 2

with deterministic_PRNG(0):
del r1
r2.seed(4)
gc_on_pypy()
assert k not in entropy.RANDOMS_TO_MANAGE, "r1 has been garbage-collected"
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered + 1

r2.seed(4)
register_random(r3)
r3.seed(4)
s4 = r3.getstate()

# Implicit check, no exception was raised in __exit__
assert k not in entropy.RANDOMS_TO_MANAGE, "r1 has been garbage-collected"
assert r2.getstate() == s2, "reset previously registered random state"
assert r3.getstate() == s4, "retained state when registered within the context"

0 comments on commit 3802a00

Please sign in to comment.