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

return_value and not_a_test_method health checks strict error fix #3581

Merged
merged 25 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4aa13d7
add note_deprecation
reaganjlee Feb 13, 2023
676aa1e
modify all()
reaganjlee Feb 13, 2023
f327a3c
add deprecated label
reaganjlee Feb 13, 2023
b3a171f
add deprecated label
reaganjlee Feb 13, 2023
c04f465
take out previous mentions of attributes
reaganjlee Feb 13, 2023
ec8613a
Merge branch 'master' of https://github.com/reaganjlee/hypothesis
reaganjlee Feb 13, 2023
29c55b4
change __iter__/__getattr__
reaganjlee Feb 15, 2023
53182a9
create release.rst and add name to authors
reaganjlee Feb 15, 2023
16f83c8
undo previous commits
reaganjlee Feb 15, 2023
840ae59
Merge branch 'strict-error-second'
reaganjlee Feb 15, 2023
bbd1ac3
Rephrase messages + add tests
Zac-HD Feb 16, 2023
53196b4
Fix tests
Zac-HD Feb 16, 2023
5dc6d40
add different tests
reaganjlee Mar 6, 2023
9463229
change all() and remove previous
reaganjlee Mar 6, 2023
eaa0695
remove extraneous comments + add __iter__
reaganjlee Mar 6, 2023
335d8c2
add deprecation when validate suppressions
reaganjlee Mar 7, 2023
8a9c35e
remove return_value test
reaganjlee Mar 7, 2023
71a1b77
add enum class for __iter__
reaganjlee Mar 11, 2023
ee09b9e
add enum metaclass for __iter__
reaganjlee Mar 11, 2023
00dd980
Merge branch 'master' of https://github.com/reaganjlee/hypothesis
reaganjlee Mar 11, 2023
431d331
remove cls arg
reaganjlee Mar 11, 2023
af8f317
Avoid HealthCheck.all()
Zac-HD Mar 12, 2023
f515c8f
Tweak formatting etc
Zac-HD Mar 12, 2023
e717840
Apply suggestions from code review
Zac-HD Mar 12, 2023
c29e219
add support for graalpy
timfel Jan 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ their individual contributions.
* `Phillip Schanely <https://github.com/pschanely>`_ (pschanely@gmail.com)
* `Pierre-Jean Campigotto <https://github.com/PJCampi>`_
* `Przemek Konopko <https://github.com/soutys>`_
* `Reagan Lee <https://github.com/reaganjlee>`_
* `Richard Boulton <https://www.github.com/rboulton>`_ (richard@tartarus.org)
* `Richard Scholtens <https://github.com/richardscholtens>`_ (richardscholtens2@gmail.com)
* `Robert Howlett <https://github.com/jebob>`_
Expand Down
7 changes: 7 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
RELEASE_TYPE: minor

This release turns ``HealthCheck.return_value`` and ``HealthCheck.not_a_test_method``
into unconditional errors. Passing them to ``suppress_health_check=`` is therefore a deprecated no-op.
(:issue:`3568`). Thanks to Reagan Lee for the patch!

Separately, GraalPy can now run and pass most of the hypothesis test suite (:issue:`3587`).
2 changes: 1 addition & 1 deletion hypothesis-python/docs/healthchecks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ If this is expected, e.g. when generating large arrays or dataframes, you can se
disable them with the :obj:`~hypothesis.settings.suppress_health_check` setting.
The argument for this parameter is a list with elements drawn from any of
the class-level attributes of the HealthCheck class.
Using a value of ``HealthCheck.all()`` will disable all health checks.
Using a value of ``list(HealthCheck)`` will disable all health checks.

.. autoclass:: hypothesis.HealthCheck
:undoc-members:
Expand Down
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
27 changes: 20 additions & 7 deletions hypothesis-python/src/hypothesis/_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import inspect
import os
import warnings
from enum import Enum, IntEnum, unique
from enum import Enum, EnumMeta, IntEnum, unique
from typing import TYPE_CHECKING, Any, Collection, Dict, List, Optional, TypeVar, Union

import attr
Expand Down Expand Up @@ -445,8 +445,14 @@ def __repr__(self):
return f"Phase.{self.name}"


class HealthCheckMeta(EnumMeta):
def __iter__(self):
deprecated = (HealthCheck.return_value, HealthCheck.not_a_test_method)
return iter(x for x in super().__iter__() if x not in deprecated)


@unique
class HealthCheck(Enum):
class HealthCheck(Enum, metaclass=HealthCheckMeta):
"""Arguments for :attr:`~hypothesis.settings.suppress_health_check`.

Each member of this enum is a type of health check to suppress.
Expand All @@ -457,6 +463,8 @@ def __repr__(self):

@classmethod
def all(cls) -> List["HealthCheck"]:
# Skipping of deprecated attributes is handled in HealthCheckMeta.__iter__
# TODO: note_deprecation() and write a codemod for HC.all() -> list(HC)
return list(HealthCheck)
Comment on lines 464 to 468
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to take this on as a follow-up PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! I can work on this after the cacheing :)


data_too_large = 1
Expand All @@ -479,15 +487,14 @@ def all(cls) -> List["HealthCheck"]:
testing."""

return_value = 5
"""Checks if your tests return a non-None value (which will be ignored and
is unlikely to do what you want)."""
"""Deprecated; we always error if a test returns a non-None value."""

large_base_example = 7
"""Checks if the natural example to shrink towards is very large."""

not_a_test_method = 8
"""Checks if :func:`@given <hypothesis.given>` has been applied to a
method defined by :class:`python:unittest.TestCase` (i.e. not a test)."""
"""Deprecated; we always error if :func:`@given <hypothesis.given>` is applied
to a method defined by :class:`python:unittest.TestCase` (i.e. not a test)."""

function_scoped_fixture = 9
"""Checks if :func:`@given <hypothesis.given>` has been applied to a test
Expand Down Expand Up @@ -585,6 +592,12 @@ def validate_health_check_suppressions(suppressions):
f"Non-HealthCheck value {s!r} of type {type(s).__name__} "
"is invalid in suppress_health_check."
)
if s in (HealthCheck.return_value, HealthCheck.not_a_test_method):
note_deprecation(
f"The {s.name} health check is deprecated, because this is always an error.",
since="RELEASEDAY",
has_codemod=False,
)
return suppressions


Expand Down Expand Up @@ -673,7 +686,7 @@ def is_in_ci() -> bool:
def note_deprecation(message: str, *, since: str, has_codemod: bool) -> None:
if since != "RELEASEDAY":
date = datetime.datetime.strptime(since, "%Y-%m-%d").date()
assert datetime.date(2016, 1, 1) <= date
assert datetime.date(2021, 1, 1) <= date
if has_codemod:
message += (
"\n The `hypothesis codemod` command-line tool can automatically "
Expand Down
2 changes: 1 addition & 1 deletion hypothesis-python/src/hypothesis/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1495,7 +1495,7 @@ def find(
if settings is None:
settings = Settings(max_examples=2000)
settings = Settings(
settings, suppress_health_check=HealthCheck.all(), report_multiple_bugs=False
settings, suppress_health_check=list(HealthCheck), report_multiple_bugs=False
)

if database_key is None and settings.database is not None:
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
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def normalize(

runner = ConjectureRunner(
test_function,
settings=settings(database=None, suppress_health_check=HealthCheck.all()),
settings=settings(database=None, suppress_health_check=list(HealthCheck)),
ignore_limits=True,
random=random,
)
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
4 changes: 2 additions & 2 deletions hypothesis-python/src/hypothesis/stateful.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step
settings = state_machine_factory.TestCase.settings
check_type(Settings, settings, "state_machine_factory.TestCase.settings")
except AttributeError:
settings = Settings(deadline=None, suppress_health_check=HealthCheck.all())
settings = Settings(deadline=None, suppress_health_check=list(HealthCheck))
check_type(Settings, settings, "settings")
check_type(int, _min_steps, "_min_steps")
if _min_steps < 0:
Expand Down Expand Up @@ -390,7 +390,7 @@ def teardown(self):
@lru_cache()
def _to_test_case(cls):
class StateMachineTestCase(TestCase):
settings = Settings(deadline=None, suppress_health_check=HealthCheck.all())
settings = Settings(deadline=None, suppress_health_check=list(HealthCheck))

def runTest(self):
run_state_machine_as_test(cls)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def example(self) -> Ex:
deadline=None,
verbosity=Verbosity.quiet,
phases=(Phase.generate,),
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
)
def example_generating_inner_function(ex):
self.__examples.append(ex)
Expand Down
2 changes: 1 addition & 1 deletion hypothesis-python/tests/common/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def wrapped_condition(x):
@given(definition)
@Settings(
parent=settings,
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
report_multiple_bugs=False,
derandomize=True,
database=None,
Expand Down
4 changes: 2 additions & 2 deletions hypothesis-python/tests/conjecture/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


TEST_SETTINGS = settings(
max_examples=5000, database=None, suppress_health_check=HealthCheck.all()
max_examples=5000, database=None, suppress_health_check=list(HealthCheck)
)


Expand Down Expand Up @@ -56,7 +56,7 @@ def accept(f):
settings=settings(
max_examples=5000,
database=None,
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
),
)
runner.cached_test_function(start)
Expand Down
2 changes: 1 addition & 1 deletion hypothesis-python/tests/conjecture/test_data_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from hypothesis.internal.conjecture.engine import ConjectureRunner

TEST_SETTINGS = settings(
max_examples=5000, database=None, suppress_health_check=HealthCheck.all()
max_examples=5000, database=None, suppress_health_check=list(HealthCheck)
)


Expand Down
18 changes: 9 additions & 9 deletions hypothesis-python/tests/conjecture/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ def f(data):
settings=settings(
max_examples=5000,
database=None,
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
verbosity=Verbosity.debug,
),
)
Expand Down Expand Up @@ -722,7 +722,7 @@ def f(data):
runner = ConjectureRunner(
f,
settings=settings(
max_examples=1, database=database, suppress_health_check=HealthCheck.all()
max_examples=1, database=database, suppress_health_check=list(HealthCheck)
),
database_key=key,
)
Expand Down Expand Up @@ -755,7 +755,7 @@ def f(data):
runner = ConjectureRunner(
f,
settings=settings(
max_examples=1, database=database, suppress_health_check=HealthCheck.all()
max_examples=1, database=database, suppress_health_check=list(HealthCheck)
),
database_key=key,
)
Expand Down Expand Up @@ -789,7 +789,7 @@ def f(data):
runner = ConjectureRunner(
f,
settings=settings(
max_examples=1, database=None, suppress_health_check=HealthCheck.all()
max_examples=1, database=None, suppress_health_check=list(HealthCheck)
),
)

Expand Down Expand Up @@ -1220,7 +1220,7 @@ def test(data):
settings=settings(
max_examples=5000,
database=InMemoryExampleDatabase(),
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
),
database_key=b"stuff",
)
Expand All @@ -1241,7 +1241,7 @@ def test(data):
settings=settings(
max_examples=5000,
database=InMemoryExampleDatabase(),
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
),
database_key=b"stuff",
)
Expand All @@ -1262,7 +1262,7 @@ def test(data):
settings=settings(
max_examples=5000,
database=InMemoryExampleDatabase(),
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
),
database_key=b"stuff",
)
Expand All @@ -1285,7 +1285,7 @@ def test(data):
runner = ConjectureRunner(
test,
settings=settings(
max_examples=500, database=db, suppress_health_check=HealthCheck.all()
max_examples=500, database=db, suppress_health_check=list(HealthCheck)
),
database_key=b"stuff",
)
Expand Down Expand Up @@ -1326,7 +1326,7 @@ def test(data):
settings=settings(
max_examples=10000,
database=db,
suppress_health_check=HealthCheck.all(),
suppress_health_check=list(HealthCheck),
phases=[Phase.reuse],
),
database_key=b"stuff",
Expand Down
Loading