Skip to main content

LiteralEnum

LiteralEnum is an experiment/prototype for a proposed Python typing construct: a finite, named set of runtime literals (usually strings) that type checkers can treat as an exhaustive Literal[...] union.

Status: Prototype / exploration for typing-sig discussion. Not an accepted PEP.

Why this exists

In typed Python today you often have to pick one:

  • Enum / StrEnum: great runtime namespace, but APIs want callers to pass enum members instead of raw strings
  • Literal[...]: great static checking, but no runtime namespace/iteration/validation

So people duplicate values or accept str and validate at runtime.

LiteralEnum aims to make the common case a single source of truth.

It’s designed for “protocol token” style values—HTTP methods, event names, command identifiers, config keys—where you want:

  • plain literals at runtime (e.g. "GET"),
  • namespaced constants (e.g. HttpMethod.GET), and
  • static exhaustiveness checking (i.e. the type is equivalent to Literal["GET", "POST", ...]).

Table of Contents


Quickstart

Install

This repo is currently set up as a package under src/.

#python -m venv .venv
#source .venv/bin/activate
pip install literalenum

Realistic Current Usage

from typing import Literal
from literalenum import LiteralEnum

HttpMethodT = Literal["GET", "POST", "DELETE"]
class HttpMethod(LiteralEnum):
    GET = "GET"
    POST = "POST"
    DELETE = "DELETE"

def handle(method: HttpMethodT) -> None:
    print(f"{method=}")

handle("GET")          # this should type-check ✅ 
handle(HttpMethod.GET) # this should type-check ✅ 
handle("git")          # ❌ should be rejected by a type checker

assert HttpMethod.GET == "GET"
assert list(HttpMethod) == ["GET", "POST", "DELETE"]
assert "GET" in HttpMethod
print(HttpMethod.keys())
print(HttpMethod.values())
print(HttpMethod.mapping)

Optimistic Future Usage

from typing import LiteralEnum # NOT valid right now

class HttpMethod(LiteralEnum):
    GET = "GET"
    POST = "POST"
    DELETE = "DELETE"

def handle(method: HttpMethod) -> None:
    print(f"{method=}")

handle("GET")          # the GOAL is that this should type-check ✅ , in reality: it will not unless typecheckers change
handle(HttpMethod.GET) # the GOAL is that this should type-check ✅ , in reality: it will not unless typecheckers change
handle("git")          # ❌ should be rejected by a type checker

assert HttpMethod.GET == "GET"
assert list(HttpMethod) == ["GET", "POST", "DELETE"]
assert "GET" in HttpMethod
print(HttpMethod.keys())
print(HttpMethod.values())
print(HttpMethod.mapping)

Contributing / discussion

Actively looking for feedback! Please comment at https://discuss.python.org/t/proposal-literalenum-runtime-literals-with-static-exhaustiveness/106000

It would be especially helpful if you are familiar with mypy/pright/pylance and have suggestions on how a future Python version could support the type hinting goals.


License

This project is released into the public domain under The Unlicense.

You are free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.

See the LICENSE file for full details.

Metadata

Release files for literalenum 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for literalenum 0.4.0
File Size Uploaded
literalenum-0.4.0.tar.gz 44.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for literalenum 0.4.0
File Interpreter ABI Platform
literalenum-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 74.6 kB

Release files / literalenum-0.4.0.tar.gz

Download URL literalenum-0.4.0.tar.gz
Size 44.7 kB
Tags Source
SHA-256 checksum
How to use checksums
774ba0c3165b7dc71d30f677548c7fc7075050b9a9171fbb352854928f6d5a56
BLAKE2b-256 checksum
How to use checksums
33483825c46b2a3ce3cdbd8d6ac33da01a29dc70b57fa1dbcec9158e6600b26f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 5, 2026.

Transparency log

Release files / literalenum-0.4.0-py3-none-any.whl

Download URL literalenum-0.4.0-py3-none-any.whl
Size 29.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f5253aa807358ece4dc79131bd7b638122a83764704c27054f4b6c0cc24ea133
BLAKE2b-256 checksum
How to use checksums
0b132999be3eb2b6058817c6a86ec01da571ef280814836bca5f7774e18a07c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page