digital-asset / dazl-client

dazl Ledger API client
Apache License 2.0
10 stars 6 forks source link

python: Redefine Command as a sealed type. #445

Closed da-tanabe closed 9 months ago

da-tanabe commented 10 months ago

This is a bit of an experiment on the ergonomics of defining:

Command = CreateCommand | ExerciseCommand | CreateAndExerciseCommand | ExerciseByKeyCommand

instead of the more traditional:

class Command: ...
class CreateCommand(Command): ...
class ExerciseCommand(Command): ...
class CreateAndExerciseCommand(Command): ...
class ExerciseByKeyCommand(Command): ...

The advantage of using union types is mypy and other Python typecheckers can do a much better job of exhaustiveness checks. The disadvantage is that under Python 3.8 and Python 3.9, using union types breaks isinstance checks. This PR hacks around it by using defining alternate implementations for those two versions of Python, but keeping the typing definition union-based. (Side note: unfortunately Python 3.9 is scheduled for EOL in October 2025 so we'll be stuck with this awkwardness for a while.)

PEP 622, the original proposal for structural pattern matching included sealed types, but PEP 634, which succeeded it, dropped them. That would allowed us to use the best of both options, but sadly it isn't an option.