Skip to content

Python · correctness

no-isinstance-union-chain

python:no-isinstance-union-chain

Use exhaustive pattern matching for dispatch over a local closed class union.

Code
SARJ003
Default
error
Fix
none
Languages
python

Why

An `isinstance` chain does not let a type checker prove that every member of a closed union is handled.

Fix

Replace the chain with `match` cases and pass the unreachable remainder to `assert_never`.

Before / after

Executed by this rule’s unit tests.

Before

Closed local union dispatched with isinstance

app/events.py · focus
class Created: ...
class Deleted: ...

def name(event):
    if isinstance(event, Created):
        return 'created'
    elif isinstance(event, Deleted):
        return 'deleted'
    else:
        raise AssertionError

After

Closed local union dispatched with match

app/events.py · focus
from typing import assert_never

class Created: ...
class Deleted: ...

def name(event):
    match event:
        case Created():
            return 'created'
        case Deleted():
            return 'deleted'
        case unreachable:
            assert_never(unreachable)

Limits

  • The rule requires at least two locally defined class arms over the same expression and a terminal fallback.
  • Builtin, imported, abstract collection, and open-ended dispatch types are excluded.