Skip to content

feat: add per-variant overloads to Option/Result methods - #111

Open
mittalabhi2123 wants to merge 1 commit into
OutSquareCapital:masterfrom
mittalabhi2123:feat/option-result-overloads
Open

mittalabhi2123 wants to merge 1 commit into
OutSquareCapital:masterfrom
mittalabhi2123:feat/option-result-overloads

Conversation

@mittalabhi2123

Copy link
Copy Markdown

Addresses #98

…pital#98)

Adds @overload pairs to Option.{map,flatten,and_then,ok_or,unwrap_or_else,
and_,or_,or_else,ok_or_else,inspect,unzip,zip,zip_with,reduce,xor} and
Result.{flatten,ok,err,unwrap_or_else,map_err,inspect,inspect_err,and_,or_,
or_else} so return types narrow to the precise Some/Null or Ok/Err variant
based on self's type, following the existing unwrap_or/is_some pattern.

transpose is intentionally left un-overloaded on both types: pyright
distributes overloads per-union-member when called on a widened
Result[Option[T], E] (as an existing typing test does on purpose), which
produces a correct but unsimplified union that breaks that test's
assert_type. This needs its own follow-up.

reduce's prior signature was typed as -> Option[R], which was actually
wrong when only one side is Some (it returns T or O, not R); the new
overloads correct this.

Fixes two benchmarks that passed Option.map/and_then as bare first-class
callables, which breaks once those methods are overloaded (pyright can't
bind an overloaded method reference to a single callable signature).

Adds typing-only check_* coverage in tests/test_typing/ for all new
overloads, following the existing assert_type/isinstance convention.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@OutSquareCapital OutSquareCapital left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual changes are looking great! Thank you for the work.

I left some comments on the tests and benchmarks changes

Comment thread benchmarks/test_option.py
return value * 2

assert benchmark(Some(10).map, double) == Some(20)
assert benchmark(lambda: Some(10).map(double)) == Some(20)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep ParamSpec usage instead of lambdas when possible. Any particular reason for these changes?

_b = assert_type(opt.inspect(print), Null[int])


def check_option_unzip() -> None:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three type checkers are failing here?



def check_option_ok_or() -> None:
opt: Option[int] = Some(10)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to let type checker inference do it's job as much as possible. explicit annotations should be avoided, or have a clear motivation. Here it should be fine in any case.

If there's issues with Literal[10] vs int, Dog and Animal classes could be preferable IMO

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of code repetition here.

Would be better to centralize as much as possible in pre-existing overload check function, or in new functions but without redundant assertions and divergent examples who swap [int, str] VS [int, int].

It's especially important since it's basically "dead code": doesn't test anything except type checkers behavior, hence we want to keep this as minimal as possible.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants