Skip to content

Bump mypy to 1.10 #1852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ incremental in minor, bugfixes only are patches.
See [0Ver](https://0ver.org/).


## 1.0.0 WIP
## 0.23.0

### Features

- *Breaking*: Remove `success_type` and `failure_type` fields from `IOResult`,
`Maybe` and `Result` types

### Misc

- *Breaking*: Remove `success_type` and `failure_type` fields from `IOResult`, `Maybe` and `Result` types
- Now requires `mypy>=1.10`
- Adds `[check-laws]` extra for installation


## 0.22.0

Expand Down
15 changes: 12 additions & 3 deletions docs/pages/contrib/mypy_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,19 @@ and improve type-safety of things developers commonly use.
Installation
------------

You will need to install ``mypy`` separately.
It is not bundled with ``returns``.
``returns`` has ``[compatible-mypy]`` extra to install the supported version.

To install any ``mypy`` plugin add it
.. code:: bash

pip install 'returns[compatible-mypy]'

Or you can install ``mypy`` separately and check that version is supported.


Enabling our mypy plugin
------------------------

To install our ``mypy`` plugin add it
to the ``plugins`` section of the config file (``setup.cfg`` or ``mypy.ini``):

.. code:: ini
Expand Down
709 changes: 335 additions & 374 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "returns"
version = "0.22.0"
version = "0.23.0"
description = "Make your functions return something meaningful, typed, and safe!"
license = "BSD-3-Clause"

Expand Down Expand Up @@ -49,13 +49,13 @@ _ = "returns.contrib.hypothesis._entrypoint"
python = "^3.9"

typing-extensions = ">=4.0,<5.0"
mypy = { version = ">=1.5,<1.6", optional = true }
mypy = { version = ">=1.10,<1.11", optional = true }
pytest = { version = "^8.0", optional = true }
hypothesis = { version = "^6.98", optional = true }

[tool.poetry.group.dev.dependencies]
anyio = "^4.3"
trio = ">=0.24,<0.26"
trio = "^0.25"
attrs = "^23.2"
httpx = "^0.27"

Expand Down
2 changes: 1 addition & 1 deletion returns/context/requires_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def ask(cls) -> RequiresContext[_EnvType, _EnvType]:
RequiresContext[int, Dict[str, str]].ask()

Otherwise, your ``.ask()`` method
will return ``RequiresContext[<nothing>, <nothing>]``,
will return ``RequiresContext[Never, Never]``,
which is unusable:

.. code:: python
Expand Down
4 changes: 2 additions & 2 deletions returns/contrib/mypy/_features/kind.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ def kinded_call(ctx: MethodContext) -> MypyType:
Turns ``-> KindN[I, t1, t2, t3]`` into ``-> I[t1, t2, t3]``.

Also strips unused type arguments for ``KindN``, so:
- ``KindN[IO, int, <nothing>, <nothing>]`` will be ``IO[int]``
- ``KindN[Result, int, str, <nothing>]`` will be ``Result[int, str]``
- ``KindN[IO, int, Never, Never]`` will be ``IO[int]``
- ``KindN[Result, int, str, Never]`` will be ``Result[int, str]``

It also processes nested ``KindN`` with recursive strategy.

Expand Down
12 changes: 7 additions & 5 deletions returns/contrib/mypy/_typeops/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
from mypy.types import CallableType, FunctionLike
from mypy.types import Type as MypyType
from mypy.types import TypeVarId
from typing_extensions import TypeAlias

from returns.contrib.mypy._structures.args import FuncArg
from returns.contrib.mypy._structures.types import CallableContext
from returns.contrib.mypy._typeops.analtype import analyze_call

#: Mapping of `typevar` to real type.
_Constraints = Mapping[TypeVarId, MypyType]
_Constraints: TypeAlias = Mapping[TypeVarId, MypyType]


@final
Expand Down Expand Up @@ -81,10 +82,11 @@ def _infer_constraints(
)
constraints = infer_constraints_for_callable(
self._fallback,
[arg.type for arg in applied_args],
kinds,
formal_to_actual,
checker.argument_infer_context(),
arg_types=[arg.type for arg in applied_args],
arg_kinds=kinds,
arg_names=[arg.name for arg in applied_args],
formal_to_actual=formal_to_actual,
context=checker.argument_infer_context(),
)
return {
constraint.type_var: constraint.target
Expand Down
1 change: 0 additions & 1 deletion returns/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from typing_extensions import ParamSpec

# Aliases:
_FirstType = TypeVar('_FirstType')
_SecondType = TypeVar('_SecondType')
_ThirdType = TypeVar('_ThirdType')
Expand Down
1 change: 1 addition & 0 deletions returns/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from returns.primitives.exceptions import UnwrapFailedError


# TODO: add overloads for specific types, so it can narrow them with `TypeIs`
def is_successful(container: Unwrappable) -> bool:
"""
Determines if a container was successful or not.
Expand Down
2 changes: 1 addition & 1 deletion returns/primitives/asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _convert(container, *, deps, backend: str):
import anyio

return _convert(
anyio.run(container.awaitable, backend=backend), # type: ignore
anyio.run(container.awaitable, backend=backend),
deps=deps,
backend=backend,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def factory(post: _Post) -> str:
future_result = managed_httpx(
FutureResultE.from_value(httpx.AsyncClient(timeout=5)),
)
print(anyio.run(future_result.awaitable)) # type: ignore # noqa: WPS421
print(anyio.run(future_result.awaitable)) # noqa: WPS421
# <IOResult: <Success: (
# 'sunt aut facere repellat provident occaecati ...',
# 'qui est esse',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
main: |
from returns.context import RequiresContext

reveal_type(RequiresContext.ask()) # N: Revealed type is "returns.context.requires_context.RequiresContext[<nothing>, <nothing>]"
reveal_type(RequiresContext.ask()) # N: Revealed type is "returns.context.requires_context.RequiresContext[Never, Never]"


- case: context_ask2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
main: |
from returns.context import RequiresContextFutureResult

reveal_type(RequiresContextFutureResult.ask()) # N: Revealed type is "returns.context.requires_context_future_result.RequiresContextFutureResult[<nothing>, <nothing>, <nothing>]"
reveal_type(RequiresContextFutureResult.ask()) # N: Revealed type is "returns.context.requires_context_future_result.RequiresContextFutureResult[Never, Never, Never]"


- case: context_result_future_ask2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
main: |
from returns.context import RequiresContextIOResult

reveal_type(RequiresContextIOResult.ask()) # N: Revealed type is "returns.context.requires_context_ioresult.RequiresContextIOResult[<nothing>, <nothing>, <nothing>]"
reveal_type(RequiresContextIOResult.ask()) # N: Revealed type is "returns.context.requires_context_ioresult.RequiresContextIOResult[Never, Never, Never]"


- case: context_result_io_ask2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
main: |
from returns.context import RequiresContextResult

reveal_type(RequiresContextResult.ask()) # N: Revealed type is "returns.context.requires_context_result.RequiresContextResult[<nothing>, <nothing>, <nothing>]"
reveal_type(RequiresContextResult.ask()) # N: Revealed type is "returns.context.requires_context_result.RequiresContextResult[Never, Never, Never]"


- case: context_ask2
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_converters/test_flatten.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

flatten(returns_result())
out: |
main:7: error: Argument 1 to "flatten" has incompatible type "Result[int, Result[int, str]]"; expected "KindN[Result[Any, Any], KindN[Result[Any, Any], <nothing>, Result[int, str], NoReturn], Result[int, str], NoReturn]" [arg-type]
main:7: error: Argument 1 to "flatten" has incompatible type "Result[int, Result[int, str]]"; expected "KindN[Result[Any, Any], KindN[Result[Any, Any], Never, Result[int, str], NoReturn], Result[int, str], NoReturn]" [arg-type]


- case: flatten_io
Expand Down
4 changes: 3 additions & 1 deletion typesafety/test_curry/test_curry/test_curry_generics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@
x: List[int]

reveal_type(zero) # N: Revealed type is "Overload(def (arg: builtins.int) -> def [T] (other: builtins.list[T`-1]) -> T`-1, def [T] (arg: builtins.int, other: builtins.list[T`-1]) -> T`-1)"
reveal_type(zero(1)) # N: Revealed type is "def [T] (other: builtins.list[T`-1]) -> T`-1"
reveal_type(zero(1)) # N: Revealed type is "def [T] (other: builtins.list[T`2]) -> T`2"
reveal_type(zero(1)(x)) # N: Revealed type is "builtins.int"
reveal_type(zero(1, x)) # N: Revealed type is "builtins.int"


# TODO: enable and fix our plugin
- case: curry_two_generic_args3
disable_cache: false
skip: True
main: |
from returns.curry import curry
from typing import List, TypeVar
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_curry/test_partial/test_partial.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
def exit(x: int) -> NoReturn:
...

reveal_type(partial(exit, 1)) # N: Revealed type is "def () -> <nothing>"
reveal_type(partial(exit, 1)) # N: Revealed type is "def () -> Never"


- case: partial_wrong_argument_types
Expand Down
22 changes: 11 additions & 11 deletions typesafety/test_curry/test_partial/test_partial_arguments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@
reveal_type(partial(multiple, 1, 2, 3, 4.0, 5.0))
reveal_type(partial(multiple, 1, 2, 3, m='m', q='q', long='long'))
out: |
main:14: note: Revealed type is "def (a: builtins.int, b: builtins.int, c: builtins.int =, *args: builtins.float, *, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:15: note: Revealed type is "def (b: builtins.int, c: builtins.int =, *args: builtins.float, *, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:16: note: Revealed type is "def (c: builtins.int =, *args: builtins.float, *, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:17: note: Revealed type is "def (*args: builtins.float, *, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:18: note: Revealed type is "def (*args: builtins.float, *, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:19: note: Revealed type is "def (*args: builtins.float, *, d: builtins.str, **kwargs: builtins.str) -> builtins.str"
main:20: note: Revealed type is "def (c: builtins.int =, *args: builtins.float, *, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:21: note: Revealed type is "def (c: builtins.int =, *args: builtins.float, *, d: builtins.str, **kwargs: builtins.str) -> builtins.str"
main:22: note: Revealed type is "def (*args: builtins.float, *, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:23: note: Revealed type is "def (*args: builtins.float, *, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:14: note: Revealed type is "def (a: builtins.int, b: builtins.int, c: builtins.int =, *args: builtins.float, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:15: note: Revealed type is "def (b: builtins.int, c: builtins.int =, *args: builtins.float, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:16: note: Revealed type is "def (c: builtins.int =, *args: builtins.float, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:17: note: Revealed type is "def (*args: builtins.float, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:18: note: Revealed type is "def (*args: builtins.float, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:19: note: Revealed type is "def (*args: builtins.float, d: builtins.str, **kwargs: builtins.str) -> builtins.str"
main:20: note: Revealed type is "def (c: builtins.int =, *args: builtins.float, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:21: note: Revealed type is "def (c: builtins.int =, *args: builtins.float, d: builtins.str, **kwargs: builtins.str) -> builtins.str"
main:22: note: Revealed type is "def (*args: builtins.float, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"
main:23: note: Revealed type is "def (*args: builtins.float, d: builtins.str, e: builtins.bool =, **kwargs: builtins.str) -> builtins.str"


- case: partial_args_kwargs
Expand Down Expand Up @@ -159,7 +159,7 @@
def test(func: C) -> C:
# One can say, that this case is not supported,
# but I don't know how to work with it
reveal_type(partial(func, 1)) # N: Revealed type is "def (*Any, **Any) -> <nothing>"
reveal_type(partial(func, 1)) # N: Revealed type is "def (*Any, **Any) -> Any"
return func

test(first)
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_functions/test_raise_exception.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
main: |
from returns.functions import raise_exception

reveal_type(raise_exception(ValueError())) # N: Revealed type is "<nothing>"
reveal_type(raise_exception(ValueError())) # N: Revealed type is "Never"
2 changes: 1 addition & 1 deletion typesafety/test_future/test_future_container/test_do.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
for x in Future.from_value(1)
)
out: |
main:3: error: Argument 1 to "do" of "Future" has incompatible type "Generator[Any, None, None]"; expected "AsyncGenerator[<nothing>, None]" [arg-type]
main:3: error: Argument 1 to "do" of "Future" has incompatible type "Generator[Any, None, None]"; expected "AsyncGenerator[Never, None]" [arg-type]
main:5: error: "Future[int]" has no attribute "__iter__"; maybe "__aiter__"? (not iterable) [attr-defined]
main:5: note: Maybe you forgot to use "await"?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
for first in FutureSuccess(1)
)
out: |
main:3: error: Argument 1 to "do" of "FutureResult" has incompatible type "Generator[Any, None, None]"; expected "AsyncGenerator[<nothing>, None]" [arg-type]
main:3: error: Argument 1 to "do" of "FutureResult" has incompatible type "Generator[Any, None, None]"; expected "AsyncGenerator[Never, None]" [arg-type]
main:5: error: "FutureResult[int, Any]" has no attribute "__iter__"; maybe "__aiter__"? (not iterable) [attr-defined]
main:5: note: Maybe you forgot to use "await"?

Expand All @@ -31,7 +31,7 @@
main: |
from returns.future import FutureSuccess, FutureResult

reveal_type(FutureResult.do( # N: Revealed type is "returns.future.FutureResult[builtins.float, <nothing>]"
reveal_type(FutureResult.do( # N: Revealed type is "returns.future.FutureResult[builtins.float, Never]"
x + y
async for x in FutureSuccess(1)
async for y in FutureSuccess(2.5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
...

x: MyClass[str, int]
reveal_type(MyClass.from_failure(10)) # N: Revealed type is "main.MyClass[<nothing>, builtins.int]"
reveal_type(MyClass.from_failure(10)) # N: Revealed type is "main.MyClass[Never, builtins.int]"


- case: diverse_failable_inheritance_correct3
Expand All @@ -48,7 +48,7 @@
...

x: MyClass[float, bool, str]
reveal_type(MyClass.from_failure(10)) # N: Revealed type is "main.MyClass[<nothing>, builtins.int, <nothing>]"
reveal_type(MyClass.from_failure(10)) # N: Revealed type is "main.MyClass[Never, builtins.int, Never]"


- case: diverse_failable_inheritance_missing
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_io/test_ioresult_container/test_do.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
main: |
from returns.io import IOSuccess, IOResult

reveal_type(IOResult.do( # N: Revealed type is "returns.io.IOResult[builtins.float, <nothing>]"
reveal_type(IOResult.do( # N: Revealed type is "returns.io.IOResult[builtins.float, Never]"
x + y
for x in IOSuccess(1)
for y in IOSuccess(2.5)
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_maybe/test_maybe_type_cast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@
main: |
from returns.maybe import Nothing

reveal_type(Nothing) # N: Revealed type is "returns.maybe.Maybe[<nothing>]"
reveal_type(Nothing) # N: Revealed type is "returns.maybe.Maybe[Never]"
4 changes: 2 additions & 2 deletions typesafety/test_pipeline/test_flow/test_flow_args.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
reveal_type(flow())
out: |
main:3: error: Missing positional argument "instance" in call to "flow" [call-arg]
main:3: note: Revealed type is "<nothing>"
main:3: note: Revealed type is "Never"


- case: flow_one_arg
Expand All @@ -17,7 +17,7 @@
reveal_type(flow(1))
out: |
main:3: error: Too few arguments for "flow" [misc]
main:3: note: Revealed type is "<nothing>"
main:3: note: Revealed type is "Never"


- case: flow_star_args
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_pipeline/test_flow/test_flow_errors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

reveal_type(flow('a', [], int))
out: |
main:3: error: "List[<nothing>]" not callable [operator]
main:3: error: "List[Never]" not callable [operator]
main:3: note: Revealed type is "builtins.int"


Expand Down
6 changes: 3 additions & 3 deletions typesafety/test_pipeline/test_pipe/test_pipe_errors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

pipe([], int)('a')
out: |
main:3: error: "List[<nothing>]" not callable [operator]
main:3: error: <nothing> not callable [misc]
main:3: error: Argument 1 to "__call__" of "_Pipe" has incompatible type "str"; expected <nothing> [arg-type]
main:3: error: "List[Never]" not callable [operator]
main:3: error: Never not callable [misc]
main:3: error: Argument 1 to "__call__" of "_Pipe" has incompatible type "str"; expected Never [arg-type]


- case: pipe_function_without_steps
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_pointfree/test_bind_awaitable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
...

x: Future[float]
bind_awaitable(test)(x) # E: Argument 1 to "bind_awaitable" has incompatible type "Callable[[float], int]"; expected "Callable[[float], Awaitable[<nothing>]]" [arg-type]
bind_awaitable(test)(x) # E: Argument 1 to "bind_awaitable" has incompatible type "Callable[[float], int]"; expected "Callable[[float], Awaitable[Never]]" [arg-type]


- case: bind_awaitable_with_flow
Expand Down
2 changes: 1 addition & 1 deletion typesafety/test_pointfree/test_bind_future.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
...

x: Future[str]
bind_future(test)(x) # E: Argument 1 to "bind_future" has incompatible type "Callable[[str], Coroutine[Any, Any, Future[int]]]"; expected "Callable[[str], Future[<nothing>]]" [arg-type]
bind_future(test)(x) # E: Argument 1 to "bind_future" has incompatible type "Callable[[str], Coroutine[Any, Any, Future[int]]]"; expected "Callable[[str], Future[Never]]" [arg-type]


- case: bind_future_requires_context_future_result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
function: Callable[[T], Kind1[Bindable1, N]],
) -> Bindable1[N]:
x = dekind(instance.bind(function))
reveal_type(x) # N: Revealed type is "returns.interfaces.bindable.BindableN[N`-2, <nothing>, <nothing>]"
reveal_type(x) # N: Revealed type is "returns.interfaces.bindable.BindableN[N`-2, Never, Never]"
return x


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@

container: Kind{{ count }}[object, int, str, bool, float]
out: |
main:3: error: Bad number of arguments for type alias, expected: {{ expected }}, given: 5 [type-arg]
main:3: error: Bad number of arguments for type alias, expected {{ expected }}, given 5 [type-arg]
Loading
Loading