Skip to content

Commit

Permalink
add mypy type tests with pytest-mypy-plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandermalyga committed Dec 31, 2022
1 parent 39b8fd5 commit f148059
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 1 deletion.
194 changes: 193 additions & 1 deletion poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pytest = "^7.2.0"
mypy = "^0.991"
black = "^22.10.0"
isort = "^5.10.1"
pytest-mypy-plugins = "^1.10.1"

[tool.mypy]
strict = true
Expand Down
39 changes: 39 additions & 0 deletions tests/mypy/test_decorator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
- case: decorator_no_args
main: |
from poltergeist import poltergeist, Result
@poltergeist
def test(a: int, b: str) -> float | None: ...
reveal_type(test) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> Union[poltergeist.result.Ok[Union[builtins.float, None], builtins.Exception], poltergeist.result.Err[Union[builtins.float, None], builtins.Exception]]"
- case: decorator_default
main: |
from poltergeist import poltergeist, Result
@poltergeist()
def test(a: int, b: str) -> float | None: ...
reveal_type(test) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> Union[poltergeist.result.Ok[Union[builtins.float, None], builtins.Exception], poltergeist.result.Err[Union[builtins.float, None], builtins.Exception]]"
- case: decorator_with_args
main: |
from poltergeist import poltergeist, Result
@poltergeist(error=ValueError)
def test(a: int, b: str) -> float | None: ...
reveal_type(test) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> Union[poltergeist.result.Ok[Union[builtins.float, None], builtins.ValueError], poltergeist.result.Err[Union[builtins.float, None], builtins.ValueError]]"
- case: decorator_invalid_error_type
main: |
from poltergeist import poltergeist, Result
@poltergeist(error=123)
def test(a: int, b: str) -> float | None: ...
out: |
main:3: error: No overload variant of "poltergeist" matches argument type "int" [call-overload]
main:3: note: Possible overload variants:
main:3: note: def [P`-1, T] poltergeist(Callable[P, T], /) -> Callable[P, Union[Ok[T, Exception], Err[T, Exception]]]
main:3: note: def poltergeist() -> Callable[[Callable[P, T]], Callable[P, Union[Ok[T, Exception], Err[T, Exception]]]]
main:3: note: def [E <: BaseException] poltergeist(*, error: Type[E]) -> Callable[[Callable[P, T]], Callable[P, Union[Ok[T, E], Err[T, E]]]]
33 changes: 33 additions & 0 deletions tests/mypy/test_err.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
- case: err_generic
main: |
from poltergeist import Err
instance: Err[str, Exception] = Err(123) # E: Argument 1 to "Err" has incompatible type "int"; expected "Exception" [arg-type]
other: Err[str, int] # E: Type argument "int" of "Err" must be a subtype of "BaseException" [type-var]
- case: err_err
main: |
from poltergeist import Err
instance: Err[str, Exception]
reveal_type(instance.err()) # N: Revealed type is "builtins.Exception"
- case: err_unwrap
main: |
from poltergeist import Err
instance: Err[str, Exception]
reveal_type(instance.unwrap()) # N: Revealed type is "<nothing>"
- case: err_unwrap_or
main: |
from poltergeist import Err
instance: Err[str, Exception]
reveal_type(instance.unwrap_or()) # N: Revealed type is "None"
reveal_type(instance.unwrap_or(123)) # N: Revealed type is "builtins.int"
reveal_type(instance.unwrap_or("abc")) # N: Revealed type is "builtins.str"
- case: err_unwrap_or_else
main: |
from poltergeist import Err
instance: Err[str, Exception]
reveal_type(instance.unwrap_or_else(lambda e: e)) # N: Revealed type is "builtins.Exception"
instance.unwrap_or_else(123) # E: Argument 1 to "unwrap_or_else" of "Err" has incompatible type "int"; expected "Callable[[Exception], <nothing>]" [arg-type]
default: str = instance.unwrap_or_else(lambda e: e) # E: Incompatible types in assignment (expression has type "Exception", variable has type "str") [assignment]
32 changes: 32 additions & 0 deletions tests/mypy/test_ok.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
- case: ok_generic
main: |
from poltergeist import Ok
instance: Ok[str, Exception] = Ok(123) # E: Argument 1 to "Ok" has incompatible type "int"; expected "str" [arg-type]
other: Ok[str, int] # E: Type argument "int" of "Ok" must be a subtype of "BaseException" [type-var]
- case: ok_err
main: |
from poltergeist import Ok
instance: Ok[str, Exception]
reveal_type(instance.err()) # N: Revealed type is "None"
- case: ok_unwrap
main: |
from poltergeist import Ok
instance: Ok[str, Exception]
reveal_type(instance.unwrap()) # N: Revealed type is "builtins.str"
- case: ok_unwrap_or
main: |
from poltergeist import Ok
instance: Ok[str, Exception]
reveal_type(instance.unwrap_or()) # N: Revealed type is "builtins.str"
reveal_type(instance.unwrap_or(123)) # N: Revealed type is "builtins.str"
reveal_type(instance.unwrap_or("abc")) # N: Revealed type is "builtins.str"
- case: ok_unwrap_or_else
main: |
from poltergeist import Ok
instance: Ok[str, Exception]
reveal_type(instance.unwrap_or_else(lambda e: e)) # N: Revealed type is "builtins.str"
instance.unwrap_or_else(123) # E: Argument 1 to "unwrap_or_else" of "Ok" has incompatible type "int"; expected "Callable[[Exception], <nothing>]" [arg-type]
40 changes: 40 additions & 0 deletions tests/mypy/test_result.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
- case: result_generic
main: |
from poltergeist import Result, Ok, Err
ok: Result[str, Exception] = Ok(123) # E: Argument 1 to "Ok" has incompatible type "int"; expected "str" [arg-type]
err: Result[str, Exception] = Err(123) # E: Argument 1 to "Err" has incompatible type "int"; expected "Exception" [arg-type]
other: Result[str, int]
out: |
main:4: error: Type argument "int" of "Ok" must be a subtype of "BaseException" [type-var]
main:4: error: Type argument "int" of "Err" must be a subtype of "BaseException" [type-var]
- case: result_err
main: |
from poltergeist import Result
instance: Result[str, Exception]
reveal_type(instance.err()) # N: Revealed type is "Union[None, builtins.Exception]"
- case: result_unwrap
main: |
from poltergeist import Result
instance: Result[str, Exception]
reveal_type(instance.unwrap()) # N: Revealed type is "builtins.str"
- case: result_unwrap_or
main: |
from poltergeist import Result
instance: Result[str, Exception]
reveal_type(instance.unwrap_or()) # N: Revealed type is "Union[builtins.str, None]"
reveal_type(instance.unwrap_or(123)) # N: Revealed type is "Union[builtins.str, builtins.int]"
reveal_type(instance.unwrap_or("abc")) # N: Revealed type is "builtins.str"
- case: result_unwrap_or_else
main: |
from poltergeist import Result
instance: Result[str, Exception]
reveal_type(instance.unwrap_or_else(lambda e: e)) # N: Revealed type is "Union[builtins.str, builtins.Exception]"
default: str = instance.unwrap_or_else(lambda e: e) # E: Incompatible types in assignment (expression has type "Union[str, Exception]", variable has type "str") [assignment]
instance.unwrap_or_else(123)
out: |
main:5: error: Argument 1 to "unwrap_or_else" of "Ok" has incompatible type "int"; expected "Callable[[Exception], <nothing>]" [arg-type]
main:5: error: Argument 1 to "unwrap_or_else" of "Err" has incompatible type "int"; expected "Callable[[Exception], <nothing>]" [arg-type]

0 comments on commit f148059

Please sign in to comment.