Last active
January 23, 2023 23:50
-
-
Save carymrobbins/097f18904d67e82430ea1946b401a6dd to your computer and use it in GitHub Desktop.
Example CSV row deserializer using Python dataclasses
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
from dataclasses import dataclass, fields, is_dataclass | |
from typing import TypeVar | |
@dataclass | |
class Widget: | |
name: str | |
amount: int | |
T = TypeVar('T') | |
def deserialize_csv_row(typ: type[T], row: str) -> T: | |
if not is_dataclass(typ): | |
raise TypeError( | |
f'Cannot deserialize type from CSV row: {type(x)}' | |
) | |
values = [] | |
for cells in csv.reader([row]): | |
x_fields = fields(x) | |
x_fields_len = len(x_fields) | |
cells_len = len(cells) | |
if x_fields_len != cells_len: | |
raise ValueError( | |
f'Row length mismatch: type {typ} expects {x_fields_len} cells ' | |
f'but got {cells_len}' | |
) | |
for f, cell in zip(x_fields, cells): | |
values.append(deserialize_csv_cell(f.type, cell)) | |
return typ(*values) | |
def deserialize_csv_cell(typ: type[T], cell: str) -> T: | |
if typ is str: | |
return cell | |
if typ is int: | |
return int(cell) | |
raise TypeError( | |
f'Cannot deserialize type from CSV cell: type was {type(x)}' | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment