Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GraalPy #3587

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RELEASE_TYPE: patch

This patch allows GraalPy to run and pass most of the hypothesis test suite
(:issue:`3587`).
27 changes: 15 additions & 12 deletions hypothesis-python/scripts/basic-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pip install "$(grep 'lark==' ../requirements/coverage.txt)"
$PYTEST tests/lark/
pip uninstall -y lark

if [ "$(python -c $'import platform, sys; print(sys.version_info.releaselevel == \'final\' and platform.python_implementation() != "PyPy")')" = "True" ] ; then
if [ "$(python -c $'import platform, sys; print(sys.version_info.releaselevel == \'final\' and platform.python_implementation() not in ("PyPy", "GraalVM"))')" = "True" ] ; then
pip install ".[codemods,cli]"
$PYTEST tests/codemods/
pip uninstall -y libcst click
Expand Down Expand Up @@ -75,16 +75,19 @@ PYTHONOPTIMIZE=2 $PYTEST \
-W'ignore:Module already imported so cannot be rewritten:pytest.PytestAssertRewriteWarning' \
tests/cover/test_testdecorators.py

if [ "$(python -c 'import platform; print(platform.python_implementation())')" != "PyPy" ]; then
pip install .[django]
HYPOTHESIS_DJANGO_USETZ=TRUE python -m tests.django.manage test tests.django
HYPOTHESIS_DJANGO_USETZ=FALSE python -m tests.django.manage test tests.django
pip uninstall -y django pytz
case "$(python -c 'import platform; print(platform.python_implementation())')" in
PyPy|GraalVM)
;;
*)
pip install .[django]
HYPOTHESIS_DJANGO_USETZ=TRUE python -m tests.django.manage test tests.django
HYPOTHESIS_DJANGO_USETZ=FALSE python -m tests.django.manage test tests.django
pip uninstall -y django pytz

pip install "$(grep 'numpy==' ../requirements/coverage.txt)"
$PYTEST tests/array_api
$PYTEST tests/numpy
pip install "$(grep 'numpy==' ../requirements/coverage.txt)"
$PYTEST tests/array_api
$PYTEST tests/numpy

pip install "$(grep 'pandas==' ../requirements/coverage.txt)"
$PYTEST tests/pandas
fi
pip install "$(grep 'pandas==' ../requirements/coverage.txt)"
$PYTEST tests/pandas
esac
13 changes: 8 additions & 5 deletions hypothesis-python/scripts/other-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pip install "$(grep 'lark==' ../requirements/coverage.txt)"
$PYTEST tests/lark/
pip uninstall -y lark

if [ "$(python -c $'import platform, sys; print(sys.version_info.releaselevel == \'final\' and platform.python_implementation() != "PyPy")')" = "True" ] ; then
if [ "$(python -c $'import platform, sys; print(sys.version_info.releaselevel == \'final\' and platform.python_implementation() not in ("PyPy", "GraalVM"))')" = "True" ] ; then
pip install ".[codemods,cli]"
$PYTEST tests/codemods/
pip uninstall -y libcst click
Expand All @@ -55,10 +55,13 @@ if [ "$(python -c $'import platform, sys; print(sys.version_info.releaselevel ==
pip install "$(grep 'numpy==' ../requirements/coverage.txt)"
fi

if [ "$(python -c 'import platform; print(platform.python_implementation())')" != "PyPy" ]; then\
$PYTEST tests/array_api
$PYTEST tests/numpy
fi
case "$(python -c 'import platform; print(platform.python_implementation())')" in
PyPy|GraalVM)
;;
*)
$PYTEST tests/array_api
$PYTEST tests/numpy
esac

pip install "$(grep 'black==' ../requirements/coverage.txt)"
$PYTEST tests/ghostwriter/
Expand Down
1 change: 1 addition & 0 deletions hypothesis-python/src/hypothesis/internal/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def get_origin(tp: Any) -> typing.Optional[Any]: # pragma: no cover
Concatenate, ParamSpec = None, None

PYPY = platform.python_implementation() == "PyPy"
GRAALPY = platform.python_implementation() == "GraalVM"
WINDOWS = platform.system() == "Windows"


Expand Down
10 changes: 5 additions & 5 deletions hypothesis-python/src/hypothesis/internal/entropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import hypothesis.core
from hypothesis.errors import HypothesisWarning, InvalidArgument
from hypothesis.internal.compat import PYPY
from hypothesis.internal.compat import GRAALPY, PYPY

if TYPE_CHECKING:
if sys.version_info >= (3, 8):
Expand Down Expand Up @@ -59,7 +59,7 @@ def __init__(self):
NP_RANDOM = None


if not PYPY:
if not (PYPY or GRAALPY):

def _get_platform_base_refcount(r: Any) -> int:
return sys.getrefcount(r)
Expand All @@ -68,7 +68,7 @@ def _get_platform_base_refcount(r: Any) -> int:
# the given platform / version of Python.
_PLATFORM_REF_COUNT = _get_platform_base_refcount(object())
else: # pragma: no cover
# PYPY doesn't have `sys.getrefcount`
# PYPY and GRAALPY don't have `sys.getrefcount`
_PLATFORM_REF_COUNT = -1


Expand Down Expand Up @@ -118,8 +118,8 @@ def my_WORKING_hook():
if r in RANDOMS_TO_MANAGE.values():
return

if not PYPY: # pragma: no branch
# PYPY does not have `sys.getrefcount`
if not (PYPY or GRAALPY): # pragma: no branch
# PYPY and GRAALPY do not have `sys.getrefcount`
gc.collect()
if not gc.get_referrers(r):
if sys.getrefcount(r) <= _PLATFORM_REF_COUNT:
Expand Down
19 changes: 10 additions & 9 deletions hypothesis-python/tests/cover/test_random_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@
from hypothesis import core, find, given, register_random, strategies as st
from hypothesis.errors import HypothesisWarning, InvalidArgument
from hypothesis.internal import entropy
from hypothesis.internal.compat import PYPY
from hypothesis.internal.compat import GRAALPY, PYPY
from hypothesis.internal.entropy import deterministic_PRNG


def gc_on_pypy():
def gc_collect():
# 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
# Python implementations with other garbage collection strategies may
# or may not, so we use this function in tests before counting the
# surviving references to ensure that they're deterministic.
if PYPY:
if PYPY or GRAALPY:
gc.collect()


Expand Down Expand Up @@ -58,14 +59,14 @@ def test_cannot_register_non_Random():
"ignore:It looks like `register_random` was passed an object that could be garbage collected"
)
def test_registering_a_Random_is_idempotent():
gc_on_pypy()
gc_collect()
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()
gc_collect()
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered


Expand Down Expand Up @@ -151,7 +152,7 @@ def test_find_does_not_pollute_state():
"ignore:It looks like `register_random` was passed an object that could be garbage collected"
)
def test_evil_prng_registration_nonsense():
gc_on_pypy()
gc_collect()
n_registered = len(entropy.RANDOMS_TO_MANAGE)
r1, r2, r3 = random.Random(1), random.Random(2), random.Random(3)
s2 = r2.getstate()
Expand All @@ -166,7 +167,7 @@ def test_evil_prng_registration_nonsense():

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

Expand Down Expand Up @@ -230,5 +231,5 @@ def f():
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered + 1

f()
gc_on_pypy()
gc_collect()
assert len(entropy.RANDOMS_TO_MANAGE) == n_registered
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from hypothesis import HealthCheck, Verbosity, given, settings
from hypothesis.errors import InvalidArgument
from hypothesis.extra.django import TestCase, TransactionTestCase
from hypothesis.internal.compat import PYPY
from hypothesis.internal.compat import GRAALPY, PYPY
from hypothesis.strategies import integers

from tests.django.toystore.models import Company
Expand All @@ -40,7 +40,7 @@ class TestConstraintsWithTransactions(SomeStuff, TestCase):
pass


if not PYPY:
if not (PYPY or GRAALPY):
# xfail
# This is excessively slow in general, but particularly on pypy. We just
# disable it altogether there as it's a niche case.
Expand Down