A hack for writing switch statements in type annotations for Python.
You most definitely should not use this in any real capacity, for any project, ever. It is fun as a proof-of-concept, however. This is done solely for entertainment purposes.
Switch is the switch-case implementation, used as a context manager. Annotating the designated keyword (defaulting to case) defines cases.
Cases are in the form:
[keyword]: (*case identifier[s],
statements
)
If statements is a tuple, the output value of the switch statement is what the last element evaluates to. If statements is any other type, it itself is evaluated as the output value.
Simplest case (ha):
from __future__ import annotations
from annotation_switch import __annotations__, Switch
switch_case = Switch(3)
with switch_case:
case: (0, 1, 2, (
print("Zero, One, or Two."),
3 < 3 # False
))
case: (3, (
print("Three."),
3 == 3 # True
))
print(switch_case.output) # TrueCase with default:
from __future__ import annotations
from annotation_switch import *
switch_case = Switch(5)
with switch_case:
case: (0, 1, 2, (
print("Zero, One, or Two."),
5 < 3 # False
))
case: (3, (
print("Three."),
5 == 3 # False
))
case: ("default", (
print("What comes after 3?"),
5 > 3 # True
))
print(switch_case.output) # TrueCase with error being raised when case is not resolved:
from __future__ import annotations
from annotation_switch import __annotations__, Switch, CONFIG
CONFIG.defaults_to_none = False
switch_case = Switch("pineapple")
with switch_case:
case: ("apple", (
print("fruit"),
"fruit"
))
case: ("pine", (
print("tree"),
"tree"
))
# raises SwitchCaseNotValidError("pineapple")Note: After the switch statement is exited at the resolution of the context manager, the Switch object is converted to an OutputWrapper holding only an output member. This is to encourage the user to not reuse the Switch object, which might have unintended effects.
Also note: __annotations__ is a required import for the package to function. You can equivalently use the import from annotation_switch import * which will perform the import automatically.
Most notably, switch cases can only be used at module-level1, and at a minimum from annotation_switch import __annotations__, Switch is required for the module to be able to work as expected.
There are many switch-case implementations for Python, most recently Python added structural pattern matching in 3.10. If you're looking for a backwards-compatible switch-case implementation that's tested and readable, try my py_switch implementation.
Footnotes
-
Annotations only trigger updates at module-level. Python discards annotations set within function declarations. ↩