Skip to content

Instantly share code, notes, and snippets.

@9999years
Created July 12, 2021 20:01
Show Gist options
  • Save 9999years/4262df566ccefc3c93070fe7f462597a to your computer and use it in GitHub Desktop.
Save 9999years/4262df566ccefc3c93070fe7f462597a to your computer and use it in GitHub Desktop.
Python TypeMap; a container holding at most one value of a given type
from typing import Type
from typing import TypeVar
class ValueTypeError(ValueError):
"""Raised when a `TypeMap` receives a key-value pair where ``type(value) != key``."""
def __init__(self, key: type, value: object, message: str) -> None:
"""Construct a `ValueTypeError`.
:param key: The key received by a `TypeMap`
:param value: The value received by a `TypeMap`
:param message: A developer-facing description of what went wrong
"""
super().__init__(message)
self.key = key
self.value = value
self.message = message
T = TypeVar("T")
class TypeMap(dict[type, object]):
"""A heterogeneous container holding at most one value of a given type.
A `TypeMap` can hold any number of values, but not more than one for a given
type; it can hold one `int`, one `str`, one `dict`, one `bool`, and so on.
.. seealso:: https://docs.rs/anymap/
"""
def __getitem__(self, k: Type[T]) -> T:
return self[k]
def __setitem__(self, k: Type[T], v: T) -> None:
if k != type(v):
raise ValueTypeError(
k,
v,
f"Attempted to set {k!r} = {v!r}, but value has type {type(v)!r}, not {k!r}",
)
self[k] = v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment