NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #4099 most downloaded on PyPI
Make your functions return something meaningful, typed, and safe!
Last release 2 months ago
02 Aug 2026
Release timing varies
gaps range from 2 months to 1.1 years
Nearly every release is documented
notes for 30 of 30 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
30 releases · first in 2019
Fixes partial mypy plugin inferring the wrong signature when a positional argument is applied by keyword: the remaining parameters are now correctly m
mypy>=1.19,<2.4 supportpartial mypy plugin inferring the wrong signature when a positionalTypeErrorFull Changelog: 0.28.0...0.29.0
mypy>=1.19,<2.4 supportpartial mypy plugin inferring the wrong signature when a positional
argument is applied by keyword: the remaining parameters are now correctly
marked as keyword-only, so passing them positionally is a type error instead
of a runtime TypeErrorFull Changelog: https://github.com/dry-python/returns/compare/0.28.0...0.29.0
One column per quarter.
What's Changed Features Add mypy>=1.19,<1.22 support Full Changelog : 0.27.0...0.28.0
mypy>=1.19,<1.22 supportFull Changelog: https://github.com/dry-python/returns/compare/0.27.0...0.28.0
@Smoothengineer made their first contribution in #2267
python3.10 supportpython3.14 supportmypy>=1.19,<1.21 supportFull Changelog: 0.26.0...0.27.0
python3.10 supportpython3.14 supportmypy>=1.19,<1.21 supportFull Changelog: https://github.com/dry-python/returns/compare/0.26.0...0.27.0
Added __bool__ to Maybe , only Nothing ever returns False
mypy>=1.16,<1.18 support__bool__ to Maybe, only Nothing ever returns FalseFull Changelog: 0.25.0...0.26.0
mypy>=1.16,<1.18 support__bool__ to Maybe, only Nothing ever returns FalseA lot of new features added to our hypothesis plugins. It now allows to create custom strategies, better instantiate containers, docouple it from buil
hypothesis plugins.UnwrapFailedError was not picklableAdd picky exceptions to future_safe decorator like safe has
python3.9 supportpython3.13 supportmypy>=1.12future_safe decorator like safe hasResultLike objects when exception catchingimpure_safe decorator like safe has. Issue #1543default_error parameter to returns.converters.maybe_to_result,FailureBreaking : Remove success_type and failure_type fields from IOResult , Maybe and Result types
success_type and failure_type fields from IOResult,Maybe and Result typesmypy>=1.10[check-laws] extra for installationBreaking : Drops python3.7 support
python3.7 supportmypy>=1.5trampolines supportpython3.7 supportmypy>=1.5trampolines supportAdds [compatible-mypy] extra for installation
mypy>=1.4[compatible-mypy] extra for installationmypy>=1.4[compatible-mypy] extra for installationFixed HKT to_str example in documentation
to_str example in documentationFixes a problem with do-notation and type aliases
mypy>=1.2do-notation and type aliasesNone values gracefullyCheck __slots__ correctness with slotscheck
do notationattempt decorator__slots__ correctness with slotscheckNow requires typing_extensions>=4.0
New Year Release! 🎄
typing_extensions>=4.0mypy>=0.930@safe, @maybe, @future, etc.
Because we now use ParamSpec type to properly type decorators__slots__ not being set properly in containers and their base classesEnables Pattern Matching support for Result containers
Result containersMaybe containerIOResult containerhypothesis plugin, now we detect
when type cannot be constructed and give a clear error messageResult containersMaybe containerIOResult containerhypothesis plugin, now we detect
when type cannot be constructed and give a clear error message@safe will handleRefactor flow function to be faster
_Nothing a singletonflow function to be fasterassert_trace was not catching containers
from @safe-wrapped functionsAdds Higher Kinded Types partial support
Adds Higher Kinded Types partial support
Breaking: drops python3.6 support
Breaking: makes our mypy plugin not optional, but required!
Breaking: changes all RequiresContext-based type arguments order,
previously we used to specify _EnvType as the first type argument,
now it is the last one. This is done to respect new HKT rules
Breaking: renames .rescue to .lash
Breaking: removes all old interfaces from primitives/interfaces.py,
use new typeclasses instead
Breaking: Maybe is fully reworked to be lawful
Breaking: removes value_or pointfree method,
because it is impossible to express with HKT
Breaking: removes .value_or, .unwrap, and .failure methods
from FutureResult and RequiresContext-based types,
because we do require these methods to raise an exception on failure,
but these methods were lazy and did not raise the required exception
Breaking: changes how is_successful is typed:
now we allow any Unwrappable interface instances there,
including custom ones
Breaking: changes UnwrapFailedError constructor,
now it does accept an Unwrappable instance instead of a BaseContainer
Breaking: removes .fix method from all containers,
also removes fix pointfree function
Breaking: Removes coalesce function,
because it is impossible to properly type it
Breaking: Removes all Context* based types with .ask() method,
use new .ask() methods on the Reader-based containers
Breaking: Now Future and FutureResult can be awaited multiple times
Breaking: Removes .unify() method from several containers,
use unify() pointfree function instead
Breaking: Removes .from_iterable method from all containers,
instead adds better iterables support,
we now have returns.iterables module with Fold helper
Breaking: Renames property empty to no_args of
all RequiresContext-based classes
Adds new public interfaces: see returns.interfaces
Adds methods package with several helpful things inside
Adds FutureSuccess and FutureFailure unit functions
to be similar to Result and IOResult
Adds .swap method to Result, IOResult, FutureResult,
and other result based containers
Adds .modify_env method to all RequiresContext* types
Adds .rescue to Maybe
Adds .equals methods to types that can be compared directly:
Result, Maybe, IO, IOResult
Adds missing from_requires_context_future_result to RequiresContext
Adds .from_optional and .bind_optional to Maybe container
Adds __slots__ to UnwrapFailedError with halted_container
Changes flatten to work with KindN and any possible container
Adds a helper to test traces to our pytest plugin
Adds cond function to pointfree and methods packages
Adds compose_result HKT method and pointfree function
Adds unify HKT pointfree function
Adds bimap pointfree function
Adds unwrap_or_failure function to methods package
Adds collect_trace helper function for better development experience
Adds hypothesis intergration and pre-defined "monad laws as values"
Adds assert_equal method to our pytest plugin
flow workspipe works,
now it has a hard limit of 20 parametersRequiresContextFutureResult was not supported by pytest pluginpartial behaviour in an edge case, #618.apply method of IOResult was working incorrectly,
it was returning IOFailure(2)
as a result of IOFailure(1).apply(IOFailure(2))safe(tap(...)) was revealing invalid types sometimesInterfaces, HKT, and Methods pages__str__ method in BaseContainer class to __repr__ methodQuickstart guideand other (code and ideas) contributors for making this release possible. You are awesome!
Special thanks to:
Announcement: https://sobolevn.me/2020/06/how-async-should-have-been
Breaking: renames mypy plugin from decorator_plugin to returns_plugin
because of a complete rewrite and lots of new features
Breaking: changes @safe, @impure, impure_safe, @maybe semantics:
they do not work with async functions anymore;
now you are forced to use Future and its helpers
to work with async functions
Breaking: renames Maybe.new to Maybe.from_value.
Because all our other containers support this protocol.
Only Maybe was different, sorry for that!
Breaking: renames .from_success() to .from_value(),
there's no need in two separate methods
Breaking: renames .from_successful_io() to .from_io(),
there's no need in two separate methods
Breaking: renames .from_successful_context() to .from_context(),
there's no need in two separate methods
Breaking: since we now support .apply() method,
there's no more need in *_squash converters, they are removed
Breaking: renamed Instanceable to Applicative
Breaking: changes .from_io and .from_failed_io of IOResult
to return Any instead of NoReturn unfilled type
Breaking: removes .lift and .lift_* methods from all containers,
use map_, bind_result, bind_io, and other pointfree helpers instead
Breaking: removes @pipeline function. It was a mistake:
it does not work with mixed container types,
it does not type failures properly,
it does not work with IO and Future,
it enforces to write imperative code in a functional codebase.
Use flow instead
Adds typed partial and curry mypy plugins!
Adds typed flow plugin, now it can accept any number of arguments,
it now also has excelent type inference
Adds typed pipe plugin, now it can accept any number of arguments,
it now also has good type inference
Adds managed pipeline function that is useful
for working with stateful computations
Adds typed map_, fix, and alt pointfree functions
Adds typed bind_result, bind_io, bind_ioresult,
bind_context, bind_context_result, bind_future,
bind_async, and bind_awaitable pointfree functions
Adds typed bind_async_future and bind_async_future_result
pointfree functions
Adds typed unify pointfree function
Adds typed apply pointfree function
Adds typed value_or pointfree function
Adds pytest plugin with the ability to tests error handling
Adds Future container to easily work with async functions
Adds FutureResult container to easily work
with async function that might fail
Adds RequiresContextFutureResult container
Adds ReaderFutureResult alias for RequiresContextFutureResult
Adds RequiresContextFutureResultE and ReaderFutureResultE aliases
Adds Future, FutureResult and RequiresContextFutureResult
support for all existing pointfree functions
Adds bind_io method to IOResult
Adds bind_io method to RequiresContextIOResult
Adds or_else method to Maybe
Adds .from_io and .from_failed_io to RequiresContextIOResult
Syncs naming in from_* methods, now all parameters are named inner_value
Adds not_ composition helper
Adds flatten support for Future,
FutureResult and RequiresContextFutureResult
Adds __copy__ and __deepcopy__ magic methods to Immutable class
Speeds up is_successful function
Makes all Context context helpers abstract,
so you cannot create new instances of this class,
also adds __slots__ to these classes
Improves RequiresContext* types with NoDeps where it is logically true
@safe decorator was generating incorrect signatures
for functions with Any.rescue() of RequiresContextResult was returning Any.rescue() of RequiresContextIOResult was returning AnyRequiresContextResult and RequiresContextIOResult
were not finalImmutableStateError was not a subclass of AttributeErrorIOResult was not showing str representation
of wrapped inner_valuepytest-asyncio with anyio plugin,
now we test compatibility with any IO stack: asyncio, trio, curioAnnouncing article: https://sobolevn.me/2020/02/typed-functional-dependency-injection
Announcing article: https://sobolevn.me/2020/02/typed-functional-dependency-injection
Breaking: renames join to flatten, sorry!
Breaking: renames box to bind and moves it to returns.pointfree
Breaking: removes Maybe.rescue and Maybe.fix methods
Breaking: renames io_squash to squash_io
and moves it to returns.converters
Breaking: moves all interfaces from returns.primitives.container to
returns.primitives.interfaces
Adds rescue pointfree function
Adds ResultE alias for Result[..., Exception]
Adds RequiresContext container and Context helper class
Adds RequiresContext support for bind pointfree function
Adds RequiresContext support for flatten function
Adds RequiresContextResult container
Adds RequiresContextResultE alias
Adds ReaderResult and ReaderResultE aliases
for RequiresContextResult[..., ..., Exception]
Adds RequiresContextResult support for bind and rescue
Adds RequiresContextResult support for flatten
Adds IOResult helper to work better with IO[Result[a, b]]
Adds IOResultE alias for IOResult[a, Exception]
Adds IOResult support for bind
Adds IOResult support for flatten
Adds IOResult support for @pipeline
Adds IOResult support for coalesce
Adds IOResult support for is_successful
Adds RequiresContextIOResult container
Adds RequiresContextIOResultE alias
Adds ReaderIOResult and ReaderIOResultE aliases
for RequiresContextIOResult[..., ..., Exception]
Adds RequiresContextIOResult support for bind and rescue
Adds RequiresContextIOResult support for flatten
Adds Result.lift, Maybe.lift, RequiresContext.lift,
and RequiresContextResult.lift functions in addition to IO.lift
Adds Immutable primitive type
Adds Unitable protocol and .from_success() and .from_failure()
methods for all Result realted classes
Adds Instanceable protocol and .from_value() method
for IO and RequiresContext
Adds flow function, which is similar to pipe
Adds swap coverter for Result and IOResult
Adds squash_context function to squash RequiresContext similar to IO
Success and Failure (both io and pure) return Any and not NoReturnflatten works, also adds more tests and docs about Failure caseUnwrappable type being parametrized with only one TypeVarSuccess and Failure to return Any instead of NoReturnpoetry version in travispipe docs with lambda and Generic problemmypy in CIBreaking: now @pipeline requires a container type when created: @pipeline(Result) or @pipeline(Maybe)
@pipeline requires a container type when created:
@pipeline(Result) or @pipeline(Maybe)Maybe and Result now has success_type and failure_type aliasesResult.unify utility method for better error type compositiondry-python/classes as a first-class citizenio_squash to squash several IO containers into one container
with a tuple inside, currently works with 9 containers max at a timeuntap function which does convert return type to NonemultiprocessingBaseContainer is the first childNothing had incorrect docstringsgenerated package is protectedpoetry to 1.0Breaking: now pipe() does not require argument to be the first value, instead it is required to use: pipe(f1, f2, f3, f4)(value)
pipe() does not require argument to be the first value,
instead it is required to use: pipe(f1, f2, f3, f4)(value)returns/__init__.py,
because we now have quite a lot of stuffNothing.fixNothing.rescueMaybe now has .failure() to match the same API as Resultidentity functiontap functionpipe allows to pipe 8 stepscoalesce_result and coalesce_maybe coverters.fix and .rescue of Maybe might be called twiceSuccess and _Success, Failure and _Failure@pipelinetypesafety/ testsBreaking: python>=3.7,<=3.7.2 are not supported anymore, because of a bug inside typing module
python>=3.7,<=3.7.2 are not supported anymore,
because of a bug inside typing modulebind does not change the type of an errorrescue does not change the type of a valuemap_failure to altbox() function with the ability
to box function for direct container composition like:
a -> Container[b] to Container[a] -> Container[b]IO.lift() function to lift a -> a to IO[a] -> IO[a]pipe() function to pipeline.py__hash__() magic methods to all containersAny to NoReturn in Success and FailureResult, Maybe, and IO are covariantmypy versionwemake-python-styleguide and introduces nitpickpytest-plugin-mypy, all tests now use ymlProvides a bunch of primitive interfaces to write your own containers
.map_failure() methodjoin() function to join nested containersMaybe.fix and Maybe.rescue to work with both lambda: 1 and lambda _: 1READMEReintroduces the Maybe monad, typed!
Maybe monad, typed!mypy plugin to type decoratorsResult typesSuccess and Failure are not types, but functionsFixableContainer and ValueUnwrapContainerIO container from Result.bind@pipeline return type.py filesIO and Container conceptAlpha to BetaAdds unsafe module with unsafe functions
IO markerunsafe module with unsafe functions@pipelineis_successful is publicraise_exception is publicstr() function works for container typessafe and pipeline now supports asyncio
safe and pipeline now supports asynciois_successful now returns Literal types if possibleAdds public API to import returns
compose helper functionimport returnsraise_exception helper function.unwrap()mypyBSDRenames all classes according to new naming pattern
.pyi filesfmap to mapdo_notation to pipeline, moves it to functions.pyebind to rescueefmap to fixMonad to ContainerMaybe monad, since typing does not have NonNullable type.pyi filesfmap to mapdo_notation to pipeline, moves it to functions.pyebind to rescueefmap to fixcontainer to ContainerMaybe container, since typing does not have NonNullable typeAdds py.typed file to be PEP561 compatible
py.typed file to be PEP561 compatibleThe project is renamed to returns and moved to dry-python org.
The project is renamed to returns and moved to dry-python org.
.pyi files for all modules,
to enable mypy support for 3rd party usersAdds immutability and __slots__ to all monads
Maybe monad__slots__ to all monadssafe decorator to convert exceptions to Either monadis_successful() function to detect if your result is a successfailure() method to unwrap values from failed monads.bind method for Success monadFailure(1) != Success(1)Maybe container__slots__ to all containerssafe decorator to convert exceptions to Result containeris_successful() function to detect if your result is a successfailure() method to unwrap values from failed containers.bind method for Success containerFailure(1) != Success(1)Your coding agent can read these notes before it upgrades. Set up the MCP server →