Skip to content

0.58.0 regression: false positive bad-return #2895

@jorenham

Description

@jorenham

The following typestats code started reported an error after upgrading pyrefly from 0.57.1 to 0.58.0 (jorenham/typestats#335):

def key(self, index: int, /) -> int | str:
    match self.kind:
        case ParamKind.POSITIONAL_ONLY:
            return index
        case ParamKind.KEYWORD_ONLY | ParamKind.POSITIONAL_OR_KEYWORD:
            return self.name
        case ParamKind.VAR_POSITIONAL:
            return "*"
        case ParamKind.VAR_KEYWORD:
            return "**"

where self.kind: ParamKind is an enum defined as follows:

class ParamKind(StrEnum):
    # matches inspect.Parameter.kind
    POSITIONAL_ONLY = "positional-only"
    POSITIONAL_OR_KEYWORD = "positional or keyword"
    VAR_POSITIONAL = "variadic positional"
    KEYWORD_ONLY = "keyword-only"
    VAR_KEYWORD = "variadic keyword"
ERROR Function declared to return `int | str`, but one or more paths are missing an explicit `return` [bad-return]
   --> src/typestats/analyze.py:222:37
    |
222 |     def key(self, index: int, /) -> int | str:
    |                                     ^^^^^^^^^
    |
 INFO 1 error (2 suppressed)
error: Recipe `typecheck` failed on line 13 with exit code 1

See https://github.com/jorenham/typestats/actions/runs/23535046261/job/68508003477?pr=335 for details.

AS you cans see, this method only returns int or str, because all enum variants are handled by the match statement, so it will never return None.

If I add an additional case _: assert_never(self.kind), the error disappears (and no new ones appear either).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions