63 lines
1.1 KiB
Python
63 lines
1.1 KiB
Python
"""
|
|
Basic Utilities
|
|
Includes common helper functions for this project
|
|
- Handling optionals
|
|
- getting members by string name
|
|
- typenames
|
|
"""
|
|
|
|
from typing import Any, Callable, TypeVar, TypeAlias, Type, Iterable
|
|
from types import GenericAlias
|
|
|
|
AnyType: TypeAlias = Type | GenericAlias
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
def some_or(data: T | None, alt: T):
|
|
return data if data is not None else alt
|
|
|
|
|
|
N = TypeVar("N")
|
|
M = TypeVar("M")
|
|
|
|
|
|
def some_or_apply(data: N, fn: Callable[[N], M], alt: M):
|
|
return fn(data) if data is not None else alt
|
|
|
|
|
|
def get(obj: Any, attr: str) -> Any:
|
|
return obj.__getattribute__(attr)
|
|
|
|
|
|
def opt_get(obj: Any, attr: str) -> Any | None:
|
|
try:
|
|
return obj.__getattribute__(attr)
|
|
except AttributeError:
|
|
return None
|
|
|
|
|
|
X = TypeVar("X")
|
|
Y = TypeVar("Y")
|
|
|
|
|
|
def firstkey(d: dict[X, Y], val: Y) -> X | None:
|
|
for k, v in d.items():
|
|
if v == val:
|
|
return k
|
|
else:
|
|
return None
|
|
|
|
|
|
def typename(t: AnyType) -> str:
|
|
if t is None:
|
|
return "None"
|
|
else:
|
|
return t.__name__
|
|
|
|
|
|
Z = TypeVar("Z")
|
|
|
|
|
|
def ordered_iter(types: Iterable[Z]) -> list[Z]:
|
|
return sorted(list(types), key=str)
|