Skip to content
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

Consistently mark types with | MaybeNone whenever it is applicable #12822

Open
oprypin opened this issue Oct 16, 2024 · 4 comments
Open

Consistently mark types with | MaybeNone whenever it is applicable #12822

oprypin opened this issue Oct 16, 2024 · 4 comments

Comments

@oprypin
Copy link
Contributor

oprypin commented Oct 16, 2024

I noticed that there's a special type alias MaybeNone that represents this specific intent:

We didn't dare to change the type to X | None so instead we changed it to Any

You can find an example in a relatively recent addition of this.

And while this approach makes me very sad, it is good that such cases are marked with MaybeNone, for the purpose of looking at them specially. Maybe some type checker will arise that will have specific handling for it and do something smarter instead.

With that in mind, it would be good to ensure that all such cases are consistently marked.

I noticed at least one case that is not marked like this. It has | Any directly written instead of | MaybeNone. This is in re.match.group*:

typeshed/stdlib/re.pyi

Lines 93 to 117 in 6feca18

def group(self, group: str | int, /) -> AnyStr | Any: ...
@overload
def group(self, group1: str | int, group2: str | int, /, *groups: str | int) -> tuple[AnyStr | Any, ...]: ...
# Each item of groups()'s return tuple is either "AnyStr" or
# "AnyStr | None", depending on the pattern.
@overload
def groups(self) -> tuple[AnyStr | Any, ...]: ...
@overload
def groups(self, default: _T) -> tuple[AnyStr | _T, ...]: ...
# Each value in groupdict()'s return dict is either "AnyStr" or
# "AnyStr | None", depending on the pattern.
@overload
def groupdict(self) -> dict[str, AnyStr | Any]: ...
@overload
def groupdict(self, default: _T) -> dict[str, AnyStr | _T]: ...
def start(self, group: int | str = 0, /) -> int: ...
def end(self, group: int | str = 0, /) -> int: ...
def span(self, group: int | str = 0, /) -> tuple[int, int]: ...
@property
def regs(self) -> tuple[tuple[int, int], ...]: ... # undocumented
# __getitem__() returns "AnyStr" or "AnyStr | None", depending on the pattern.
@overload
def __getitem__(self, key: Literal[0], /) -> AnyStr: ...
@overload
def __getitem__(self, key: int | str, /) -> AnyStr | Any: ...

@JelleZijlstra
Copy link
Member

Feel free to submit a PR!

And if you're motivated to get this to a better state, consider writing a PEP for something like python/typing#1096.

@srittau
Copy link
Collaborator

srittau commented Oct 16, 2024

Or python/typing#566, which would replace this with AnyOf[X, None] and could also be controlled with strictness flags.

@oprypin
Copy link
Contributor Author

oprypin commented Oct 16, 2024

Sure, if AnyOf is ever approved, then in this repository one could find all occurrences of MaybeNone and replace them.

But that's what I want to track in this issue - that all the occurrences are readily marked for this. So that then it's more straightforward to apply any such ideas.

@oprypin

This comment was marked as outdated.

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

No branches or pull requests

3 participants