Skip to main content

Type-containing enumeration

Project description

Typenum

This package provide a way to create typed enumerations.

Install

  • pip install typenum
  • pip install typenum[pydantic] - install with pydantic >=2.9

Quickstart

Without pydantic

from typenum import TypEnum, TypEnumContent

class SimpleEnum(TypEnum[TypEnumContent]):
    A: type["SimpleEnum[NoValue"]
    Int: type["SimpleEnum[int]"]

# isinstance checking
assert isinstance(SimpleEnum.A(...), SimpleEnum)
assert isinstance(SimpleEnum.Int(123), SimpleEnum.Int)
assert not isinstance(SimpleEnum.Int(123), SimpleEnum.A)

# fully pattern-matching
match SimpleEnum.Int(1):
    case SimpleEnum.Int(2):
        a = False
    case SimpleEnum.Int(1):
        a = True
    case SimpleEnum.Int():
        a = True
    case _:
        a = False

assert a

With pydantic

import typing
from dataclasses import dataclass

from pydantic import BaseModel

from typenum import TypEnum, TypEnumContent, NoValue
from typenum.pydantic import TypEnumPydantic, FieldMetadata, Rename
from typing_extensions import Annotated, TypedDict


class Enum(TypEnum[NoValue]):
    V1: type["Enum"]
    V2: type["Enum"]


@dataclass
class TestDataClass:
    a: int


class TestModel(BaseModel):
    b: str


class TestTypedDict(TypedDict):
    tm: TestModel


class SimpleEnum(TypEnumPydantic[NoValue]):
    V1: type["SimpleEnum"]
    V2: type["SimpleEnum"]


class OtherEnum(TypEnumPydantic[TypEnumContent]):
    Int: type["OtherEnum[int]"]
    Int: type["OtherEnum[str]"]


# class MyEnum(TypEnumPydantic[TypEnumContent], variant="key", content="value"): <- adjacently
# class MyEnum(TypEnumPydantic[TypEnumContent], variant="key"): <- internally
class MyEnum(TypEnumPydantic[TypEnumContent]):  # <- externally, default
    # MyEnum.Int(123)
    Int: type["MyEnum[int]"]

    # MyEnum.Str(123)
    Str: type["MyEnum[str]"]

    # MyEnum.Str(OtherEnum.Int(1))
    Other: type["MyEnum[OtherEnum[Any]]"]  # any from OtherEnum variants

    # MyEnum.Str(MyEnum.Int(1)) | MyEnum.Str(MyEnum.Str(1))
    Self: type["MyEnum[MyEnum[Any]]"]  # any from self variants

    # MyEnum.OnlySelf(...) - any parameters skipped, serialized just by name
    NoValue: type["MyEnum[NoValue]"]

    # MyEnum.OnlySelf2(None)
    Optional: type["MyEnum[Optional[bool]]"]

    # MyEnum.List(["1", "2", "3"])
    List: type["MyEnum[list[str]]"]

    # MyEnum.Dict({"key": "value"})
    Dict: type["MyEnum[dict[str, str]]"]
    # TypedDict: type["MyEnum[{"b": str}]"]
    TypedDict: type["MyEnum[TestD]"]  # python doesn`t have inline TypedDict now

    # MyEnum.DC(TestDataClass(a=1))
    DataClass: type["MyEnum[TestDataClass]"]

    # MyEnum.Model(TestModel(b="2"))
    Model: type["MyEnum[TestModel]"]

    # MyEnum.StrTuple(("1", "2")))
    StringTuple: Annotated[type["MyEnum[tuple[str, str]]"], FieldMetadata(rename="just_str_tuple")]
    # or use typenum.pydantic.Rename
    # StrTuple: Annotated[type["MyEnum[tuple[str, str]]"], Rename("some_other_name")]


class FinModel(BaseModel):
    enum: MyEnum


def dump_and_load(e: MyEnum):
    model = FinModel(enum=e)
    json_ = model.model_dump_json()
    print(json_)
    restored = FinModel.model_validate_json(json_)
    assert model == restored


# externally -> {"enum":{"Int":1}} 
# adjacently -> {"enum":{"key":"Int","value":1}}
# internally -> not supported
dump_and_load(MyEnum.Int(1))

# externally -> {"enum":{"Str":"str"}}
# adjacently -> {"enum":{"key":"Str","value":"str"}}
# internally -> not supported
dump_and_load(MyEnum.Str("str"))

# externally -> {"enum":{"List":["list"]}}
# adjacently -> {"enum":{"key":"List","value":["list"]}}
# internally -> not supported
dump_and_load(MyEnum.List(["list"]))

# externally -> {"enum":{"just_str_tuple":["str","str2"]}} 
# adjacently -> {"enum":{"key":"just_str_tuple","value":["str","str2"]}}
# internally -> not supported
dump_and_load(MyEnum.StringTuple(("str", "str2")))

# externally -> {"enum":{"Self":{"Int":1}}} 
# adjacently -> {"enum":{"key":"Self","value":{"key":"Int","value":1}}}
# internally -> not supported
dump_and_load(MyEnum.Self(MyEnum.Int(1)))

# externally -> {"enum":{"DC":{"a":1}}} 
# adjacently -> {"enum":{"key":"DC","value":{"a":1}}}
# internally -> {"enum":{"key":"DC","a":1}}}
dump_and_load(MyEnum.DataClass(TestDataClass(a=1)))

# externally -> {"enum":{"Model":{"b":"test_model"}}} 
# adjacently -> {"enum":{"key":"Model","value":{"b":"test_model"}}}
# internally -> {"enum":{"key":"Model", "b":"test_model"}}
dump_and_load(MyEnum.Model(TestModel(b="test_model")))

# externally -> {"enum":{"TypedDict":{"tm":{"b":"test_model"}}}} 
# adjacently -> {"enum":{"key":"TypedDict","value":{"tm":{"b":"test_model"}}}}
# internally -> {"enum":{"key":"TypedDict","tm":{"b":"test_model"}}}
dump_and_load(MyEnum.TypedDict(TestTypedDict(tm=TestModel(b="test_model"))))

# externally -> {"enum":{"Dict":{"a":"1","b":"2"}}} 
# adjacently -> {"enum":{"key":"Dict","value":{"a":"1","b":"2"}}}
# internally -> not supported
dump_and_load(MyEnum.Dict({"a": "1", "b": "2"}))

# externally -> {"enum":"NoValue"}
# adjacently -> {"enum":{"key":"NoValue"}}
# internally -> {"enum":{"key":"NoValue"}}
dump_and_load(MyEnum.NoValue(...))

# externally -> {"enum":{"Optional":null}} 
# adjacently -> {"enum":{"key":"Optional","value":null}}
# internally -> not supported
dump_and_load(MyEnum.Optional(None))

Other

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typenum-0.3.0.tar.gz (9.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typenum-0.3.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file typenum-0.3.0.tar.gz.

File metadata

  • Download URL: typenum-0.3.0.tar.gz
  • Upload date:
  • Size: 9.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 colorama/0.4.4 importlib-metadata/8.5.0 keyring/24.3.1 pkginfo/1.11.2 readme-renderer/34.0 requests-toolbelt/1.0.0 requests/2.32.3 rfc3986/1.5.0 tqdm/4.57.0 urllib3/2.2.0 CPython/3.10.12

File hashes

Hashes for typenum-0.3.0.tar.gz
Algorithm Hash digest
SHA256 fbd9f07070b093ac045766068bb9255e4672102b5c87e2e483059c5540aec802
MD5 4cb05e96df3fffecc446047b5d3af3c4
BLAKE2b-256 fc5ad06277eac3002902ba0b7491b3a5809952df62e7d6912e16d66b2f5fe4ab

See more details on using hashes here.

File details

Details for the file typenum-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: typenum-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 colorama/0.4.4 importlib-metadata/8.5.0 keyring/24.3.1 pkginfo/1.11.2 readme-renderer/34.0 requests-toolbelt/1.0.0 requests/2.32.3 rfc3986/1.5.0 tqdm/4.57.0 urllib3/2.2.0 CPython/3.10.12

File hashes

Hashes for typenum-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 57dfa011797092b29eb64f9c7a81ccf2faa605e5e88c4a07ca6ddd92f54e0c03
MD5 f825e889794d8a8a5a667a33fa5a2458
BLAKE2b-256 7f87a0e020affedf5a497241ae7a64a27d86b3f1d085e8826a010d11ff664882

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page