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

Strictly match all the possibilities in if-else blocks #9748

Closed
sayanarijit opened this issue Nov 23, 2020 · 1 comment
Closed

Strictly match all the possibilities in if-else blocks #9748

sayanarijit opened this issue Nov 23, 2020 · 1 comment
Labels

Comments

@sayanarijit
Copy link

sayanarijit commented Nov 23, 2020

Feature

Inspired by the match statement in modern languages like Rust, Elm, Haskell etc., I would like the if-else blocks in Python to be stricter and make us match all the possibilities either explicitly or by enforcing the else block or by enforcing the usage of > / < to cover all the possibilities.

Pitch

I have attempted to gain this strictness to some degree (only for enums) by creating this library. However, hacks like these aren't static and requires us to run the program to identify the missing possibilities.

Here's my proposal:

  • For values with finite possibilities (e.g. bool, Enum etc.), the else block isn't required, but it can be used as a wildcard matcher.

e.g.

class Color(Enum):
    red: auto()
    green: auto()
    blue: auto()

color = Color.red

# Valid
if color == Color.red:
    ...
elif color == Color.green:
    ...
elif color == Color.blue:
    ...

# Also valid
if color == Color.red or color == Color.green:
    ...
elif color == Color.blue:
    ...

# Also valid
if color in [Color.red, Color.green]:
    ...
elif color == Color.blue:
    ...

# Also valid
if color == Color.red:
    ...
else:
    ...

# Invalid (missing possibility: Color.blue)
if color == Color.red:
    ...
elif color == Color.green:
    ...
  • For values with infinite possibilities (e.g. str, int etc.), must either use the else block or use > / < to cover all the possibilities.

e.g.

x = 10

# Valid
if x == 10:
    ...
else:
    ...

# Also valid
if x == 10:
    ...
elif x < 10:
    ...
elif x > 10:
    ...

# Also valid
if x in range(10, 20):
    ...
elif x < 10:
    ...
elif x >= 20:
    ...

# Invalid (Missing possibilities where x != 10 and x != 11)
if x == 10:
   ...
elif x == 11:
   ...

There will be more edge-cases that we'll need to cover, however, I think for this feature, having something is better than nothing. So this is my general proposal as the starting point.

@hauntsaninja
Copy link
Collaborator

I'm closing this as a duplicate of #5818 and #6366
It should be possible to get the assert_never trick described in those issues to make your enum examples work. mypy's not going to change to enforce that all if statements are exhaustive by default, since there are many good reasons to have non-exhaustive if statements. The range / dependent type stuff you propose isn't covered by those issues, but it would probably be a lot of work to design and implement.
Finally, Python might soon have a match statement (see PEP 636, 634, 635)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants