Skip to content

Commit 4de09ed

Browse files
authored
Merge pull request #240 from Zac-HD/next
Fix stateful test fuzzing
2 parents 822340d + 467a551 commit 4de09ed

File tree

13 files changed

+87
-45
lines changed

13 files changed

+87
-45
lines changed

deps/check.txt

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
#
55
# pip-compile --annotation-style=line --output-file=deps/check.txt deps/check.in
66
#
7-
anyio==4.10.0 # via starlette
7+
anyio==4.11.0 # via starlette
88
attrs==25.3.0 # via hypothesis, outcome, trio
9-
black==25.1.0 # via shed
9+
black==25.9.0 # via shed
1010
click==8.1.8 # via black
1111
com2ann==0.3.0 # via shed
1212
exceptiongroup==1.3.0 # via anyio, hypercorn, hypothesis, pytest, taskgroup, trio
@@ -16,12 +16,12 @@ h2==4.3.0 # via hypercorn
1616
hpack==4.1.0 # via h2
1717
hypercorn==0.17.3 # via -r deps/check.in
1818
hyperframe==6.1.0 # via h2
19-
hypothesis==6.138.14 # via -r deps/check.in
19+
hypothesis==6.140.2 # via -r deps/check.in
2020
idna==3.10 # via anyio, trio
2121
iniconfig==2.1.0 # via pytest
22-
libcst==1.8.2 # via shed
22+
libcst==1.8.5 # via shed
2323
mccabe==0.7.0 # via flake8
24-
mypy==1.17.1 # via -r deps/check.in
24+
mypy==1.18.2 # via -r deps/check.in
2525
mypy-extensions==1.1.0 # via black, mypy
2626
outcome==1.3.0.post0 # via trio
2727
packaging==25.0 # via black, pytest
@@ -30,24 +30,25 @@ pep8-naming==0.15.1 # via -r deps/check.in
3030
platformdirs==4.4.0 # via black
3131
pluggy==1.6.0 # via pytest
3232
priority==2.0.0 # via hypercorn
33-
psutil==7.0.0 # via -r deps/check.in
33+
psutil==7.1.0 # via -r deps/check.in
3434
pycodestyle==2.14.0 # via flake8
3535
pyflakes==3.4.0 # via flake8
3636
pygments==2.19.2 # via pytest
37-
pytest==8.4.1 # via -r deps/check.in
37+
pytest==8.4.2 # via -r deps/check.in
38+
pytokens==0.1.10 # via black
3839
pyupgrade==3.20.0 # via shed
39-
pyyaml==6.0.2 # via libcst
40-
ruff==0.12.11 # via -r deps/check.in, shed
40+
pyyaml==6.0.3 # via libcst
41+
ruff==0.13.2 # via -r deps/check.in, shed
4142
shed==2025.6.1 # via -r deps/check.in
4243
sniffio==1.3.1 # via anyio, trio
4344
sortedcontainers==2.4.0 # via hypothesis, sortedcontainers-stubs, trio
4445
sortedcontainers-stubs==2.4.3 # via -r deps/check.in
45-
starlette==0.47.3 # via -r deps/check.in
46+
starlette==0.48.0 # via -r deps/check.in
4647
taskgroup==0.2.2 # via hypercorn
4748
tokenize-rt==6.2.0 # via pyupgrade
4849
tomli==2.2.1 # via black, hypercorn, mypy, pytest
49-
trio==0.30.0 # via -r deps/check.in
50-
types-requests==2.32.4.20250809 # via -r deps/check.in
50+
trio==0.31.0 # via -r deps/check.in
51+
types-requests==2.32.4.20250913 # via -r deps/check.in
5152
typing-extensions==4.15.0 # via anyio, black, exceptiongroup, hypercorn, libcst, mypy, sortedcontainers-stubs, starlette, taskgroup
5253
urllib3==2.5.0 # via types-requests
5354
wsproto==1.2.0 # via hypercorn

deps/docs.txt

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,33 @@
66
#
77
accessible-pygments==0.0.5 # via furo
88
alabaster==0.7.16 # via sphinx
9-
anyio==4.10.0 # via starlette
9+
anyio==4.11.0 # via starlette
1010
attrs==25.3.0 # via hypothesis, outcome, trio
1111
babel==2.17.0 # via sphinx
12-
beautifulsoup4==4.13.5 # via furo
13-
black==25.1.0 # via hypofuzz (pyproject.toml), hypothesis
12+
beautifulsoup4==4.14.0 # via furo
13+
black==25.9.0 # via hypofuzz (pyproject.toml), hypothesis
1414
certifi==2025.8.3 # via requests
1515
charset-normalizer==3.4.3 # via requests
1616
click==8.1.8 # via black, hypothesis
17-
coverage==7.10.6 # via hypofuzz (pyproject.toml)
17+
coverage==7.10.7 # via hypofuzz (pyproject.toml)
1818
docutils==0.21.2 # via myst-parser, pybtex-docutils, sphinx, sphinxcontrib-bibtex
1919
exceptiongroup==1.3.0 # via anyio, hypercorn, hypothesis, pytest, taskgroup, trio
20-
furo==2025.7.19 # via -r deps/docs.in
20+
furo==2025.9.25 # via -r deps/docs.in
2121
h11==0.16.0 # via hypercorn, wsproto
2222
h2==4.3.0 # via hypercorn
2323
hpack==4.1.0 # via h2
2424
hypercorn==0.17.3 # via hypofuzz (pyproject.toml)
2525
hyperframe==6.1.0 # via h2
26-
hypothesis[cli,watchdog]==6.138.14 # via hypofuzz (pyproject.toml)
26+
hypothesis[cli,watchdog]==6.140.2 # via hypofuzz (pyproject.toml)
2727
idna==3.10 # via anyio, requests, trio
2828
imagesize==1.4.1 # via sphinx
2929
importlib-metadata==8.7.0 # via pybtex, sphinx, sphinxcontrib-bibtex
3030
iniconfig==2.1.0 # via pytest
3131
jinja2==3.1.6 # via myst-parser, sphinx
3232
latexcodec==3.0.1 # via pybtex
33-
libcst==1.8.2 # via hypofuzz (pyproject.toml)
33+
libcst==1.8.5 # via hypofuzz (pyproject.toml)
3434
markdown-it-py==3.0.0 # via mdit-py-plugins, myst-parser, rich
35-
markupsafe==3.0.2 # via jinja2
35+
markupsafe==3.0.3 # via jinja2
3636
mdit-py-plugins==0.4.2 # via myst-parser
3737
mdurl==0.1.2 # via markdown-it-py
3838
mypy-extensions==1.1.0 # via black
@@ -43,12 +43,13 @@ pathspec==0.12.1 # via black
4343
platformdirs==4.4.0 # via black
4444
pluggy==1.6.0 # via pytest
4545
priority==2.0.0 # via hypercorn
46-
psutil==7.0.0 # via hypofuzz (pyproject.toml)
46+
psutil==7.1.0 # via hypofuzz (pyproject.toml)
4747
pybtex==0.25.1 # via pybtex-docutils, sphinxcontrib-bibtex
4848
pybtex-docutils==1.0.3 # via sphinxcontrib-bibtex
4949
pygments==2.19.2 # via accessible-pygments, furo, pytest, rich, sphinx
50-
pytest==8.4.1 # via hypofuzz (pyproject.toml)
51-
pyyaml==6.0.2 # via libcst, myst-parser, pybtex
50+
pytest==8.4.2 # via hypofuzz (pyproject.toml)
51+
pytokens==0.1.10 # via black
52+
pyyaml==6.0.3 # via libcst, myst-parser, pybtex
5253
requests==2.32.5 # via sphinx
5354
rich==14.1.0 # via hypothesis
5455
sniffio==1.3.1 # via anyio, trio
@@ -64,10 +65,10 @@ sphinxcontrib-htmlhelp==2.1.0 # via sphinx
6465
sphinxcontrib-jsmath==1.0.1 # via sphinx
6566
sphinxcontrib-qthelp==2.0.0 # via sphinx
6667
sphinxcontrib-serializinghtml==2.0.0 # via sphinx
67-
starlette==0.47.3 # via hypofuzz (pyproject.toml)
68+
starlette==0.48.0 # via hypofuzz (pyproject.toml)
6869
taskgroup==0.2.2 # via hypercorn
6970
tomli==2.2.1 # via black, hypercorn, pytest, sphinx
70-
trio==0.30.0 # via hypofuzz (pyproject.toml)
71+
trio==0.31.0 # via hypofuzz (pyproject.toml)
7172
typing-extensions==4.15.0 # via anyio, beautifulsoup4, black, exceptiongroup, hypercorn, libcst, starlette, taskgroup
7273
urllib3==2.5.0 # via requests
7374
watchdog==6.0.0 # via hypothesis

deps/test.txt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@
44
#
55
# pip-compile --annotation-style=line --output-file=deps/test.txt deps/test.in pyproject.toml
66
#
7-
anyio==4.10.0 # via starlette
7+
anyio==4.11.0 # via starlette
88
attrs==25.3.0 # via hypothesis, outcome, trio
9-
black==25.1.0 # via hypofuzz (pyproject.toml), hypothesis
9+
black==25.9.0 # via hypofuzz (pyproject.toml), hypothesis
1010
certifi==2025.8.3 # via requests
1111
charset-normalizer==3.4.3 # via requests
1212
click==8.1.8 # via black, hypothesis
13-
coverage[toml]==7.10.6 # via hypofuzz (pyproject.toml), pytest-cov
13+
coverage[toml]==7.10.7 # via hypofuzz (pyproject.toml), pytest-cov
1414
exceptiongroup==1.3.0 # via anyio, hypercorn, hypothesis, pytest, taskgroup, trio
1515
execnet==2.1.1 # via pytest-xdist
1616
h11==0.16.0 # via hypercorn, wsproto
1717
h2==4.3.0 # via hypercorn
1818
hpack==4.1.0 # via h2
1919
hypercorn==0.17.3 # via hypofuzz (pyproject.toml)
2020
hyperframe==6.1.0 # via h2
21-
hypothesis[cli,watchdog]==6.138.14 # via hypofuzz (pyproject.toml)
21+
hypothesis[cli,watchdog]==6.140.2 # via hypofuzz (pyproject.toml)
2222
idna==3.10 # via anyio, requests, trio
2323
iniconfig==2.1.0 # via pytest
24-
libcst==1.8.2 # via hypofuzz (pyproject.toml)
24+
libcst==1.8.5 # via hypofuzz (pyproject.toml)
2525
markdown-it-py==3.0.0 # via rich
2626
mdurl==0.1.2 # via markdown-it-py
2727
mypy-extensions==1.1.0 # via black
@@ -31,20 +31,21 @@ pathspec==0.12.1 # via black
3131
platformdirs==4.4.0 # via black
3232
pluggy==1.6.0 # via pytest, pytest-cov
3333
priority==2.0.0 # via hypercorn
34-
psutil==7.0.0 # via hypofuzz (pyproject.toml)
34+
psutil==7.1.0 # via hypofuzz (pyproject.toml)
3535
pygments==2.19.2 # via pytest, rich
36-
pytest==8.4.1 # via -r deps/test.in, hypofuzz (pyproject.toml), pytest-cov, pytest-xdist
37-
pytest-cov==6.2.1 # via -r deps/test.in
36+
pytest==8.4.2 # via -r deps/test.in, hypofuzz (pyproject.toml), pytest-cov, pytest-xdist
37+
pytest-cov==7.0.0 # via -r deps/test.in
3838
pytest-xdist==3.8.0 # via -r deps/test.in
39-
pyyaml==6.0.2 # via libcst
39+
pytokens==0.1.10 # via black
40+
pyyaml==6.0.3 # via libcst
4041
requests==2.32.5 # via -r deps/test.in
4142
rich==14.1.0 # via hypothesis
4243
sniffio==1.3.1 # via anyio, trio
4344
sortedcontainers==2.4.0 # via hypothesis, trio
44-
starlette==0.47.3 # via hypofuzz (pyproject.toml)
45+
starlette==0.48.0 # via hypofuzz (pyproject.toml)
4546
taskgroup==0.2.2 # via hypercorn
4647
tomli==2.2.1 # via black, coverage, hypercorn, pytest
47-
trio==0.30.0 # via hypofuzz (pyproject.toml)
48+
trio==0.31.0 # via hypofuzz (pyproject.toml)
4849
typing-extensions==4.15.0 # via anyio, black, exceptiongroup, hypercorn, libcst, starlette, taskgroup
4950
urllib3==2.5.0 # via requests
5051
watchdog==6.0.0 # via hypothesis

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ keywords = ["python", "testing", "fuzzing", "property-based-testing"]
2727
dependencies = [
2828
"black>=23.3.0",
2929
"coverage>=5.2.1",
30-
"hypothesis[cli,watchdog]>=6.138.14",
30+
"hypothesis[cli,watchdog]>=6.140.2",
3131
"libcst>=1.0.0", # for hypothesis.extra._patching
3232
"psutil>=3.0.0",
3333
"pytest>=7.0.0",
@@ -127,7 +127,6 @@ ignore = [
127127
"E741",
128128
"FBT003",
129129
"PD011",
130-
"PD901",
131130
"PIE790", # See https://github.com/astral-sh/ruff/issues/10538
132131
"PT001",
133132
"PT003",

src/hypofuzz/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
from hypofuzz.detection import in_hypofuzz_run
44

5-
__version__ = "25.09.01"
5+
__version__ = "25.09.02"
66
__all__: list[str] = ["in_hypofuzz_run"]

src/hypofuzz/docs/changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
HypoFuzz uses [calendar-based versioning](https://calver.org/), with a
33
`YY-MM-patch` format.
44

5+
(v25-09-02)=
6+
## 25.09.02
7+
8+
* Fix error while running stateful tests
9+
* Support middle click to open links in new tab in more places
10+
511
(v25-09-01)=
612
## 25.09.01
713

src/hypofuzz/hypofuzz.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,13 @@ def _new_state(
174174
) -> HypofuzzStateForActualGivenExecution:
175175
arguments: list[Any] = []
176176

177-
if self.pytest_item is not None and isinstance(self.pytest_item.parent, Class):
177+
if (
178+
self.pytest_item is not None
179+
and isinstance(self.pytest_item.parent, Class)
180+
# don't get tricked by the .TestCase class in stateful tests;
181+
# that's already a standard @given test
182+
and not hasattr(self.pytest_item.obj, "_hypothesis_state_machine_class")
183+
):
178184
assert self._pytest_item_instance is not None
179185
# if we're a class-based test, we need to provide the `self` instance
180186
# as the first argument.

tests/common.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import dataclasses
12
import inspect
23
import os
34
import queue
@@ -298,6 +299,7 @@ def write_test_code(path: Path, db_dir, code: str) -> None:
298299
import pytest
299300
from hypothesis import given, settings, strategies as st, HealthCheck, target
300301
from hypothesis.database import DirectoryBasedExampleDatabase
302+
from hypothesis.stateful import RuleBasedStateMachine, rule
301303
302304
from hypofuzz import in_hypofuzz_run
303305
@@ -334,7 +336,7 @@ def interesting_origin(n: Optional[int] = None) -> InterestingOrigin:
334336
int("not an int")
335337
except Exception as e:
336338
origin = InterestingOrigin.from_exception(e)
337-
return origin._replace(lineno=n if n is not None else origin.lineno)
339+
return dataclasses.replace(origin, lineno=n if n is not None else origin.lineno)
338340

339341

340342
def collect(code: str) -> CollectionResult:

tests/conftest.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import os
2+
3+
# If this envvar is set, Hypothesis loads the CI profile. We can't combine that
4+
# with hypofuzz, since the CI profile sets derandomize=True, which hypofuzz
5+
# skips during collection.
6+
#
7+
# This has to be changed at the os.environ level, instead of doing
8+
# settings.load_profile("default"), because pytest collection and subprocesses
9+
# inherit the current os.environ and would think themselves as in CI.
10+
os.environ.pop("__TOX_ENVIRONMENT_VARIABLE_ORIGINAL_CI", None)

tests/test_corpus.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def observations(
5555
os_getpid=st.just(0),
5656
imported_at=st.just(0.0),
5757
data_status=statuses,
58+
phase=st.just(""),
5859
interesting_origin=st.builds(interesting_origin, n=st.integers()),
5960
choice_nodes=st.lists(nodes()).map(tuple),
6061
choice_spans=st.just(None),

0 commit comments

Comments
 (0)