type_enum: Concise sum types in Python
Sum types (aka tagged unions) in the style of Rust's enums, with pattern matching and (with the mypy plugin) exhaustiveness checking.
Basic usage
from type_enum import Field, TypeEnum
class BgColor(TypeEnum):
transparent: Field[()]
name: Field[str]
rgb: Field[int, int, int]
hsv: Field[int, int, int]
background_color: BgColor = BgColor.rgb(39, 127, 168)
assert isinstance(background_color, BgColor)
assert not isinstance(BgColor.rgb, BgColor)
match background_color:
case BgColor.transparent(): # unfortunately needs the parentheses
print("no color")
case BgColor.name(color_name):
print(f"color name: {color_name}")
case BgColor.rgb(red, green, blue):
print(f"RGB: {red}, {green}, {blue}")
case BgColor.hsv(hue, saturation, value):
print(f"HSV: {hue}, {saturation}, {value}")
# will print "RGB: 39, 127, 168"
Installation
Requires Python >= 3.11 (because features from PEP 646 are required)
pip install type-enum
And for the mypy plugin (requires mypy >= 1.8):
pip install type-enum-plugin
Then register the plugin with
[tool.mypy]
plugins = "type_enum_plugin"
Advanced usage
Exhaustiveness checking
To make exhaustiveness checking work, you first need the mypy plugin, and then you also need to use the special T attribute that is synthesized for each TypeEnum:
from type_enum import Field, TypeEnum
class Color(TypeEnum):
transparent: Field[()]
name: Field[str]
def f(color: Color.T) -> str:
match color:
case Color.transparent():
return "no color"
case Color.name(color_name):
return color_name
assert f(Color.transparent()) == "no color"
The requirement to use .T is a limitation of the mypy plugin, and hopefully will be removed in the future.
Generics
The .T attribute can also be used to specify type arguments for generic TypeEnums:
from typing import Generic, Tuple, Type, TypeVar
from type_enum import Field, TypeEnum
U = TypeVar("U")
class Maybe(TypeEnum, Generic[U]):
nothing: Field[()]
some: Field[U]
a = Maybe.some[int](3)
def f(x: Maybe.T[int]) -> int:
match x:
case Maybe.some(y):
return y
case Maybe.nothing():
return 0
assert f(a) == 3
Metadata
Release files for type-enum 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| type_enum-0.5.0.tar.gz | 7.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| type_enum-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.8 kB
Release files / type_enum-0.5.0.tar.gz
| Download URL | type_enum-0.5.0.tar.gz |
|---|---|
| Size | 7.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c9dcb0e4c302c7f44648ae656fce91a4a620b071b5cee3d58f64cbbf902a498a
|
|
BLAKE2b-256 checksum How to use checksums |
de3a55c2d7426962b9caefb6995884fcd5ee4cd7905cb698c12d0c12ebdbec69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.12.1
|
Release files / type_enum-0.5.0-py3-none-any.whl
| Download URL | type_enum-0.5.0-py3-none-any.whl |
|---|---|
| Size | 5.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f9482abae65eb80f2ec7fc4f52a1da6172775fd2b33daa60a8c1da5f1370fa95
|
|
BLAKE2b-256 checksum How to use checksums |
86e52c7b9ad4971be8c1a6af0dac887ce2e6789f6da2d7919171a2c68bcdb47e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.12.1
|