Skip to content

Pyrefly Fails to Report Non-Exhaustive match Statements and Incorrect Enum Case Patterns #400

@davisuga

Description

@davisuga

Describe the Bug

Observed Behavior (with Pyrefly):

When analyzing Python match statements, Pyrefly currently reports no errors under the following conditions where issues are present:

  • Non-exhaustive matching: When case statements within a match block do not collectively handle all possible members of an Enum or all types within a Union that the matched variable could be.
  • Incorrect syntax for Enum member case patterns: When Enum members used in case patterns are incorrectly written with parentheses as if they were being called (e.g., MyEnum.MEMBER() instead of the correct syntax MyEnum.MEMBER).

This behavior implies Pyrefly currently considers these potentially problematic patterns as valid.

Expected Behavior:

Pyrefly should identify and report errors in the scenarios described above to help developers catch potential bugs and ensure code correctness:

  • For non-exhaustive matching: Pyrefly should issue an error or warning, ideally specifying which Enum members or Union types are not handled by any case statement.
  • For incorrect Enum syntax: Pyrefly should report a syntax or type error when Enum members are incorrectly used with parentheses in case patterns (e.g., similar to Pyright's "Literal[...] is not a class" report).

This would align Pyrefly's strictness with other type checkers and provide more robust static analysis for match statements.

Pyright's Output (for reference, from the original user report):

/Users/davi/gits/chief-app/test_types.py
  /Users/davi/gits/chief-app/test_types.py:21:11 - error: Cases within match statement do not exhaustively handle all values
    Unhandled type: "OrderStatus"
    If exhaustive handling is not intended, add "case _: pass" (reportMatchNotExhaustive)
  /Users/davi/gits/chief-app/test_types.py:22:14 - error: "Literal[OrderStatus.Ready]" is not a class (reportGeneralTypeIssues)
  /Users/davi/gits/chief-app/test_types.py:24:14 - error: "Literal[OrderStatus.Shipped]" is not a class (reportGeneralTypeIssues)
  /Users/davi/gits/chief-app/test_types.py:30:11 - error: Cases within match statement do not exhaustively handle all values
    Unhandled type: "Literal[OrderStatus.Scheduled]"
    If exhaustive handling is not intended, add "case _: pass" (reportMatchNotExhaustive)
  /Users/davi/gits/chief-app/test_types.py:52:11 - error: Cases within match statement do not exhaustively handle all values
    Unhandled type: "int"
    If exhaustive handling is not intended, add "case _: pass" (reportMatchNotExhaustive)
5 errors, 0 warnings, 0 information 

Steps to Reproduce:

  1. Prepare the code: Save the Python code snippet provided in the "Sandbox Link" section of this GitHub issue (which contains functions handle_order_1, handle_order_2, and handle) into a local file (e.g., test_match_issues.py). This code demonstrates the non-exhaustive matches and incorrect Enum syntax.
  2. Analyze with Pyrefly: Run pyrefly on the created file:
    pyrefly check test_match_issues.py
  3. Observe Pyrefly's output: Notice that Pyrefly does not report any errors for the problematic match statements within the handle_order_1, handle_order_2, or handle functions.
  4. (Optional Comparison) Analyze with Pyright: Run pyright on the same file:
    pyright test_match_issues.py
  5. Observe Pyright's output: Notice that Pyright correctly identifies and reports multiple errors related to non-exhaustiveness and incorrect enum case patterns for the same functions, as detailed in the "Pyright's Output" section of this issue. This highlights the behavior expected from Pyrefly.

Sandbox Link

https://pyrefly.org/sandbox/?code=GYJw9gtgBApgdgV2gSwgBzCALlAooiAKEIGIoB5EZAc2TgEMAbKAZTARAGMYAuKACyxY0AZx4B6cf3oBrZACN4yLPQB0nSOLQBPLPzBwAtBG07DMAB7SEIrMgBuMQ534xOcuNVWkoAFX7IIlAaACYwsBZojJgwQZbWtg7wsUEubh7UUHRQEPRYLlC2eTAQ8Fgi3mQAYphQAAq6+nBQAMyqAIztANQANFBYpnRe9CIiMNgA+nAwjiBZQfT29MiM9PKMvAJCohLiA2hDqiAw9CF6MCFgnBXIYOLw4qtYsVjiIuxcMOIIcMf0LmsNqpBBBGD5-OFLPR0BsgopogB3KD0Y5QGwXfpgfovCIJOyOaajYKudxDHwI5T8eqNAytDoABgA5EFcvkqUVnqU4FhVNSqNRBMyoIppPZbnMABQaEDHThYRjaLJhbnIYDaIawGWYEQASnmUDgYGeIUqfgCQWOGGwAho-EYtvK-WkOB0x2ACqgEoRAQKlswxo9dBCyE4xSCACIwDJw1BaobNeAQEFgLVzmNgiNYjqfCJ9AhGCElSdGB6mO8iyq1U7YuEMM8VUx5iIELEoCm5uB5DYcPtwmlSZ5vIROKsiZQwiAWCosDYJfgkDqeIQoCuoAAlE4hRUAXig4b+W-Dy9XLDSIXzGN34ZEZ4vISPq9YATQaEve9zyBfFyPPgabo9ubsAWRZMB6frYEuZDtLyAByBjmFY9DdkkOR5AUErjuMU55DYqinq454bIWECBCIQw6qaABMvIAJJwNKsounkzwgM0AAGmGTtOuEbqc2gSjqbGeoB+aFooUAcSAE7YTOFS8VubEUT4bRQHRDFuExQjjOxnEybhLDPq+IQCUJEoicB4mSdJ3EVAZn5GYp3hhMAAj0HAIQbBMmAThM7RmTZfC6TZeqGAAfFAcHTEuj6suhHI2IuUBkH+DpQPa0xQJRAAcWTNJgNB0I2UIwjAx6PiuobpkFOFyZu-GJcl2j8oIaV0OElEAJxleVj5oFQ3IStez6xlJ4zhtmPUVZmFCjVxNV4YZFwCXwjXNTg6XhC0lHdZNUB9XQWCDQCnjhN5Y3Zr+TUwO6irmYWyBhKBirgVgkFQNBEXwfESGJI4qFsp61WyXht5ETkpHkU512ue5nlnSAEyUf5NWBbNem6lAYWfVF3WxVSyOyQ1fKpRtUAACz0rlI0FQwzDFVEpW7ZV4RAzxdXRbtq77QNQ2fiNE7jTtq7MzN1nzXZX4hBznN7f1h3hsd1CnbNguPiAyzpgAakwLa4FqIASsA4bo1AADe8UiAAvvqho4Es9r3hdZD+IE+rAG1fSutdAF5sBL0Gli4yJhUhDOTDHkwF5s0TC0BM2KjYuE9L-1xcFyePiLrO1Xx6eTdz8sfmg-PnULU1VWjNkgwRd65z1+eDYXxcgKrk2ZxX4uLVLpflfXCvSCdTeC4QdFYJQU5zLuB1QAAPoUWAgMQq3e7dvv3Y9JbPTAVqvT4H2RQheIoXjnpsQdQm9uDoyQ6H0P9xHEoWFAfAj2P88heFkW8LjaFUhYK3EwKdabUoAAHZKJU3yrQWmERoQM27iLWwBtFzd16nLQaAAJNyEdHZAA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions