Skip to content

Commit 17c39ee

Browse files
committed
hypothesis: add docs.
1 parent f465cc8 commit 17c39ee

File tree

3 files changed

+80
-49
lines changed

3 files changed

+80
-49
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ See [0Ver](https://0ver.org/).
2828

2929
- Make `hypothesis` plugin test laws from user-defined interfaces too
3030
- Make `hypothesis` plugin accept user-defined strategies
31+
- Allow users to override the `hypothesis` plugin's strategies for types, such
32+
as `TypeVar` and `Callable`.
3133

3234
### Bugfixes
3335

docs/pages/contrib/hypothesis_plugins.rst

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -32,40 +32,8 @@ So, you don't have to. Example:
3232
3333
assert st.from_type(Result).example()
3434
35-
This is a convenience thing only.
36-
37-
38-
strategy_from_container
39-
-----------------------
40-
41-
We provide a utility function
42-
to create ``hypothesis`` strategy from any container.
43-
44-
You can use it to easily register your own containers.
45-
46-
.. code:: python
47-
48-
from hypothesis import strategies as st
49-
from returns.contrib.hypothesis.containers import strategy_from_container
50-
51-
st.register_type_strategy(
52-
YourContainerClass,
53-
strategy_from_container(YourContainerClass),
54-
)
55-
56-
You can also pass ``use_init`` keyword argument
57-
if you wish to use ``__init__`` method to instantiate your containers.
58-
Turned off by default.
59-
Example:
60-
61-
.. code:: python
62-
63-
st.register_type_strategy(
64-
YourContainerClass,
65-
strategy_from_container(YourContainerClass, use_init=True),
66-
)
67-
68-
Or you can write your own ``hypothesis`` strategy. It is also fine.
35+
This means you can use ``Result``, ``Maybe``, etc. in your own property tests,
36+
and ``hypothesis`` will generate values for them as expected.
6937

7038

7139
check_all_laws
@@ -140,8 +108,26 @@ like ``Future``, ``ReaderFutureResult``, etc
140108
that have complex ``__init__`` signatures.
141109
And we don't want to mess with them.
142110

143-
You can also register a custom strategy to be used when running your
144-
container's laws:
111+
Warning::
112+
Checking laws is not compatible with ``pytest-xdist``,
113+
because we use a lot of global mutable state there.
114+
Please, use ``returns_lawful`` marker
115+
to exclude them from ``pytest-xdist`` execution plan.
116+
117+
118+
Registering Custom Strategies when Checking Laws
119+
------------------------------------------------
120+
121+
``hypothesis`` works by looking up strategies for the provided type
122+
annotations. Given that the types provided by ``returns`` are very complicated
123+
and not really native to Python, they may not be understood by ``hypothesis``,
124+
and you may get runtime exceptions such as ``ResolutionFailed``.
125+
126+
In such cases, you may want to register custom strategies for types for which
127+
``hypothesis`` does not find any strategies.
128+
129+
The main use case is registering a custom strategy to generate your container
130+
when running its laws:
145131

146132
.. code:: python
147133
@@ -150,22 +136,64 @@ container's laws:
150136
151137
check_all_laws(Number, container_strategy=st.builds(Number, st.integers()))
152138
153-
The ``container_strategy`` will be used only when running the tests generated
154-
by the ``check_all_laws`` call above. It will have no effect on any other
155-
property tests that involve ``Number``. You cannot use this argument together
156-
with ``use_init``.
139+
You can also register strategies for other types:
140+
141+
.. code:: python
142+
143+
144+
from hypothesis import strategies as st
145+
146+
check_all_laws(
147+
Number,
148+
container_strategy=st.builds(Number, st.integers()),
149+
other_strategies={Foo: st.builds(Foo, st.text())},
150+
)
151+
152+
These custom strategies will be used only when running the tests generated by
153+
the ``check_all_laws`` call above. They will have no effect on any other
154+
property tests that involve the same types. You cannot use this argument
155+
together with ``use_init``.
156+
157+
158+
Registering Custom Strategies outside Law Tests
159+
-----------------------------------------------
160+
161+
We provide a utility function
162+
to create ``hypothesis`` strategy from any container:
163+
``strategy_from_container``.
164+
165+
You can use it to register your own containers.
166+
167+
.. code:: python
168+
169+
from hypothesis import strategies as st
170+
from returns.contrib.hypothesis.containers import strategy_from_container
171+
172+
st.register_type_strategy(
173+
YourContainerClass,
174+
strategy_from_container(YourContainerClass),
175+
)
176+
177+
You can also pass ``use_init`` keyword argument
178+
if you wish to use ``__init__`` method to instantiate your containers.
179+
Turned off by default.
180+
Example:
181+
182+
.. code:: python
183+
184+
st.register_type_strategy(
185+
YourContainerClass,
186+
strategy_from_container(YourContainerClass, use_init=True),
187+
)
188+
189+
Or you can write your own ``hypothesis`` strategy. It is also fine.
157190

158191
Warning::
159192
Avoid directly registering your container's strategy with ``hypothesis``
160193
using ``st.register_type_strategy``. Because of the way we emulate
161-
higher-kinded types, ``hypothesis`` may mistakenly use the strategy
162-
for other incompatible containers and cause spurious test failures.
163-
164-
Warning::
165-
Checking laws is not compatible with ``pytest-xdist``,
166-
because we use a lot of global mutable state there.
167-
Please, use ``returns_lawful`` marker
168-
to exclude them from ``pytest-xdist`` execution plan.
194+
higher-kinded types, ``hypothesis`` may mistakenly use the strategy for
195+
other incompatible containers and cause spurious test failures. We specify
196+
how to do it just in case you need it and you know what you're doing.
169197

170198

171199
Further reading

tests/test_contrib/test_hypothesis/test_laws/test_custom_strategy_for_callable.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
77
Without the custom strategy, we would simply get instances of `_Wrapper`, even
88
though it is not an `Applicative`, because `_Wrapper` is a subtype of `KindN`
9-
and `hypothesis` doesn't know about that `KindN` is just emulating HKTs.
9+
and `hypothesis` doesn't know about the fact that `KindN` is just emulating
10+
HKTs.
1011
"""
1112

1213
from abc import abstractmethod

0 commit comments

Comments
 (0)