-
Notifications
You must be signed in to change notification settings - Fork 78
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
Split Result type into Ok and Err class #18
Conversation
and make Result[T, E] a type alias for typing.Union[Ok[T], Err[E]]. This allows type safe access to the result members via isinstance checks.
Nice, thanks! Regarding However, I think that in the next version we should try to avoid magic, and be explicit in all decisions. Removing the default value (
Could we maybe add an empty |
Btw, we should probably add a note to the README that this library is best enjoyed together with mypy and type annotations. |
Yes, but you can already use a tuple to check for multiple types at once. |
As far as I can see, it isn't possible currently due to the restrictive way mypy treats variance. If you have a class covariant over |
I believe the error is from an outdated mypy. I couldn't install a development environment from requirements-dev.txt, so I set up a fresh poetry project and used that to setup my dev environment with up-to-date versions. With mypy 0.730 there are no errors. |
I think the most faithful way to model sum types is to create classes for each enum member like I've done here and then to wrap them into a class with just one attribute This structure also allows nested enums. If you just had a union type alias for the enum Example (using dataclass for brevity): @dataclass
class Ok(Generic[T]):
value: Final[T]
@dataclass
class Err(Generic[E]):
value: Final[E]
@dataclass
class Result(Generic[T, E]):
member: Union[Ok[T], Err[E]]
def unwrap_or(self, value: T) -> T:
if isinstance(self.member, Ok):
return self.member.value
else:
return value Downside: It's even more verbose |
Replaced by #27. Thanks @Emerentius for getting this started. If possible, I'll try to retain your co-ownership of the initial commit when merging the other PR 🙂 |
This allows for much better type safety in code that uses results, since code can now use `isinstance` as a replacement for matching on the type of a result. See #17 for details. A migration guide has been provided. Fixes #17, replaces #18. Co-authored-by: Emerentius <emerentius@arcor.de> Co-authored-by: francium <francium@users.noreply.github.com> Co-authored-by: Danilo Bargen <mail@dbrgn.ch>
and make
Result[T, E]
a type alias fortyping.Union[Ok[T], Err[E]]
.This allows type safe access to the result members via isinstance
checks.
Implementation of #17 for discussion.
This is of course a big breaking change. I've switched the order of the
T
andE
parameters to be in line with Rust. I haven't added theOk()
fallback forOk[bool]
, yet. I'm a bit confused on why that was added, especially with abool
member but it can of course be added again.The big upside of this way is type safety. A downside is that you can no longer do checks like
isinstance(res, Result)
becauseResult
is no longer a real type. Consequently, if you want to have aUnion[Result[T, E], U]
, it will be less ergonomic to go back toResult[T, E]
.