Skip to content

Commit 31669c2

Browse files
committed
hypothesis: make Settings public and document it inline.
1 parent db141ba commit 31669c2

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

returns/contrib/hypothesis/laws.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,26 @@
2323

2424
@final
2525
@dataclasses.dataclass(frozen=True)
26-
class _Settings:
27-
"""Settings that we provide to an end user."""
26+
class Settings:
27+
"""Settings for the law tests.
2828
29+
Any settings passed by the user will override the value from
30+
:func:`default_settings`.
31+
"""
32+
33+
#: Settings directly passed on to `hypothesis`. We support all kwargs from
34+
#: ``@settings``, see `@settings docs
35+
#: <https://hypothesis.readthedocs.io/en/latest/settings.html>`_.
2936
settings_kwargs: dict[str, Any]
37+
#: Whether to create examples using ``__init__`` instead of the default .
3038
use_init: bool
39+
#: Strategy for generating the container. By default, we generate examples
40+
#: of a container using:
41+
#: :func:`returns.contrib.hypothesis.containers.strategy_from_container`.
3142
container_strategy: StrategyFactory | None
43+
#: Strategies for generating values of other types. This can be useful for
44+
#: overriding ``TypeVar``, ``Callable``, etc. in case you use certain
45+
#: types that ``hypothesis`` is unable to find.
3246
other_strategies: dict[type[object], StrategyFactory]
3347

3448
def __post_init__(self) -> None:
@@ -41,7 +55,7 @@ def __post_init__(self) -> None:
4155

4256
def __or__(self, other: Self) -> Self:
4357
"""Merge the two settings, preferring values from `other`."""
44-
return _Settings(
58+
return Settings(
4559
settings_kwargs=self.settings_kwargs | other.settings_kwargs,
4660
use_init=self.use_init | other.use_init,
4761
container_strategy=self.container_strategy
@@ -51,7 +65,7 @@ def __or__(self, other: Self) -> Self:
5165
)
5266

5367

54-
def default_settings(container_type: type[Lawful]) -> _Settings:
68+
def default_settings(container_type: type[Lawful]) -> Settings:
5569
"""Return default settings for creating law tests.
5670
5771
We use some special strategies by default, but
@@ -68,7 +82,7 @@ def default_settings(container_type: type[Lawful]) -> _Settings:
6882
`collections.abc.Callable`. So, this is the type we should register with
6983
`hypothesis`.
7084
"""
71-
return _Settings(
85+
return Settings(
7286
settings_kwargs={},
7387
use_init=False,
7488
container_strategy=None,
@@ -132,7 +146,7 @@ def check_all_laws(
132146
- https://mmhaskell.com/blog/2017/3/13/obey-the-type-laws
133147
134148
"""
135-
settings = default_settings(container_type) | _Settings(
149+
settings = default_settings(container_type) | Settings(
136150
settings_kwargs or {},
137151
use_init,
138152
container_strategy,
@@ -212,7 +226,7 @@ def _create_law_test_case(
212226
interface: type[Lawful],
213227
law: Law,
214228
*,
215-
settings: _Settings,
229+
settings: Settings,
216230
) -> None:
217231
test_function = given(st.data())(
218232
hypothesis_settings(**settings.settings_kwargs)(
@@ -248,7 +262,7 @@ def _run_law(
248262
container_type: type[Lawful],
249263
law: Law,
250264
*,
251-
settings: _Settings,
265+
settings: Settings,
252266
) -> Callable[[st.DataObject], None]:
253267
def factory(source: st.DataObject) -> None:
254268
with ExitStack() as stack:
@@ -265,7 +279,7 @@ def factory(source: st.DataObject) -> None:
265279

266280
def _types_to_strategies(
267281
container_type: type[Lawful],
268-
settings: _Settings,
282+
settings: Settings,
269283
) -> dict[type[object], StrategyFactory]:
270284
"""Return a mapping from type to `hypothesis` strategy."""
271285
return settings.other_strategies | _container_mapping(
@@ -275,7 +289,7 @@ def _types_to_strategies(
275289

276290
def _container_mapping(
277291
container_type: type[Lawful],
278-
settings: _Settings,
292+
settings: Settings,
279293
) -> dict[type[object], StrategyFactory]:
280294
"""Map `container_type` and its interfaces to the container strategy."""
281295
container_strategy = _strategy_for_container(container_type, settings)
@@ -287,7 +301,7 @@ def _container_mapping(
287301

288302
def _strategy_for_container(
289303
container_type: type[Lawful],
290-
settings: _Settings,
304+
settings: Settings,
291305
) -> StrategyFactory:
292306
return (
293307
strategy_from_container(container_type, use_init=settings.use_init)

tests/test_contrib/test_hypothesis/test_type_resolution.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
RequiresContextResultE,
1717
)
1818
from returns.contrib.hypothesis.laws import (
19-
_Settings, # noqa: PLC2701
19+
Settings,
2020
_types_to_strategies, # noqa: PLC2701
2121
default_settings,
2222
)
@@ -116,13 +116,13 @@ def test_custom_readerresult_types_resolve(
116116

117117
def test_merge_settings() -> None:
118118
"""Check that each part of the settings can be overridden by users."""
119-
settings1 = _Settings(
119+
settings1 = Settings(
120120
settings_kwargs={'a': 1, 'b': 2},
121121
use_init=False,
122122
container_strategy=st.integers(),
123123
other_strategies={int: st.integers(max_value=10), str: st.text('abc')},
124124
)
125-
settings2 = _Settings(
125+
settings2 = Settings(
126126
settings_kwargs={'a': 1, 'c': 3},
127127
use_init=False,
128128
container_strategy=st.integers(max_value=20),
@@ -131,7 +131,7 @@ def test_merge_settings() -> None:
131131

132132
result = settings1 | settings2
133133

134-
assert result == _Settings(
134+
assert result == Settings(
135135
settings_kwargs={'a': 1, 'b': 2, 'c': 3},
136136
use_init=False,
137137
container_strategy=st.integers(max_value=20),
@@ -149,13 +149,13 @@ def test_merge_use_init() -> None:
149149
Note: They can't set a `True` to `False`, since we use `|` to merge.
150150
However, the default value is `False`, so this should not be a problem.
151151
"""
152-
settings1 = _Settings(
152+
settings1 = Settings(
153153
settings_kwargs={},
154154
use_init=False,
155155
container_strategy=None,
156156
other_strategies={},
157157
)
158-
settings2 = _Settings(
158+
settings2 = Settings(
159159
settings_kwargs={},
160160
use_init=True,
161161
container_strategy=None,
@@ -164,7 +164,7 @@ def test_merge_use_init() -> None:
164164

165165
result = settings1 | settings2
166166

167-
assert result == _Settings(
167+
assert result == Settings(
168168
settings_kwargs={},
169169
use_init=True,
170170
container_strategy=None,
@@ -230,7 +230,7 @@ def test_types_to_strategies_overrides() -> None: # noqa: WPS210
230230

231231
result = _types_to_strategies(
232232
container_type,
233-
_Settings(
233+
Settings(
234234
settings_kwargs={},
235235
use_init=False,
236236
container_strategy=st.builds(container_type, st.integers()),

0 commit comments

Comments
 (0)