{"id":4744,"library":"returns","title":"Returns: Meaningful, Typed, and Safe Function Returns","description":"The `returns` library (version 0.26.0) is a functional programming toolkit for Python, enhancing type-safety and explicit error handling. It allows developers to make functions return meaningful, typed, and safe values like `Result`, `Maybe`, and `IO` monads, promoting composable and testable code. The project is actively maintained with frequent releases, often every few months, introducing new features and compatibility updates.","status":"active","version":"0.26.0","language":"python","source_language":"en","source_url":"https://github.com/dry-python/returns","tags":["functional programming","type-safety","error-handling","monads","fp","mypy"],"install":[{"cmd":"pip install returns","lang":"bash","label":"Install core library"},{"cmd":"pip install returns[compatible-mypy]","lang":"bash","label":"Install with compatible MyPy version"}],"dependencies":[{"reason":"Core language runtime requirement.","package":"python","version":">=3.10, <4.0"},{"reason":"Crucial for type-checking and leveraging `returns`' full benefits; specific versions are often required.","package":"mypy","version":">=1.16, <1.18","optional":true}],"imports":[{"symbol":"Result, Success, Failure","correct":"from returns.result import Result, Success, Failure"},{"symbol":"Maybe, Some, Nothing","correct":"from returns.maybe import Maybe, Some, Nothing"},{"symbol":"IO, IOResult","correct":"from returns.io import IO, IOResult"},{"symbol":"do","correct":"from returns.do_notation import do"},{"symbol":"safe","correct":"from returns.result import safe"},{"symbol":"maybe","correct":"from returns.maybe import maybe"}],"quickstart":{"code":"from returns.result import Result, Success, Failure\nfrom returns.do_notation import do\n\ndef divide(numerator: int, denominator: int) -> Result[float, str]:\n    if denominator == 0:\n        return Failure('Cannot divide by zero')\n    return Success(numerator / denominator)\n\ndef multiply(value: float, multiplier: int) -> Result[float, str]:\n    if multiplier < 0:\n        return Failure('Multiplier cannot be negative')\n    return Success(value * multiplier)\n\n@do(Result)\ndef calculate_compound(num: int, den: int, mult: int) -> Result[float, str]:\n    divided_val = yield divide(num, den)\n    final_val = yield multiply(divided_val, mult)\n    return final_val\n\n# Example usage:\nassert calculate_compound(10, 2, 5) == Success(25.0)\nassert calculate_compound(10, 0, 5) == Failure('Cannot divide by zero')\nassert calculate_compound(10, 2, -1) == Failure('Multiplier cannot be negative')\n\nprint(calculate_compound(10, 2, 5))\n","lang":"python","description":"This quickstart demonstrates the `do` notation for composing operations with `Result` types. Functions `divide` and `multiply` return `Result` objects, encapsulating either a `Success` value or a `Failure` message. The `calculate_compound` function uses `yield` within the `@do(Result)` decorator to sequentially process these results, automatically propagating any `Failure`."},"warnings":[{"fix":"Ensure your Python environment is at version `3.10` or higher to use recent `returns` releases.","message":"`returns` has specific Python version requirements that have changed over time. Python 3.7 support was dropped in `0.22.0`, and Python 3.9 support was dropped in `0.24.0`. Current versions require Python `>=3.10`.","severity":"breaking","affected_versions":">=0.22.0"},{"fix":"Refactor code to not rely on these specific type attributes. Type hints should now be inferred correctly without needing to inspect these fields directly.","message":"The `success_type` and `failure_type` fields were removed from `IOResult`, `Maybe`, and `Result` types. Code that directly accessed these attributes will break.","severity":"breaking","affected_versions":">=0.23.0"},{"fix":"Be explicit when checking `Maybe` values. Use `is_some()`, `is_nothing()`, or `match` statements instead of direct boolean evaluation to avoid unintended behavior, especially when dealing with `Some(False)` or `Some(0)`.","message":"The `Maybe` type now implements a `__bool__` method where only `Nothing` evaluates to `False`. `Some` values, regardless of their content, evaluate to `True`.","severity":"gotcha","affected_versions":">=0.26.0"},{"fix":"Always check the `returns` changelog or documentation for the currently supported `mypy` version range. Install `returns` with the `[compatible-mypy]` extra, e.g., `pip install returns[compatible-mypy]` to ensure `mypy` is installed correctly.","message":"`returns` is highly reliant on specific `mypy` versions for correct type inference and to prevent `mypy` errors. The compatible `mypy` version often changes with `returns` releases.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always handle the error case before unwrapping. Use methods like `.alt()`, `.bind_failure()`, `.lash()`, `.fix()`, `.map_failure()`, or `match` statements to safely process both `Success`/`Some` and `Failure`/`Nothing` paths.","message":"Attempting to unwrap a `Failure` or `Nothing` value (e.g., using `.unwrap()`, `.value_or()`, or accessing `.value` directly on `Failure`) without handling the error path will raise an `UnwrapFailedError`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'0.26.0':12 'activ':54 'allow':29 'code':50 'compat':67 'compos':47 'develop':30 'enhanc':20 'error':26,75 'error-handl':74 'everi':60 'explicit':25 'featur':65 'fp':78 'frequent':57 'function':6,15,33,69 'handl':27,76 'introduc':63 'io':44 'librari':10 'like':40 'maintain':55 'make':32 'mayb':42 'meaning':2,35 'monad':45,77 'month':62 'mypi':79 'new':64 'often':59 'program':16,70 'project':52 'promot':46 'python':19 'releas':58 'result':41 'return':1,7,9,34 'safe':5,38 'safeti':23,73 'testabl':49 'toolkit':17 'type':3,22,36,72 'type-safeti':21,71 'updat':68 'valu':39 'version':11","created_at":"2026-04-12T14:05:45.311773+00:00","updated_at":"2026-04-16T21:00:45.309567+00:00","problems":[{"fix":"Install the library using pip: `pip install returns`","cause":"The 'returns' library is not installed in the current Python environment or the environment is not correctly activated.","error":"ModuleNotFoundError: No module named 'returns'"},{"fix":"Use methods like `.map()`, `.bind()`, `.unwrap()`, `.alt()`, or pattern matching to correctly operate on or extract the value from within the monad.\n```python\nfrom returns.result import Result, Success\n\ndef add_five(value: Result[int, str]) -> Result[int, str]:\n    return value.map(lambda x: x + 5)\n\n# print(add_five(Success(10))) # Expected: Success(15)\n```","cause":"You are attempting to perform a direct operation on a monadic object (like `Result`, `Maybe`, `IO`) without first safely extracting its successful value or handling its failure state.","error":"TypeError: unsupported operand type(s) for +: 'Result[int, str]' and 'int'"},{"fix":"Import the specific type directly from its corresponding submodule, e.g., `returns.result` for `Result`.\n```python\nfrom returns.result import Result, Success, Failure\n# from returns.maybe import Maybe, Some, Nothing\n# from returns.io import IO, IOFailure, IOSuccess\n```","cause":"The `Result` type (or similar types like `Maybe`, `IO`) is not directly exposed under the top-level `returns` module; it must be imported from its specific submodule.","error":"AttributeError: module 'returns' has no attribute 'Result'"},{"fix":"Before calling `.unwrap()`, check if the `Result` is a `Success` using `.is_success`, or handle both `Success` and `Failure` cases using `.map()`, `.bind()`, `.alt()`, or pattern matching.\n```python\nfrom returns.result import Result, Success, Failure\n\ndef divide(a: int, b: int) -> Result[float, str]:\n    return Success(a / b) if b != 0 else Failure(\"Division by zero\")\n\nresult = divide(10, 0)\n\n# Correct handling:\nif result.is_success:\n    print(f\"Result: {result.unwrap()}\")\nelse:\n    print(f\"Error: {result.failure()}\")\n\n# Or using .alt() for a default value:\n# print(divide(10, 0).alt(lambda _: -1.0).unwrap()) # Prints -1.0\n```","cause":"You attempted to use the `.unwrap()` method on a `Result` object that is in a `Failure` state, which is designed to raise an exception when the underlying value cannot be successfully unwrapped.","error":"returns.primitives.exceptions.UnwrapFailedError: Cannot unwrap a `Failure` from the `Result` monad."}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.29.0","cli_name":"","cli_version":null,"type":"library","homepage":"https://returns.readthedocs.io","github":"https://github.com/sponsors/dry-python","docs":null,"changelog":null,"pypi":"https://pypi.org/project/returns/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization","testing"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-30","next_check":"2026-07-28","install_tag":null}}