Skip to content

Commit b107680

Browse files
committed
Improves docs
1 parent 0ccdb53 commit b107680

File tree

1 file changed

+60
-59
lines changed

1 file changed

+60
-59
lines changed

returns/context/requires_context_future_result.py

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,53 @@ class RequiresContextFutureResult(
4242
BaseContainer,
4343
Generic[_EnvType, _ValueType, _ErrorType],
4444
):
45-
"""Someday this container will grow very big."""
45+
"""
46+
The ``RequiresContextFutureResult`` combinator.
47+
48+
This probably the main type people are going to use in ``async`` programms.
49+
50+
See :class:`returns.context.requires_context.RequiresContext`,
51+
:class:`returns.context.requires_context_result.RequiresContextResult`,
52+
and
53+
:class:`returns.context.requires_context_result.RequiresContextIOResult`
54+
for more docs.
55+
56+
This is just a handy wrapper around
57+
``RequiresContext[env, FutureResult[a, b]]``
58+
which represents a context-dependent impure operation that might fail.
59+
60+
So, this is a thin wrapper, without any changes in logic.
61+
Why do we need this wrapper? That's just for better usability!
62+
63+
This way ``RequiresContextIOResult`` allows to simply work with:
64+
65+
- raw values and pure functions
66+
- ``RequiresContext`` values and pure functions returning it
67+
- ``RequiresContextResult`` values and pure functions returning it
68+
- ``RequiresContextIOResult`` values and pure functions returning it
69+
- ``Result`` and pure functions returning it
70+
- ``IOResult`` and functions returning it
71+
- ``FutureResult`` and functions returning it
72+
- other ``RequiresContextFutureResult`` related functions and values
73+
74+
This is a complex type for complex tasks!
75+
76+
Important implementation detail:
77+
due it is meaning, ``RequiresContextFutureResult``
78+
cannot have ``Success`` and ``Failure`` subclasses.
79+
80+
We only have just one type. That's by design.
81+
82+
Different converters are also not supported for this type.
83+
Use converters inside the ``RequiresContext`` context, not outside.
84+
85+
See also:
86+
https://dev.to/gcanti/getting-started-with-fp-ts-reader-1ie5
87+
https://en.wikipedia.org/wiki/Lazy_evaluation
88+
https://bit.ly/2R8l4WK
89+
https://bit.ly/2RwP4fp
90+
91+
"""
4692

4793
#: Inner value of `RequiresContext`
4894
#: is just a function that returns `FutureResult`.
@@ -188,15 +234,7 @@ def bind(
188234
>>> from returns.future import FutureResult
189235
>>> from returns.io import IOSuccess, IOFailure
190236
191-
>>> def first(lg: bool) -> RequiresContextFutureResult[int, int, int]:
192-
... # `deps` has `int` type here:
193-
... return RequiresContextFutureResult(
194-
... lambda deps: FutureResult.from_value(
195-
... deps,
196-
... ) if lg else FutureResult.from_failure(-deps),
197-
... )
198-
199-
>>> def second(
237+
>>> def function(
200238
... number: int,
201239
... ) -> RequiresContextFutureResult[int, str, int]:
202240
... # `deps` has `int` type here:
@@ -205,11 +243,13 @@ def bind(
205243
... )
206244
207245
>>> assert anyio.run(
208-
... first(True).bind(second)(1).awaitable,
209-
... ) == IOSuccess('2')
246+
... RequiresContextFutureResult.from_value(2).bind(function),
247+
... 3,
248+
... ) == IOSuccess('5')
210249
>>> assert anyio.run(
211-
... first(False).bind(second)(2).awaitable,
212-
... ) == IOFailure(-2)
250+
... RequiresContextFutureResult.from_failure(2).bind(function),
251+
... 3,
252+
... ) == IOFailure(2)
213253
214254
"""
215255
return RequiresContextFutureResult(
@@ -229,11 +269,11 @@ def bind_result(
229269
230270
>>> import anyio
231271
>>> from returns.context import RequiresContextFutureResult
232-
>>> from returns.result import Success, Failure, Result
272+
>>> from returns.result import Success, Result
233273
>>> from returns.io import IOSuccess, IOFailure
234274
235275
>>> def function(num: int) -> Result[int, str]:
236-
... return Success(num + 1) if num > 0 else Failure('<0')
276+
... return Success(num + 1)
237277
238278
>>> assert anyio.run(
239279
... RequiresContextFutureResult.from_value(1).bind_result(
@@ -242,13 +282,6 @@ def bind_result(
242282
... RequiresContextFutureResult.empty,
243283
... ) == IOSuccess(2)
244284
245-
>>> assert anyio.run(
246-
... RequiresContextFutureResult.from_value(0).bind_result(
247-
... function,
248-
... ),
249-
... RequiresContextFutureResult.empty,
250-
... ) == IOFailure('<0')
251-
252285
>>> assert anyio.run(
253286
... RequiresContextFutureResult.from_failure(':(').bind_result(
254287
... function,
@@ -280,8 +313,6 @@ def bind_context(
280313
>>> def function(arg: int) -> RequiresContext[str, int]:
281314
... return RequiresContext(lambda deps: len(deps) + arg)
282315
283-
>>> assert function(2)('abc') == 5
284-
285316
>>> assert anyio.run(
286317
... RequiresContextFutureResult.from_value(2).bind_context(
287318
... function,
@@ -318,34 +349,20 @@ def bind_context_result(
318349
>>> import anyio
319350
>>> from returns.context import RequiresContextResult
320351
>>> from returns.io import IOSuccess, IOFailure
321-
>>> from returns.result import Success, Failure
352+
>>> from returns.result import Success
322353
323354
>>> def function(arg: int) -> RequiresContextResult[str, int, int]:
324-
... if arg > 0:
325-
... return RequiresContextResult(
326-
... lambda deps: Success(len(deps) + arg),
327-
... )
328355
... return RequiresContextResult(
329-
... lambda deps: Failure(len(deps) + arg),
356+
... lambda deps: Success(len(deps) + arg),
330357
... )
331358
332-
>>> assert function(2)('abc') == Success(5)
333-
>>> assert function(-1)('abc') == Failure(2)
334-
335359
>>> instance = RequiresContextFutureResult.from_value(
336360
... 2,
337361
... ).bind_context_result(
338362
... function,
339363
... )('abc')
340364
>>> assert anyio.run(instance.awaitable) == IOSuccess(5)
341365
342-
>>> instance = RequiresContextFutureResult.from_value(
343-
... -1,
344-
... ).bind_context_result(
345-
... function,
346-
... )('abc')
347-
>>> assert anyio.run(instance.awaitable) == IOFailure(2)
348-
349366
>>> instance = RequiresContextFutureResult.from_failure(
350367
... 2,
351368
... ).bind_context_result(
@@ -405,7 +422,7 @@ def bind_ioresult(
405422
>>> from returns.io import IOResult, IOSuccess, IOFailure
406423
407424
>>> def function(num: int) -> IOResult[int, str]:
408-
... return IOSuccess(num + 1) if num > 0 else IOFailure('<0')
425+
... return IOSuccess(num + 1)
409426
410427
>>> assert anyio.run(
411428
... RequiresContextFutureResult.from_value(1).bind_ioresult(
@@ -414,13 +431,6 @@ def bind_ioresult(
414431
... RequiresContextFutureResult.empty,
415432
... ) == IOSuccess(2)
416433
417-
>>> assert anyio.run(
418-
... RequiresContextFutureResult.from_value(0).bind_ioresult(
419-
... function,
420-
... ),
421-
... RequiresContextFutureResult.empty,
422-
... ) == IOFailure('<0')
423-
424434
>>> assert anyio.run(
425435
... RequiresContextFutureResult.from_failure(':(').bind_ioresult(
426436
... function,
@@ -510,16 +520,14 @@ def rescue(
510520
>>> import anyio
511521
>>> from returns.context import RequiresContextFutureResult
512522
>>> from returns.future import FutureResult
513-
>>> from returns.io import IOSuccess, IOFailure
523+
>>> from returns.io import IOSuccess
514524
515525
>>> def rescuable(
516526
... arg: str,
517527
... ) -> RequiresContextFutureResult[str, str, str]:
518528
... return RequiresContextFutureResult(
519529
... lambda deps: FutureResult.from_value(
520530
... deps + arg,
521-
... ) if len(arg) > 1 else FutureResult.from_failure(
522-
... arg + deps,
523531
... ),
524532
... )
525533
@@ -528,13 +536,6 @@ def rescue(
528536
... 'c',
529537
... ) == IOSuccess('a')
530538
531-
>>> assert anyio.run(
532-
... RequiresContextFutureResult.from_failure('a').rescue(
533-
... rescuable,
534-
... ),
535-
... 'c',
536-
... ) == IOFailure('ac')
537-
538539
>>> assert anyio.run(
539540
... RequiresContextFutureResult.from_failure('aa').rescue(
540541
... rescuable,

0 commit comments

Comments
 (0)