def test_derive_typeddict_dataclass_simple(): DC = make_datacls("A", (("a", str), ("b", int), ("c", float))) TD = derive_typeddict("TD", DC) annotations = TD.__annotations__ assert annotations["a"] is str assert annotations["b"] is int assert annotations["c"] is float
def dataclass_codec( dataclass: Any, columns: Sequence[str] = None, fields: Mapping[str, str] = None, codecs: Mapping[str, Any] = None, ): """ Return a codec that encodes/decodes a dataclass to/from a CSV row. A CSV row is represented as a list of strings. Parameters: • dataclass: dataclass type to encode/decode • columns: ordered column names • fields: mapping between row columns and dataclass fields • codecs: mapping between columns and codecs The columns parameter specifies the names of CSV columns, and the order they are encoded in a row. If the columns parameter is omitted, then columns will be all dataclass fields, in the order they are defined in the dataclass. The fields mapping specifies the mapping between column names and dictionary keys. If no mapping for a given column is specified, then the column will map to the field name of the same name. The codecs mapping specifies which codecs are used to encode columns. If no mapping for a given column is provided, then the default codec for its associated field is used. """ td_codec = typeddict_codec(derive_typeddict("TD", dataclass), columns=columns, keys=fields, codecs=codecs) class DataclassRowCodec(Codec[dataclass, list[str]]): """Encodes/decodes a dataclass value to/from a CSV row.""" def __init__(self, columns: Sequence[str]): self.columns = columns def encode(self, value: dataclass) -> list[str]: """ Encode from dataclass value to CSV row. If a field value is None, it will be represented in a column as an empty string. """ return td_codec.encode(dataclasses.asdict(value)) def decode(self, values: list[str]) -> dataclass: """ Decode from CSV row to dataclass value. If a column to decode contains an empty string value, it will be represented as None if the associated field is optional. """ return dataclass(**td_codec.decode(values)) return DataclassRowCodec(td_codec.columns)
def test_derive_typeddict_annotated_dataclass(): DC = make_datacls("A", (("a", str), )) TD = derive_typeddict("TD", Annotated[DC, "annotated"]) assert TD.__annotations__.keys() == DC.__annotations__.keys()
def test_derive_typeddict_dataclass_exclude(): DC = make_datacls("A", (("a", str), ("b", int), ("c", float))) TD = derive_typeddict("TD", DC, exclude={"a"}) assert TD.__annotations__.keys() == {"b", "c"}