.. _hypothesis-plugins: hypothesis plugin ================= We provide several extra features for Hypothesis users. And encourage to use it together with ``returns``. Installation ------------ You will need to install ``hypothesis`` separately. It is not bundled with ``returns``. We also require ``anyio`` package for this plugin to work with async laws. hypothesis entrypoint --------------------- We support a ``hypothesis`` entrypoint that is executed on ``hypothesis`` import. There we are registering all our containers as strategies. So, you don't have to. Example: .. code:: python from returns.result import Result from hypothesis import strategies as st 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. check_all_laws -------------- We also provide a very powerful mechanism of checking defined container laws. It works in a combination with "Laws as Values" feature we provide in the core. .. code:: python from returns.contrib.hypothesis.laws import check_all_laws from your.module import YourCustomContainer check_all_laws(YourCustomContainer) This one line of code will generate ~100 tests for all defined law in both ``YourCustomContainer`` and all its super types, including our internal ones. We also provide a way to configure the checking process with ``settings_kwargs``: .. code:: python check_all_laws(YourCustomContainer, settings_kwargs={'max_examples': 500}) This will increase the number of generated test to 500. We support all kwargs from ``@settings``, see `@settings docs `_. You can also change how ``hypothesis`` creates instances of your container. By default, we use ``.from_value``, ``.from_optional``, and ``.from_failure`` if we are able to find them. But, you can also pass types without these methods, but with ``__init__`` defined: .. code:: python from typing import Callable, TypeVar, final from returns.interfaces.mappable import Mappable1 from returns.primitives.container import BaseContainer from returns.primitives.hkt import SupportsKind1 _ValueType = TypeVar('_ValueType') _NewValueType = TypeVar('_NewValueType') @final class Number( BaseContainer, SupportsKind1['Number', _ValueType], Mappable1[_ValueType], ): def __init__(self, inner_value: _ValueType) -> None: super().__init__(inner_value) def map( self, function: Callable[[_ValueType], _NewValueType], ) -> 'Number[_NewValueType]': return Number(function(self._inner_value)) # We want to allow ``__init__`` method to be used: check_all_laws(Number, use_init=True) As you see, we don't support any ``from`` methods here. But, ``__init__`` would be used to generate values thanks to ``use_init=True``. By default, we don't allow to use ``__init__``, because there are different complex types like ``Future``, ``ReaderFutureResult``, etc that have complex ``__init__`` signatures. And we don't want to mess with them. 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. Further reading --------------- - `Projects Extending hypothesis `_ API Reference ------------- Types we have already registered for you ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. automodule:: returns.contrib.hypothesis._entrypoint :members: DSL to register custom containers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. automodule:: returns.contrib.hypothesis.containers :members: DSL to define laws ~~~~~~~~~~~~~~~~~~ .. autoclasstree:: returns.primitives.laws :strict: .. automodule:: returns.primitives.laws :members: Plugin internals ~~~~~~~~~~~~~~~~ .. automodule:: returns.contrib.hypothesis.laws :members: