from dataclasses import dataclass
from datetime import date, datetime
from enum import Enum
from typing import TYPE_CHECKING, Generic, List, Literal, Tuple, Type, TypeVar, Union
from typing_extensions import TypeAlias
from latch.registry.record import Record
from latch.registry.upstream_types.types import DBType
from latch.registry.upstream_types.values import EmptyCell
from latch.types.directory import LatchDir
from latch.types.file import LatchFile
if not TYPE_CHECKING:
try:
from enum import StrEnum
except ImportError:
class StrEnum(str, Enum): ...
else:
class StrEnum(str, Enum): ...
[docs]@dataclass(frozen=True)
class InvalidValue:
"""Registry :class:`Record` value that failed validation."""
raw_value: str
"""User-provided string representation of the invalid value.
May be `""` (the empty string) if the value is missing but the column is required.
"""
RegistryPrimitivePythonValue: TypeAlias = Union[
str,
datetime,
date,
int,
float,
LatchFile,
LatchDir,
None,
bool,
]
RegistryPythonValue: TypeAlias = Union[
RegistryPrimitivePythonValue,
Record,
List["RegistryPythonValue"],
]
RecordValue: TypeAlias = Union[RegistryPythonValue, EmptyCell, InvalidValue]
[docs]@dataclass(frozen=True)
class Column:
"""Registry :class:`Table` column definition.
:meth:`Table.get_columns` is the typical way to get a :class:`Column`.
"""
key: str
"""Unique identifier within the table. Not globally unique."""
type: Union[Type[RegistryPythonValue], Type[Union[RegistryPythonValue, EmptyCell]]]
"""Python equivalent of the stored column type."""
# fixme(maximsmol): deal with defaults
# default: Union[RegistryPythonValue, EmptyCell]
upstream_type: DBType
"""Raw column type.
Used to convert between Python values and Registry values.
"""
RegistryEnumDefinitionArg = TypeVar("RegistryEnumDefinitionArg", bound=Tuple[str, ...])
[docs]class RegistryEnumDefinition(Generic[RegistryEnumDefinitionArg]):
def __new__(cls, *values: str):
return RegistryEnumDefinition[Tuple[tuple(Literal[v] for v in values)]]
LinkedRecordTypeArg = TypeVar("LinkedRecordTypeArg", bound=str)
[docs]class LinkedRecordType(Generic[LinkedRecordTypeArg]):
def __new__(cls, id: str):
return LinkedRecordType[Literal[id]]
RegistryPrimitivePythonType: TypeAlias = Union[
Type[str],
Type[int],
Type[float],
Type[date],
Type[datetime],
Type[bool],
Type[LatchFile],
Type[LatchDir],
Type[StrEnum],
Type[RegistryEnumDefinition],
Type[LinkedRecordType],
]
RegistryPythonType: TypeAlias = Union[
RegistryPrimitivePythonType,
Type[List[LatchFile]],
Type[List[LatchDir]],
Type[List[LinkedRecordType]],
]