### Install returns with mypy support Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/mypy_plugins.rst Install the returns library with the compatible mypy extra to include the necessary components for the mypy plugin. ```bash pip install 'returns[compatible-mypy]' ``` -------------------------------- ### Install Returns Package Source: https://github.com/dry-python/returns/blob/master/README.md Use pip to install the Returns package. For compatibility with the latest mypy, use the [compatible-mypy] extra. ```bash pip install returns ``` ```bash pip install returns[compatible-mypy] ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/dry-python/returns/blob/master/CONTRIBUTING.md Use this command to install all project dependencies managed by poetry. ```bash poetry install ``` -------------------------------- ### Initial Django View and Logic Source: https://github.com/dry-python/returns/blob/master/README.md An example of a basic Django view and its associated logic for calculating points, before introducing configurable thresholds. ```python from django.http import HttpRequest, HttpResponse from words_app.logic import calculate_points def view(request: HttpRequest) -> HttpResponse: user_word: str = request.POST['word'] # just an example points = calculate_points(user_word) ... # later you show the result to user somehow # Somewhere in your `words_app/logic.py`: def calculate_points(word: str) -> int: guessed_letters_count = len([letter for letter in word if letter != '.']) return _award_points_for_letters(guessed_letters_count) def _award_points_for_letters(guessed: int) -> int: return 0 if guessed < 5 else guessed # minimum 6 points possible! ``` -------------------------------- ### Result Type Usage Example Source: https://github.com/dry-python/returns/blob/master/docs/pages/result.rst Demonstrates how to use the Result type with Success and Failure, and how to compose functions using `unify`. ```APIDOC ## Result Type Usage Example ### Description This example shows how to create a function that returns a `Result` type, handling potential errors like `ZeroDivisionError`. It also demonstrates composing this function with another `Result` using the `unify` function from `returns.pointfree`. ### Code ```python from returns.result import Result, Success, Failure from returns.pointfree import unify def div(number: int) -> Result[float, ZeroDivisionError]: if number: return Success(1 / number) return Failure(ZeroDivisionError('division by zero')) container: Result[int, ValueError] = Success(1) assert unify(div)(container) == Success(1.0) ``` ### Output Type ``` Result[float, Union[ValueError, ZeroDivisionError]] ``` ``` -------------------------------- ### Configure Law Checking with Max Examples Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/hypothesis_plugins.rst Configures the number of examples generated during law checking by passing `settings_kwargs`. This allows fine-tuning the test generation process, similar to the `@settings` decorator in hypothesis. ```python check_all_laws(YourCustomContainer, settings_kwargs={'max_examples': 500}) ``` -------------------------------- ### Install Extra Dependencies for Checks Source: https://github.com/dry-python/returns/blob/master/CONTRIBUTING.md Install extra dependencies for hypothesis or mypy plugin checks using poetry's extras feature. ```bash poetry install --extras check-laws ``` ```bash poetry install --extras compatible-mypy ``` -------------------------------- ### BindableN Container Returning Function Example Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Demonstrates a function that returns a container, as required by the BindableN interface. This function takes a string and returns a Maybe container. ```python >>> from returns.maybe import Maybe >>> def can_be_bound(string: str) -> Maybe[str]: ... return Some(string + '!') ``` -------------------------------- ### Generate a list of IO containers with random numbers Source: https://github.com/dry-python/returns/blob/master/docs/pages/container.rst Creates a list of 10 IO containers, each holding an integer. This setup is used to demonstrate summing multiple containerized values. ```python >>> import random >>> from returns.io import IO >>> def random_number() -> IO[int]: ... return IO(2) # Example, basically alias of ``random.randint(1, 5)`` >>> numbers = [random_number() for _ in range(10)] >>> assert len(numbers) == 10 >>> assert all(isinstance(number, IO) for number in numbers) ``` -------------------------------- ### Using Generic Container Transformation Source: https://github.com/dry-python/returns/blob/master/docs/pages/hkt.rst Examples of using the 'to_str' function with different container types like Maybe and IO, demonstrating polymorphic behavior. ```python >>> from returns.maybe import Maybe >>> from returns.io import IO >>> assert to_str(Maybe.from_value(1)) == Maybe.from_value('1') >>> assert to_str(IO.from_value(1)) == IO.from_value('1') ``` -------------------------------- ### Map vs Bind Operations Source: https://github.com/dry-python/returns/blob/master/docs/pages/result.rst Explains the difference between `map` and `bind` operations on the Result type and provides examples. ```APIDOC ## Map vs Bind Operations ### Description This section clarifies the usage of `map` and `bind` methods on the `Result` type. `map` is used for pure functions without side-effects, while `bind` is used for functions that might produce side-effects (like exceptions) and return a `Result` instance. The `safe` decorator is shown as a way to handle potential exceptions. ### Map Example ```python from returns.result import Success def cast_to_bool(arg: int) -> bool: return bool(arg) assert Success(1).map(cast_to_bool) == Success(True) ``` ### Bind Example ```python import json from returns.result import Failure, Result, Success, safe @safe def parse_json(arg: str) -> dict: return json.loads(arg) assert Success('{"example": "example"}').bind(parse_json) == Success({"example": "example"}) assert Success('').bind(parse_json).alt(str) == Failure('Expecting value: line 1 column 1 (char 0)') ``` ``` -------------------------------- ### Bind Right Identity Law Example Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Demonstrates the Right Identity law for the bind operation. It shows that binding a value through the bindable constructor yields the same result as direct instantiation. ```python >>> def can_be_bound(value: int) -> Number[int]: ... return Number(value) >>> assert Number.from_value(5).bind(can_be_bound) == can_be_bound(5) ``` -------------------------------- ### MappableN Pure Function Example Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Shows a pure function suitable for the MappableN interface. This function takes a string and returns a string without side effects. ```python >>> def can_be_mapped(string: str) -> str: ... return string ``` -------------------------------- ### Define a Custom Applicative Container Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Provides an example of creating a custom container that implements the Applicative1 interface. This includes defining `map`, `apply`, and `from_value` methods. ```python >>> from typing import Callable, TypeVar >>> from returns.interfaces.applicative import Applicative1 >>> from returns.primitives.hkt import SupportsKind1, Kind1, dekind >>> from returns.primitives.container import BaseContainer >>> _NumberType = TypeVar('_NumberType') >>> _NewNumberType = TypeVar('_NewNumberType') >>> class Number( ... BaseContainer, ... SupportsKind1['Number', _NumberType], ... Applicative1[_NumberType], ... ): ... def __init__(self, inner_value: _NumberType) -> None: ... super().__init__(inner_value) ... ... def map( # This method is required by Mappable ... self, ... function: Callable[[_NumberType], _NewNumberType] ... ) -> 'Number[_NewNumberType]': ... return Number(function(self._inner_value)) ... ... def apply( # This method is required by Applicative ... self, ... container: Kind1[ ... 'Number', ... Callable[[_NumberType], _NewNumberType], ... ], ... ) -> 'Number[_NewNumberType]': ... return Number.from_value( ... dekind(container._inner_value(self._inner_value)), ... ) ... ... @classmethod ... def from_value( # This method is required by Applicative ... cls, ... inner_value: _NewNumberType, ... ``` -------------------------------- ### Await FutureResult to get IOResult Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Demonstrates how to await a FutureResult to obtain the actual IOResult. This is necessary because FutureResult holds a coroutine that needs to be executed. ```python >>> # it's just the intention of having one, >>> # we have to await it to get the real result >>> result_like: FutureResult[int, str] = FutureResult(coro(1)) >>> assert isinstance(result_like, FutureResultBasedN) >>> assert isinstance(result_like, IOResultLikeN) >>> assert isinstance(result_like, ResultLikeN) >>> # `anyio.run(...)` will await our coroutine and give the real result to us >>> result: IOResult[int, str] = anyio.run(result_like.awaitable) >>> assert isinstance(result, IOResultBasedN) >>> assert isinstance(result, ResultLikeN) >>> # Compare it with the real result: >>> assert isinstance(Success(1), ResultBasedN) ``` -------------------------------- ### Compose functions with pipe Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Use `pipe` to create a reusable pipeline of functions. This is useful when you don't have an initial instance to start with. Requires mypy plugins. ```python >>> from returns.pipeline import pipe >>> pipeline = pipe(str, lambda x: x + 'b', str.upper) >>> assert pipeline(1) == '1B' ``` -------------------------------- ### Bind Associative Law Example Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Verifies the Associative Law for the bind operation. It compares binding sequentially with two functions versus binding with a composed function. ```python >>> def minus_one(arg: int) -> Number[int]: ... return Number(arg - 1) >>> def half(arg: int) -> Number[int]: ... return Number(arg // 2) >>> number = Number(9) >>> assert number.bind(minus_one).bind(half) == number.bind( ... lambda value: minus_one(value).bind(half), ... ) ``` -------------------------------- ### Combining managed with flow for pipelines Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Shows how to integrate the `managed` function into a functional pipeline using `flow`. This example parses a TOML file and extracts the project name, demonstrating a sequence of operations including file reading and data extraction. ```python >>> import tomlkit >>> from returns.pipeline import flow >>> from returns.pointfree import bind_result >>> from returns.result import safe >>> from returns.io import IOSuccess >>> @safe ... def parse_toml(file_contents: str) -> dict: ... return tomlkit.parse(file_contents) >>> @safe ... def get_project_name(parsed: dict) -> str: ... return parsed['tool']['poetry']['name'] >>> pipeline_result = flow( ... 'pyproject.toml', # filename we work with ... impure_safe(lambda filename: open(filename, 'r')), ... managed_read, # Assuming managed_read is defined as in the previous example ... bind_result(parse_toml), ... bind_result(get_project_name), ... ) >>> assert pipeline_result == IOSuccess('returns') ``` -------------------------------- ### Using KindN with a TypeVar bound to MappableN Source: https://github.com/dry-python/returns/blob/master/docs/pages/hkt.rst This example demonstrates a function that works with any subtype of `MappableN` by using a `TypeVar` bound to `MappableN`. It correctly maps a string representation over the container. ```python >>> from typing import TypeVar >>> from returns.primitives.hkt import KindN, kinded >>> from returns.interfaces.mappable import MappableN >>> _FirstType = TypeVar('_FirstType') >>> _SecondType = TypeVar('_SecondType') >>> _ThirdType = TypeVar('_ThirdType') >>> _MappableKind = TypeVar('_MappableKind', bound=MappableN) >>> @kinded ... def works_with_interface( ... container: KindN[_MappableKind, _FirstType, _SecondType, _ThirdType], ... ) -> KindN[_MappableKind, str, _SecondType, _ThirdType]: ... return container.map(str) >>> from returns.maybe import Maybe >>> from returns.io import IO >>> from returns.result import Success >>> assert works_with_interface(Maybe.from_value(1)) == Maybe.from_value('1') >>> assert works_with_interface(IO.from_value(1)) == IO.from_value('1') >>> assert works_with_interface(Success(1)) == Success('1') ``` -------------------------------- ### Using KindN with a specific type (Maybe) Source: https://github.com/dry-python/returns/blob/master/docs/pages/hkt.rst This example shows a function specifically designed to work with the `Maybe` container type using `KindN`. It maps a string representation over the `Maybe` instance. ```python >>> from returns.maybe import Maybe >>> @kinded ... def works_with_maybe( ... container: KindN[Maybe, _FirstType, _SecondType, _ThirdType], ... ) -> KindN[Maybe, str, _SecondType, _ThirdType]: ... return container.map(str) >>> assert works_with_maybe(Maybe.from_value(1)) == Maybe.from_value('1') ``` -------------------------------- ### Do Notation with Generator Expression Source: https://github.com/dry-python/returns/blob/master/docs/pages/do-notation.rst This example demonstrates the correct usage of do-notation with a generator expression. Ensure the expression is literal; variables or function calls are not permitted by mypy's plugin. ```python >>> from returns.result import Result, Success >>> expr = ( ... first + second ... for first in Success(2) ... for second in Success(3) ... ) >>> >>> assert Result.do(expr) == Success(5) ``` -------------------------------- ### Summing an iterable of IO containers with a different initial value Source: https://github.com/dry-python/returns/blob/master/docs/pages/container.rst Shows how to use `Fold.loop` to sum values from an iterable of IO containers, starting with a different initial value. This illustrates the flexibility of the `Fold.loop` method. ```python >>> assert Fold.loop( ... numbers, ... IO(5), # now we will start from ``5``, not ``0` ... sum_two_numbers, ... ) == IO(25) ``` -------------------------------- ### Run Future with anyio Source: https://github.com/dry-python/returns/blob/master/docs/pages/future.rst Demonstrates how to execute a Future instance using anyio.run and verifies the result is an IO container. ```python import anyio from returns.io import IO assert anyio.run(main().awaitable) == IO(2) ``` -------------------------------- ### Get Value or Default with .value_or() Source: https://github.com/dry-python/returns/blob/master/docs/pages/railway.rst The `.value_or()` method provides a safe way to get the contained value, returning a default if the container is a `Failure`. This is an alternative to directly unwrapping. ```python >>> from returns.result import Success, Failure >>> assert Success(1).value_or(None) == 1 >>> assert Failure(1).value_or(None) is None ``` -------------------------------- ### Enable mypy plugin in setup.cfg or mypy.ini Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/mypy_plugins.rst Add the returns mypy plugin to the 'plugins' section of your mypy configuration file. ```ini [mypy] plugins = returns.contrib.mypy.returns_plugin ``` -------------------------------- ### Enabling the mypy plugin Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/mypy_plugins.rst Add the returns mypy plugin to your mypy configuration file (setup.cfg, mypy.ini, or pyproject.toml). It is recommended to add it as the first plugin. ```ini [mypy] plugins = returns.contrib.mypy.returns_plugin ``` ```toml [tool.mypy] plugins = ["returns.contrib.mypy.returns_plugin"] ``` -------------------------------- ### Configure Returns Mypy Plugin Source: https://github.com/dry-python/returns/blob/master/README.md Configure the mypy plugin for Returns by adding it to your setup.cfg or mypy.ini file, or to your pyproject.toml. ```ini # In setup.cfg or mypy.ini: [mypy] plugins = returns.contrib.mypy.returns_plugin ``` ```toml [tool.mypy] plugins = ["returns.contrib.mypy.returns_plugin"] ``` -------------------------------- ### Creating Future Containers Source: https://github.com/dry-python/returns/blob/master/docs/pages/future.rst Demonstrates how to create instances of the Future container using various factory methods. ```APIDOC ## Creating Future Containers For ``Future`` container: - ``from_value``: Create a Future from a raw value. - ``from_io``: Create a Future from an existing ``IO`` container. - ``from_future_result``: Create a Future from an existing ``FutureResult`` container. ``` -------------------------------- ### Define a simple addition function Source: https://github.com/dry-python/returns/blob/master/docs/pages/do-notation.rst A basic function that takes two integers and returns their sum. This is used as an example for do-notation. ```python >>> def add(one: int, two: int) -> int: ... return one + two ``` -------------------------------- ### Typing with returns.curry.partial Source: https://github.com/dry-python/returns/blob/master/docs/pages/curry.rst Shows how returns.curry.partial improves type hinting for partial application, providing more specific type information. Requires the mypy plugin. ```python from returns.curry import partial def some_function(first: int, second: int) -> float: return first / second reveal_type(partial(some_function, 1)) # => def (second: builtins.int) -> builtins.float* # => Which is fair! ``` -------------------------------- ### Typing with types and instances using returns.curry.partial Source: https://github.com/dry-python/returns/blob/master/docs/pages/curry.rst Shows that returns.curry.partial works seamlessly with types and instances as callables, providing correct type hints. Requires the mypy plugin. ```python from returns.curry import partial class Test(object): def __init__(self, arg: int) -> None: self.arg = arg def __call__(self, other: int) -> int: return self.arg + other reveal_type(partial(Test, 1)) # N: Revealed type is 'def () -> ex.Test' reveal_type(partial(Test(1), 1)) # N: Revealed type is 'def () -> builtins.int' ``` -------------------------------- ### Creating IOResult Units in Python Source: https://github.com/dry-python/returns/blob/master/docs/pages/io.rst Shows how to instantiate success and failure cases for IOResult using helper functions like IOSuccess and IOFailure, or class methods like from_value and from_failure. Proper type annotation is recommended for mypy. ```python >>> from returns.io import IOResult, IOSuccess, IOFailure >>> first: IOResult[int, str] = IOSuccess(1) >>> second: IOResult[float, int] = IOFailure(1) >>> assert IOResult.from_value(1) == IOSuccess(1) >>> assert IOResult.from_failure(2) == IOFailure(2) ``` -------------------------------- ### Example of incorrect usage of @asyncify with blocking calls Source: https://github.com/dry-python/returns/blob/master/docs/pages/future.rst Illustrates a scenario where @asyncify is misused with a blocking network request, which does not result in asynchronous execution. ```python import requests from returns.future import asyncify @asyncify def please_do_not_do_that(): pass ``` -------------------------------- ### Typing with functools.partial Source: https://github.com/dry-python/returns/blob/master/docs/pages/curry.rst Demonstrates how functools.partial handles typing for a simple function. Requires the mypy plugin for accurate type inference. ```python from functools import partial def some_function(first: int, second: int) -> float: return first / second reveal_type(partial(some_function, 1)) # => functools.partial[builtins.float*] # => Which is really: `def (*Any, **Any) -> builtins.float` ``` -------------------------------- ### Create IO containers with integer values Source: https://github.com/dry-python/returns/blob/master/docs/pages/container.rst Demonstrates the creation of two IO containers, each holding an integer value. These containers are used to showcase composition with functions. ```python >>> from returns.io import IO >>> one = IO(1) >>> two = IO(2) ``` -------------------------------- ### MappableN Interface Type Hinting Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Demonstrates how to use MappableN with different numbers of type arguments for type hinting. Shortcuts like Mappable1, Mappable2, and Mappable3 reduce boilerplate. ```python >>> from typing_extensions import Never >>> from returns.interfaces.mappable import ( ... MappableN, Mappable1, Mappable2, Mappable3, ... ) >>> one_type: MappableN[int, Never, Never] >>> two_types: MappableN[int, str, Never] >>> three_types: MappableN[int, str, bool] >>> # We have a shortcut for each amount of arguments to reduce the boilerplate >>> one_type: Mappable1[int] >>> two_types: Mappable2[int, str] >>> three_type: Mappable3[int, str, bool] ``` -------------------------------- ### Define a Custom Bindable Container Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Demonstrates how to create a custom container that implements the Bindable1 interface. This involves defining the `bind` method. ```python >>> from typing import Callable, TypeVar >>> from returns.interfaces.bindable import Bindable1 >>> from returns.primitives.hkt import SupportsKind1, Kind1, dekind >>> from returns.primitives.container import BaseContainer >>> _NumberType = TypeVar('_NumberType') >>> _NewNumberType = TypeVar('_NewNumberType') >>> class Number( ... BaseContainer, ... SupportsKind1['Number', _NumberType], ... Bindable1[_NumberType], ... ): ... def __init__(self, inner_value: _NumberType) -> None: ... super().__init__(inner_value) ... ... def bind( # This method is required by Bindable ... self, ... function: Kind1[ ... 'Number', ... Callable[[_NumberType], 'Number[_NewNumberType]'], ... ], ... ) -> 'Number[_NewNumberType]': ... return dekind(function(self._inner_value)) ``` -------------------------------- ### Compose IO containers using do-notation Source: https://github.com/dry-python/returns/blob/master/docs/pages/do-notation.rst Demonstrates composing two IO containers with a two-argument function using the IO.do method. This simplifies handling nested containerized values. ```python >>> from returns.io import IO >>> assert IO.do( ... add(first, second) ... for first in IO(2) ... for second in IO(3) ... ) == IO(5) ``` -------------------------------- ### RequiresContextFutureResult Usage Example Source: https://github.com/dry-python/returns/blob/master/docs/pages/context.rst Demonstrates the usage of RequiresContextFutureResult for writing synchronous code that executes asynchronously and may fail. This container wraps impure async functions. ```python from typing import TypeVar from returns.context import RequiresContextFutureResult from returns.future import FutureResult def _first_task(value: int) -> FutureResult[int, str]: return FutureResult.from_value(value) def _second_task(value: int) -> FutureResult[int, str]: return FutureResult.from_value(value) def _third_task(value: int) -> FutureResult[int, str]: return FutureResult.from_value(value) _first_task_context = RequiresContextFutureResult.from_future_result( FutureResult.from_value(1), ) _second_task_context = RequiresContextFutureResult.from_future_result( FutureResult.from_value(2), ) _third_task_context = RequiresContextFutureResult.from_future_result( FutureResult.from_value(3), ) # This is how you can chain them: # First, we create a context that will run `_first_task` with `1` as input # Then, we chain it with `_second_task` and `_third_task` # All of them will be executed in a synchronous way, but under the hood # they will be executed asynchronously result = ( _first_task_context.bind_future_result(_first_task) .bind_future_result(_second_task) .bind_future_result(_third_task) ) # To get the result, you need to provide an environment # In this case, the environment is not used, so we can pass `None` # The result will be a FutureResult[int, str] # To run it, you need to call `.await_()` method # await result.await_() # This will return FutureResult[int, str] ``` -------------------------------- ### Alternative composition using .bind() Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Shows the alternative to pipeline composition when dealing with containers and functions that return containers, using the `.bind()` method. ```python returns_result().bind(works_with_result).bind(notifies_user) ``` -------------------------------- ### Creating a Custom Mappable Container Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Illustrates how to create a custom container class that implements the `Mappable1` interface. This involves inheriting from `BaseContainer` and `SupportsKind1`, and implementing the `map` method. ```python >>> from typing import Callable, TypeVar >>> from returns.interfaces.mappable import Mappable1 >>> from returns.primitives.hkt import SupportsKind1 >>> from returns.primitives.container import BaseContainer >>> _NumberType = TypeVar('_NumberType') >>> _NewNumberType = TypeVar('_NewNumberType') >>> class Number( ... BaseContainer, ... SupportsKind1['Number', _NumberType], ... Mappable1[_NumberType], ... ): ... def __init__(self, inner_value: _NumberType) -> None: ... super().__init__(inner_value) ... ... def map( # This method is required by Mappable ... self, ... function: Callable[[_NumberType], _NewNumberType] ... ) -> 'Number[_NewNumberType]': ... return Number(function(self._inner_value)) ``` -------------------------------- ### Using bind for pointfree container binding Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Shows how `pointfree.bind` lifts a function that returns a container to accept the same container type as input, facilitating declarative composition. ```python from returns import pointfree from returns.maybe import Maybe, Some def index_of_1(arg: str) -> Maybe[int]: if '1' in arg: return Some(arg.index('1')) return Nothing container = Some('A1 Steak Sauce') # We now have two way of composing these entities. # 1. Via ``.bind``: assert container.bind(index_of_1) == Some(1) # 2. Or via the ``bind`` function. assert pointfree.bind(index_of_1)(container) == Some(1) # This produces the same result, but in a different order ``` -------------------------------- ### Type-test for Pair.pair Source: https://github.com/dry-python/returns/blob/master/docs/pages/create-your-own-container.rst A type-test configuration file for mypy, verifying the correct typing of the Pair.pair function. It uses a warning to explain the necessity of the 'env:' property in this specific test setup. ```yaml test_pair4_def.yml: env: - ../../tests/test_examples/test_your_container/test_pair4.py "mypy": - -m - "test_pair4_def" "assert": - "output == " ``` -------------------------------- ### Apply a function to a Number instance Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Demonstrates how to apply a custom math function to a Number instance using `Number.from_value`. ```python >>> def my_math_function(number: int) -> int: ... return number - 1 >>> number = Number(3) >>> number_function = Number.from_value(my_math_function) >>> assert number.apply(number_function) == Number(2) ``` -------------------------------- ### Handle Async Exceptions with FutureResult Source: https://github.com/dry-python/returns/blob/master/README.md This example shows how to use the `@future_safe` decorator with an async function that raises an exception. The `FutureResult` container captures the exception, preventing it from crashing the event loop. ```python import anyio from returns.future import future_safe from returns.io import IOFailure @future_safe async def raising(): raise ValueError('Not so fast!') ioresult = anyio.run(raising.awaitable) # all `Future`s return IO containers assert ioresult == IOFailure(ValueError('Not so fast!')) # True ``` -------------------------------- ### Compose two IO containers using .apply() and partial Source: https://github.com/dry-python/returns/blob/master/docs/pages/container.rst Demonstrates an alternative way to compose two IO containers using .apply() and the `partial` function. This method achieves the same result as the @curry decorator but uses a different utility. ```python >>> from returns.curry import partial >>> one = IO(1) >>> two = IO(2) >>> assert two.apply(one.apply( ... IO(lambda x: partial(sum_two_numbers, x)), ... )) == IO(3) ``` -------------------------------- ### Using managed for resource management Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Demonstrates how to use the `managed` function to wrap resource acquisition and release operations. This is useful for ensuring resources like files are properly closed after use within a pipeline. ```python >>> from returns.pipeline import managed, is_successful >>> from returns.result import ResultE >>> from returns.io import IOResultE, impure_safe >>> def read_file(file_obj: TextIO) -> IOResultE[str]: ... return impure_safe(file_obj.read)() # this will be the final result >>> def close_file( ... file_obj: TextIO, ... file_contents: ResultE[str], ... ) -> IOResultE[None]: # sometimes might require to use `untap` ... return impure_safe(file_obj.close)() # this value will be dropped >>> managed_read = managed(read_file, close_file) >>> read_result = managed_read( ... impure_safe(lambda filename: open(filename, 'r'))('pyproject.toml'), ... ) >>> assert is_successful(read_result) # file content is inside `IOSuccess` ``` -------------------------------- ### Defining a pure function for seat booking Source: https://github.com/dry-python/returns/blob/master/docs/pages/io.rst This is an example of a pure function that checks seat availability based on provided arguments. Pure functions are easy to test as they do not rely on external state or produce side effects. ```python def can_book_seats( number_of_seats: int, reservation: 'Reservation', ) -> bool: return reservation.capacity >= number_of_seats + reservation.booked ``` -------------------------------- ### Flow with pointfree functions and containers Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Demonstrates composing regular functions and functions returning containers (like `Result`) using `flow`. Use `bind` to chain functions that operate on container types. ```python >>> from returns.result import Result, Success, Failure >>> from returns.pointfree import bind >>> from returns.pipeline import flow >>> def regular_function(arg: int) -> float: ... return float(arg) >>> def returns_container(arg: float) -> Result[str, ValueError]: ... if arg != 0: ... return Success(str(arg)) ... return Failure(ValueError('Wrong arg')) >>> def also_returns_container(arg: str) -> Result[str, ValueError]: ... return Success(arg + '!') >>> assert flow( ... 1, # initial value ... regular_function, # composes easily ... returns_container, # also composes easily, but returns a container ... # So we need to `bind` the next function to allow it to consume ... # the container from the previous step. ... bind(also_returns_container), ... ) == Success('1.0!') >>> # And this will fail: >>> assert flow( ... 0, # initial value ... regular_function, # composes easily ... returns_container, # also composes easily, but returns a container ... # So we need to `bind` the next function to allow it to consume ... # the container from the previous step. ... bind(also_returns_container), ... ).failure().args == ('Wrong arg', ) ``` -------------------------------- ### Using is_error_handled for error track testing Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/pytest_plugins.rst The is_error_handled function tests if containers correctly handle their error track. It returns False for unhandled errors and True when errors are handled, for example, by methods like lash. ```python >>> from returns.result import Failure, Success >>> from returns.contrib.pytest import ReturnsAsserts >>> def test_error_handled(returns: ReturnsAsserts): ... assert not returns.is_error_handled(Failure(1)) ... assert returns.is_error_handled( ... Failure(1).lash(lambda _: Success('default value')), ... ) ``` -------------------------------- ### Django View with Business Logic Source: https://github.com/dry-python/returns/blob/master/docs/pages/context.rst A basic Django view that calls a business logic function to calculate points based on user input. This example demonstrates a common pattern where business logic is separated from the web framework. ```python from django.http import HttpRequest, HttpResponse from words_app.logic import calculate_points def view(request: HttpRequest) -> HttpResponse: user_word: str = request.POST['word'] # just an example points = calculate_points(user_word) ... # later you show the result to user somehow ``` -------------------------------- ### Handling Impure and Failing Functions with IOResult Source: https://github.com/dry-python/returns/blob/master/README.md When a function is both impure and can fail (e.g., network requests), use the IOResult type. This example demonstrates fetching a user profile by combining impure request execution with safe JSON parsing. ```python import requests from returns.io import IOResult, impure_safe from returns.result import safe from returns.pipeline import flow from returns.pointfree import bind_result def fetch_user_profile(user_id: int) -> IOResult['UserProfile', Exception]: """Fetches `UserProfile` TypedDict from foreign API.""" return flow( user_id, _make_request, # before: def (Response) -> UserProfile # after safe: def (Response) -> ResultE[UserProfile] # after bind_result: def (IOResultE[Response]) -> IOResultE[UserProfile] bind_result(_parse_json), ) @impure_safe def _make_request(user_id: int) -> requests.Response: response = requests.get('/api/users/{0}'.format(user_id)) response.raise_for_status() return response @safe def _parse_json(response: requests.Response) -> 'UserProfile': return response.json() ``` -------------------------------- ### Pipe with containers Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Shows how to compose functions, including those returning containers, using `pipe`. Use `bind` to chain functions that operate on container types. ```python >>> from returns.pipeline import pipe >>> from returns.result import Result, Success, Failure >>> from returns.pointfree import bind >>> def regular_function(arg: int) -> float: ... return float(arg) >>> def returns_container(arg: float) -> Result[str, ValueError]: ... if arg != 0: ... return Success(str(arg)) ... return Failure(ValueError('Wrong arg')) >>> def also_returns_container(arg: str) -> Result[str, ValueError]: ... return Success(arg + '!') >>> transaction = pipe( ... regular_function, # composes easily ... returns_container, # also composes easily, but returns a container ... # So we need to `bind` the next function to allow it to consume ... # the container from the previous step. ... bind(also_returns_container), ... ) >>> result = transaction(1) # running the pipeline >>> assert result == Success('1.0!') ``` -------------------------------- ### Define Sync Permissions with RequiresContext Source: https://github.com/dry-python/returns/blob/master/docs/pages/context.rst Defines a function `sync_permissions` that uses ReaderIOResultE to manage dependencies for fetching metadata, getting user permissions, and updating BI permissions. This pattern is useful for pure functional code that needs explicit context. ```python from typing import Callable, Dict, Protocol, final from returns.io import IOResultE from returns.context import ReaderIOResultE class _SyncPermissionsDeps(Protocol): fetch_metadata: Callable[[], IOResultE['Metadata']] get_user_permissions: Callable[['Metadata'], Dict[int, str]] # pure update_bi_permissions: Callable[[Dict[int, str]], IOResultE['Payload']] def sync_permissions() -> ReaderIOResultE[_SyncPermissionsDeps, 'Payload']: """ This functions runs a scheduled task once a day. It syncs permissions from the metadata storage to our BI system. """ def factory(deps: _SyncPermissionsDeps) -> IOResultE['Payload']: return deps.fetch_metadata().map( deps.get_user_permissions, ).bind_ioresult( deps.update_bi_permissions, ) return ReaderIOResult(factory) ``` -------------------------------- ### Typing with @overload using returns.curry.partial Source: https://github.com/dry-python/returns/blob/master/docs/pages/curry.rst Illustrates how returns.curry.partial supports @overload definitions, correctly inferring types from multiple function signatures. Requires the mypy plugin. ```python from typing import overload from returns.curry import partial @overload def test(a: int, b: str) -> str: ... @overload def test(a: int) -> int: ... @overload def test(a: str) -> None: # won't match! ... def test(a, b=None): ... reveal_type(partial(test, 1)) # N: Revealed type is 'Overload(def (b: builtins.str) -> builtins.str, def () -> builtins.int)' ``` -------------------------------- ### Chaining Asynchronous Operations with bind Source: https://github.com/dry-python/returns/blob/master/README.md This snippet demonstrates chaining multiple asynchronous operations using `bind` from `returns.pointfree` and `flow` for a clean, point-free style. It requires importing `bind` and `flow`. ```python from returns.pointfree import bind from returns.pipeline import flow def main(user_id: int) -> FutureResultE[bool]: return flow( fetch_user(user_id), bind(get_user_permissions), bind(ensure_allowed), ) ``` -------------------------------- ### Pipe with multiple values Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Demonstrates that a pipeline created with `pipe` can be applied to multiple values sequentially. ```python >>> assert pipeline(2) == '2B' ``` -------------------------------- ### Instantiate a Result container from a value Source: https://github.com/dry-python/returns/blob/master/docs/pages/container.rst Use the `.from_value` static method to create a container instance from a raw value. For `Result`, this will always create a `Success` container. ```python >>> from returns.result import Result >>> assert str(Result.from_value(1)) == '' ``` -------------------------------- ### Run Linting Source: https://github.com/dry-python/returns/blob/master/CONTRIBUTING.md Perform code linting using flake8 to enforce code style. The default virtual environment folder is excluded from checking. ```bash poetry run flake8 . ``` -------------------------------- ### Execute Future with an Event Loop Source: https://github.com/dry-python/returns/blob/master/README.md Demonstrates how to execute a Future container within an event loop using a library like anyio. The Future must be awaited within a proper event loop to yield its result. ```python import anyio # or asyncio, or any other lib # We can then pass our `Future` to any library: asyncio, trio, curio. # And use any event loop: regular, uvloop, even a custom one, etc assert anyio.run(second().awaitable) == 2 ``` -------------------------------- ### bind_context3 Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Pointfree version of `bind` for containers with three environments. ```APIDOC ## bind_context3 ### Description Pointfree version of `bind` for containers with three environments. ### Method `bind_context3(function)` ### Parameters - **function** (callable) - The function to bind. It should return a container with three environments. ``` -------------------------------- ### Use Custom Bindable Container Source: https://github.com/dry-python/returns/blob/master/docs/pages/interfaces.rst Shows how to use a custom container that implements the Bindable interface. It applies a function to the inner value using the `bind` method. ```python >>> def double(arg: int) -> Number[int]: ... return Number(arg * 2) >>> number = Number(5) >>> assert number.bind(double) == Number(10) ``` -------------------------------- ### bind_context_ioresult Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Pointfree version of `bind` for containers with an environment and an IOResult. ```APIDOC ## bind_context_ioresult ### Description Pointfree version of `bind` for containers with an environment and an IOResult. ### Method `bind_context_ioresult(function)` ### Parameters - **function** (callable) - The function to bind. It should return a container with an environment and an IOResult. ``` -------------------------------- ### Compose two IO containers using .apply() and @curry Source: https://github.com/dry-python/returns/blob/master/docs/pages/container.rst Shows how to compose two IO containers with a curried function using the .apply() method. This approach allows passing arguments sequentially to a function wrapped in containers. ```python >>> from returns.curry import curry >>> from returns.io import IO >>> @curry ... def sum_two_numbers(first: int, second: int) -> int: ... return first + second >>> one = IO(1) >>> two = IO(2) >>> assert two.apply(one.apply(IO(sum_two_numbers))) == IO(3) ``` -------------------------------- ### Using managed for resource management in pipelines Source: https://github.com/dry-python/returns/blob/master/docs/pages/pipeline.rst Demonstrates how to use the `managed` function to handle resource acquisition and release within a pipeline, ensuring resources like files are properly closed. ```APIDOC ## managed ### Description The `managed` function creates a pipeline-ready operation that handles resource management. It takes two functions: one for acquiring the resource and another for releasing it. ### Usage ```python from returns.pipeline import managed from returns.io import IOResultE, impure_safe def read_file(file_obj) -> IOResultE[str]: # ... implementation ... pass def close_file(file_obj, file_contents) -> IOResultE[None]: # ... implementation ... pass managed_read = managed(read_file, close_file) # Example usage within a pipeline or directly: # result = managed_read(resource_acquisition_step) ``` ### Supported Types `managed` can be used with: - `IOResult` - `FutureResult` - `RequiresContextIOResult` - `RequiresContextFutureResult` ``` -------------------------------- ### Register Custom Container Strategy Using __init__ Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/hypothesis_plugins.rst Register a Hypothesis strategy for a custom container class, using its __init__ method for instantiation. This is an alternative to the default instantiation method. ```python st.register_type_strategy( YourContainerClass, strategy_from_container(YourContainerClass, use_init=True), ) ``` -------------------------------- ### Composing Functions with RequiresContext Source: https://github.com/dry-python/returns/blob/master/docs/pages/context.rst Demonstrates how to wrap a pure function with RequiresContext to enable composition and dependency injection, then map another function over its result. ```python from returns.context import RequiresContext def first(limit: int) -> RequiresContext[bool, str]: def inner(deps: str) -> bool: return len(deps) > limit return RequiresContext(inner) # wrapping function here! ``` ```python def bool_to_str(arg: bool) -> str: return 'ok' if arg else 'nope' ``` ```python assert first(1).map(bool_to_str)('abc') == 'ok' assert first(5).map(bool_to_str)('abc') == 'nope' ``` -------------------------------- ### Generics typing with returns.curry.partial Source: https://github.com/dry-python/returns/blob/master/docs/pages/curry.rst Demonstrates how returns.curry.partial correctly handles generic types, providing accurate type inference. Requires the mypy plugin. ```python from returns.curry import partial reveal_type(partial(some_function, x)) # => def (second: builtins.int) -> builtins.int* ``` -------------------------------- ### Register Returns Containers as Hypothesis Strategies Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/hypothesis_plugins.rst Automatically registers 'returns' containers like Result and Maybe as hypothesis strategies. This allows hypothesis to generate values for these types in property tests without manual configuration. ```python from returns.result import Result from hypothesis import strategies as st assert st.from_type(Result).example() ``` -------------------------------- ### Demonstrate SyntaxError for await in sync function Source: https://github.com/dry-python/returns/blob/master/docs/pages/future.rst Illustrates the SyntaxError that occurs when attempting to use 'await' outside of an async function. ```python def test(): await some() # SyntaxError: 'await' outside async function ``` -------------------------------- ### Comparing RequiresContext with traditional decorators Source: https://github.com/dry-python/returns/blob/master/docs/pages/context.rst Illustrates the difference between using `RequiresContext` and a traditional decorator with arguments, highlighting `RequiresContext`'s flexibility in changing behavior. ```python assert my_function(2, 3)(False) == 5 assert my_function(2, 3)(True) == 5 ``` -------------------------------- ### Enable __init__ for Container Law Checking Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/hypothesis_plugins.rst Enables the use of the container's `__init__` method for generating instances during law checking. This is useful for custom containers that do not provide `from_value` or `from_optional` methods. Requires `use_init=True`. ```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) ``` -------------------------------- ### bind_context2 Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Pointfree version of `bind` for containers with two environments. ```APIDOC ## bind_context2 ### Description Pointfree version of `bind` for containers with two environments. ### Method `bind_context2(function)` ### Parameters - **function** (callable) - The function to bind. It should return a container with two environments. ``` -------------------------------- ### bind_context Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Pointfree version of `bind` for containers with one environment. ```APIDOC ## bind_context ### Description Pointfree version of `bind` for containers with one environment. ### Method `bind_context(function)` ### Parameters - **function** (callable) - The function to bind. It should return a container with one environment. ``` -------------------------------- ### Using assert_trace to check container creation Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/pytest_plugins.rst The assert_trace context manager helps verify that a container is created correctly at a specific point in your flow, checking for the desired function and container type. ```python >>> from returns.result import Result, Success, Failure >>> from returns.contrib.pytest import ReturnsAsserts >>> def desired_function(arg: str) -> Result[int, str]: ... if arg.isnumeric(): ... return Success(int(arg)) ... return Failure('"{0}" is not a number'.format(arg)) >>> def test_if_failure_is_created_at_convert_function( ... returns: ReturnsAsserts, ... ): ... with returns.assert_trace(Failure, desired_function): ... Success('not a number').bind(desired_function) ``` ```python >>> def test_if_success_is_created_at_convert_function( ... returns: ReturnsAsserts, ... ): ... with returns.assert_trace(Success, desired_function): ... Success('42').bind(desired_function) ``` -------------------------------- ### Making IO Lazy in Python Source: https://github.com/dry-python/returns/blob/master/docs/pages/io.rst Demonstrates how to create a lazy IO computation by defining a lambda function that returns an IO instance. This approach simulates laziness for IO operations. ```python >>> from returns.io import IO >>> lazy = lambda: IO(1) >>> assert lazy() == IO(1) ``` -------------------------------- ### Composing functions with containers using pipe Source: https://github.com/dry-python/returns/blob/master/docs/pages/pointfree.rst Demonstrates the challenge of composing functions that expect regular values with containers using the `pipe` function. Without pointfree functions, direct composition fails. ```python from returns.pipeline import pipe from returns.result import ResultE def returns_result(arg: int) -> ResultE[int]: ... def works_with_result(arg: int) -> ResultE[int]: ... def finish_work(arg: int) -> ResultE[int]: ... pipe( returns_result, works_with_result, # does not compose! Needs a container for input finish_work, # does not compose either! ) ``` -------------------------------- ### Enable mypy plugin in pyproject.toml Source: https://github.com/dry-python/returns/blob/master/docs/pages/contrib/mypy_plugins.rst Configure the returns mypy plugin in the 'tool.mypy' section of your pyproject.toml file. ```toml [tool.mypy] plugins = ["returns.contrib.mypy.returns_plugin"] ``` -------------------------------- ### Create Maybe from Value (Handles None) Source: https://github.com/dry-python/returns/blob/master/docs/pages/maybe.rst Use `Maybe.from_value` to create a `Some` container, even if the value is None. This differs from `from_optional` as it wraps None in a `Some`. ```python >>> from returns.maybe import Maybe >>> assert str(Maybe.from_value(1)) == '' >>> assert str(Maybe.from_value(None)) == '' ```