Skip to content

Commit db141ba

Browse files
committed
hypothesis: merge settings in check_all_laws.
This way, the deeper code doesn't need to know about defaults and overrides. It just deals with `Settings`.
1 parent d57d6b0 commit db141ba

2 files changed

Lines changed: 29 additions & 25 deletions

File tree

returns/contrib/hypothesis/laws.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,16 @@ class _Settings:
3131
container_strategy: StrategyFactory | None
3232
other_strategies: dict[type[object], StrategyFactory]
3333

34+
def __post_init__(self) -> None:
35+
"""Check that the settings are mutually compatible."""
36+
if self.use_init and self.container_strategy is not None:
37+
raise AssertionError(
38+
'Expected only one of `use_init` and'
39+
' `container_strategy` to be truthy'
40+
)
41+
3442
def __or__(self, other: Self) -> Self:
43+
"""Merge the two settings, preferring values from `other`."""
3544
return _Settings(
3645
settings_kwargs=self.settings_kwargs | other.settings_kwargs,
3746
use_init=self.use_init | other.use_init,
@@ -41,20 +50,23 @@ def __or__(self, other: Self) -> Self:
4150
other_strategies=self.other_strategies | other.other_strategies,
4251
)
4352

44-
def __post_init__(self) -> None:
45-
"""Check that the settings are mutually compatible."""
46-
if self.use_init and self.container_strategy is not None:
47-
raise AssertionError(
48-
'Expected only one of `use_init` and'
49-
' `container_strategy` to be truthy'
50-
)
51-
5253

53-
def _default_settings(container_type: type[Lawful]) -> _Settings:
54+
def default_settings(container_type: type[Lawful]) -> _Settings:
5455
"""Return default settings for creating law tests.
5556
56-
We use special strategies for `TypeVar` and `Callable` by default, but
57-
they can be overriden by the user if needed.
57+
We use some special strategies by default, but
58+
they can be overriden by the user if needed:
59+
60+
+ `TypeVar`: We need to make sure that the values generated behave
61+
sensibly when tested for equality.
62+
63+
+ `collections.abc.Callable`: We need to generate pure functions, which
64+
are not the default.
65+
66+
Note that this is `collections.abc.Callable`, NOT `typing.Callable`. This
67+
is because, at runtime, `typing.get_origin(Callable[[int], str])` is
68+
`collections.abc.Callable`. So, this is the type we should register with
69+
`hypothesis`.
5870
"""
5971
return _Settings(
6072
settings_kwargs={},
@@ -120,7 +132,7 @@ def check_all_laws(
120132
- https://mmhaskell.com/blog/2017/3/13/obey-the-type-laws
121133
122134
"""
123-
settings = _Settings(
135+
settings = default_settings(container_type) | _Settings(
124136
settings_kwargs or {},
125137
use_init,
126138
container_strategy,
@@ -255,13 +267,9 @@ def _types_to_strategies(
255267
container_type: type[Lawful],
256268
settings: _Settings,
257269
) -> dict[type[object], StrategyFactory]:
258-
"""Return a mapping from type to `hypothesis` strategy.
259-
260-
We override the default settings with the user-provided `settings`.
261-
"""
262-
merged_settings = _default_settings(container_type) | settings
263-
return merged_settings.other_strategies | _container_mapping(
264-
container_type, merged_settings
270+
"""Return a mapping from type to `hypothesis` strategy."""
271+
return settings.other_strategies | _container_mapping(
272+
container_type, settings
265273
)
266274

267275

tests/test_contrib/test_hypothesis/test_type_resolution.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from returns.contrib.hypothesis.laws import (
1919
_Settings, # noqa: PLC2701
2020
_types_to_strategies, # noqa: PLC2701
21+
default_settings,
2122
)
2223
from returns.contrib.hypothesis.type_resolver import (
2324
StrategyFactory,
@@ -183,12 +184,7 @@ def test_types_to_strategies_default() -> None: # noqa: WPS210
183184

184185
result = _types_to_strategies(
185186
container_type,
186-
_Settings(
187-
settings_kwargs={},
188-
use_init=False,
189-
container_strategy=None,
190-
other_strategies={},
191-
),
187+
default_settings(container_type),
192188
)
193189

194190
wrapper_strategy = (

0 commit comments

Comments
 (0)