Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2be1352
hypothesis: get lawful ancestors using the `laws()` classmethod.
pradeep90 Mar 11, 2025
16bc815
hypothesis: extract function for registering strategies.
pradeep90 Mar 11, 2025
02a4f50
hypothesis: replace `hypothesis` mutation with context manager.
pradeep90 Mar 11, 2025
9f5ee66
hypothesis: extract functions for strategy factories.
pradeep90 Mar 11, 2025
448ae84
hypothesis: inline context managers for pure functions and type vars.
pradeep90 Mar 11, 2025
96106b1
hypothesis: add test for hypothesis state with settings.
pradeep90 Mar 11, 2025
f476ef8
hypothesis: inline context managers for container and interfaces.
pradeep90 Mar 11, 2025
2957d5e
hypothesis: merge the context mappings.
pradeep90 Mar 11, 2025
e093247
hypothesis: rearrange functions in calling order.
pradeep90 Mar 11, 2025
9e7d609
hypothesis: extract a pure function for types-to-strategies.
pradeep90 Mar 11, 2025
cfc58fc
hypothesis: split settings into default and override.
pradeep90 Mar 11, 2025
bdccc04
hypothesis: accept other strategies in `check_all_laws`.
pradeep90 Mar 11, 2025
d57d6b0
hypothesis: add end-to-end test for registering callable.
pradeep90 Mar 12, 2025
db141ba
hypothesis: merge settings in `check_all_laws`.
pradeep90 Mar 12, 2025
31669c2
hypothesis: make `Settings` public and document it inline.
pradeep90 Mar 12, 2025
f465cc8
hypothesis: add type test.
pradeep90 Mar 12, 2025
17c39ee
hypothesis: add docs.
pradeep90 Mar 12, 2025
ab6a362
hypothesis: fix typo.
pradeep90 Mar 12, 2025
40da087
hypothesis: rename attribute and parameter for type strategies.
pradeep90 Mar 12, 2025
c1b78f2
Update docs/pages/contrib/hypothesis_plugins.rst
sobolevn Mar 12, 2025
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ See [0Ver](https://0ver.org/).

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

### Bugfixes

Expand Down
123 changes: 75 additions & 48 deletions docs/pages/contrib/hypothesis_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,40 +32,8 @@ So, you don't have to. Example:

assert st.from_type(Result).example()

This is a convenience thing only.


strategy_from_container
-----------------------

We provide a utility function
to create ``hypothesis`` strategy from any container.

You can use it to easily register your own containers.

.. code:: python

from hypothesis import strategies as st
from returns.contrib.hypothesis.containers import strategy_from_container

st.register_type_strategy(
YourContainerClass,
strategy_from_container(YourContainerClass),
)

You can also pass ``use_init`` keyword argument
if you wish to use ``__init__`` method to instantiate your containers.
Turned off by default.
Example:

.. code:: python

st.register_type_strategy(
YourContainerClass,
strategy_from_container(YourContainerClass, use_init=True),
)

Or you can write your own ``hypothesis`` strategy. It is also fine.
This means you can use ``Result``, ``Maybe``, etc. in your own property tests,
and ``hypothesis`` will generate values for them as expected.


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

You can also register a custom strategy to be used when running your
container's laws:
Warning::
Checking laws is not compatible with ``pytest-xdist``,
because we use a lot of global mutable state there.
Please, use ``returns_lawful`` marker
to exclude them from ``pytest-xdist`` execution plan.
Copy link
Member

Choose a reason for hiding this comment

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

We can also make a note about running them on a single node.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, this was an existing paragraph that I moved up. I don't have anything to add here.



Registering Custom Strategies when Checking Laws
------------------------------------------------

``hypothesis`` works by looking up strategies for the provided type
annotations. Given that the types provided by ``returns`` are very complicated
and not really native to Python, they may not be understood by ``hypothesis``,
and you may get runtime exceptions such as ``ResolutionFailed``.

In such cases, you may want to register custom strategies for types for which
``hypothesis`` does not find any strategies.

The main use case is registering a custom strategy to generate your container
when running its laws:

.. code:: python

Expand All @@ -150,22 +136,63 @@ container's laws:

check_all_laws(Number, container_strategy=st.builds(Number, st.integers()))

The ``container_strategy`` will be used only when running the tests generated
by the ``check_all_laws`` call above. It will have no effect on any other
property tests that involve ``Number``. You cannot use this argument together
with ``use_init``.
You can also register strategies for other types:

.. code:: python

from hypothesis import strategies as st

check_all_laws(
Number,
container_strategy=st.builds(Number, st.integers()),
type_strategies={Foo: st.builds(Foo, st.text())},
)

These custom strategies will be used only when running the tests generated by
the ``check_all_laws`` call above. They will have no effect on any other
property tests that involve the same types. You cannot use this argument
together with ``use_init``.


Registering Custom Strategies outside Law Tests
-----------------------------------------------

We provide a utility function
to create ``hypothesis`` strategy from any container:
``strategy_from_container``.

You can use it to register your own containers.

.. code:: python

from hypothesis import strategies as st
from returns.contrib.hypothesis.containers import strategy_from_container

st.register_type_strategy(
YourContainerClass,
strategy_from_container(YourContainerClass),
)

You can also pass ``use_init`` keyword argument
if you wish to use ``__init__`` method to instantiate your containers.
Turned off by default.
Example:

.. code:: python

st.register_type_strategy(
YourContainerClass,
strategy_from_container(YourContainerClass, use_init=True),
)

Or you can write your own ``hypothesis`` strategy. It is also fine.

Warning::
Avoid directly registering your container's strategy with ``hypothesis``
using ``st.register_type_strategy``. Because of the way we emulate
higher-kinded types, ``hypothesis`` may mistakenly use the strategy
for other incompatible containers and cause spurious test failures.

Warning::
Checking laws is not compatible with ``pytest-xdist``,
because we use a lot of global mutable state there.
Please, use ``returns_lawful`` marker
to exclude them from ``pytest-xdist`` execution plan.
higher-kinded types, ``hypothesis`` may mistakenly use the strategy for
other incompatible containers and cause spurious test failures. We specify
how to do it just in case you need it and you know what you're doing.


Further reading
Expand Down
Loading