From 7dd4b765ad84500300634acef6c753c1c563bc6b Mon Sep 17 00:00:00 2001 From: Alexander Malyga Date: Sat, 14 Jan 2023 16:52:20 +0100 Subject: [PATCH] removed unnecessary generic parameters from Ok and Err. WIP --- poltergeist/result.py | 8 ++++---- tests/mypy/test_decorator.yml | 12 ++++++------ tests/mypy/test_err.yml | 12 ++++++------ tests/mypy/test_ok.yml | 17 +++++++++-------- tests/mypy/test_result.yml | 7 ++----- tests/test_result.py | 8 ++++---- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/poltergeist/result.py b/poltergeist/result.py index 8806a68..f38f5d8 100644 --- a/poltergeist/result.py +++ b/poltergeist/result.py @@ -8,7 +8,7 @@ @final @dataclass(repr=False, frozen=True, slots=True) -class Ok(Generic[T, E]): +class Ok(Generic[T]): _value: T def __repr__(self) -> str: @@ -31,13 +31,13 @@ def unwrap_or(self, default: DefaultT) -> T: def unwrap_or(self, default: Any = None) -> Any: return self.unwrap() - def unwrap_or_else(self, op: Callable[[E], DefaultT]) -> T: + def unwrap_or_else(self, op: NoReturn) -> T: return self.unwrap() @final @dataclass(repr=False, eq=False, frozen=True, slots=True) -class Err(Generic[T, E]): +class Err(Generic[E]): _err: E def __repr__(self) -> str: @@ -71,4 +71,4 @@ def __eq__(self, __o: Any) -> bool: ) -Result = Ok[T, E] | Err[T, E] +Result = Ok[T] | Err[E] diff --git a/tests/mypy/test_decorator.yml b/tests/mypy/test_decorator.yml index 9c9aee2..be74660 100644 --- a/tests/mypy/test_decorator.yml +++ b/tests/mypy/test_decorator.yml @@ -5,7 +5,7 @@ @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]]" + reveal_type(test) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> Union[poltergeist.result.Ok[Union[builtins.float, None]], poltergeist.result.Err[builtins.Exception]]" - case: decorator_default main: | @@ -14,7 +14,7 @@ @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]]" + reveal_type(test) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> Union[poltergeist.result.Ok[Union[builtins.float, None]], poltergeist.result.Err[builtins.Exception]]" - case: decorator_with_args main: | @@ -23,7 +23,7 @@ @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]]" + reveal_type(test) # N: Revealed type is "def (a: builtins.int, b: builtins.str) -> Union[poltergeist.result.Ok[Union[builtins.float, None]], poltergeist.result.Err[builtins.ValueError]]" - case: decorator_invalid_error_type main: | @@ -34,6 +34,6 @@ 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]]]] + main:3: note: def [P`-1, T] poltergeist(Callable[P, T], /) -> Callable[P, Union[Ok[T], Err[Exception]]] + main:3: note: def poltergeist() -> Callable[[Callable[P, T]], Callable[P, Union[Ok[T], Err[Exception]]]] + main:3: note: def [E <: BaseException] poltergeist(*, error: Type[E]) -> Callable[[Callable[P, T]], Callable[P, Union[Ok[T], Err[E]]]] diff --git a/tests/mypy/test_err.yml b/tests/mypy/test_err.yml index c451c0e..88b2052 100644 --- a/tests/mypy/test_err.yml +++ b/tests/mypy/test_err.yml @@ -1,25 +1,25 @@ - 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] + instance: Err[Exception] = Err(123) # E: Argument 1 to "Err" has incompatible type "int"; expected "Exception" [arg-type] + other: Err[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] + instance: Err[Exception] reveal_type(instance.err()) # N: Revealed type is "builtins.Exception" - case: err_unwrap main: | from poltergeist import Err - instance: Err[str, Exception] + instance: Err[Exception] reveal_type(instance.unwrap()) # N: Revealed type is "" - case: err_unwrap_or main: | from poltergeist import Err - instance: Err[str, Exception] + instance: Err[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" @@ -27,7 +27,7 @@ - case: err_unwrap_or_else main: | from poltergeist import Err - instance: Err[str, Exception] + instance: Err[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], ]" [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] diff --git a/tests/mypy/test_ok.yml b/tests/mypy/test_ok.yml index d8e5b9f..4a5ac58 100644 --- a/tests/mypy/test_ok.yml +++ b/tests/mypy/test_ok.yml @@ -1,25 +1,24 @@ - 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] + instance: Ok[str] = Ok(123) # E: Argument 1 to "Ok" has incompatible type "int"; expected "str" [arg-type] - case: ok_err main: | from poltergeist import Ok - instance: Ok[str, Exception] + instance: Ok[str] reveal_type(instance.err()) # N: Revealed type is "None" - case: ok_unwrap main: | from poltergeist import Ok - instance: Ok[str, Exception] + instance: Ok[str] reveal_type(instance.unwrap()) # N: Revealed type is "builtins.str" - case: ok_unwrap_or main: | from poltergeist import Ok - instance: Ok[str, Exception] + instance: Ok[str] 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" @@ -27,6 +26,8 @@ - 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], ]" [arg-type] + instance: Ok[str] + reveal_type(instance.unwrap_or_else(lambda e: e)) + out: | + main:3: note: Revealed type is "builtins.str" + main:3: error: Argument 1 to "unwrap_or_else" of "Ok" has incompatible type "Callable[[Any], Any]"; expected "NoReturn" [arg-type] diff --git a/tests/mypy/test_result.yml b/tests/mypy/test_result.yml index 88ebf3b..a909825 100644 --- a/tests/mypy/test_result.yml +++ b/tests/mypy/test_result.yml @@ -3,10 +3,7 @@ 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] + other: Result[str, int] # E: Type argument "int" of "Err" must be a subtype of "BaseException" [type-var] - case: result_err main: | @@ -36,5 +33,5 @@ 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], ]" [arg-type] + main:5: error: Argument 1 to "unwrap_or_else" of "Ok" has incompatible type "int"; expected "NoReturn" [arg-type] main:5: error: Argument 1 to "unwrap_or_else" of "Err" has incompatible type "int"; expected "Callable[[Exception], ]" [arg-type] diff --git a/tests/test_result.py b/tests/test_result.py index 18fa600..dd18c9d 100644 --- a/tests/test_result.py +++ b/tests/test_result.py @@ -4,7 +4,7 @@ def test_ok() -> None: - result: Result[str, Exception] = Ok("abc") + result = Ok("abc") match result: case Ok(v): @@ -24,7 +24,7 @@ def test_ok() -> None: def test_ok_eq() -> None: - result: Result[str, Exception] = Ok("abc") + result = Ok("abc") assert result == Ok("abc") assert result != Ok("aaa") assert result != Err(Exception("abc")) @@ -32,7 +32,7 @@ def test_ok_eq() -> None: def test_error() -> None: - result: Result[str, ValueError] = Err(ValueError("abc")) + result = Err(ValueError("abc")) match result: case Err(e): @@ -58,7 +58,7 @@ def test_error() -> None: def test_err_eq() -> None: - result: Result[str, ValueError] = Err(ValueError("abc")) + result = Err(ValueError("abc")) assert result == Err(ValueError("abc")) assert result != Err(ValueError("aaa")) assert result != Err(ValueError("abc", 1))