{"id":589,"library":"typedload","title":"typedload","description":"typedload is a Python library designed to load and dump data from JSON-like formats into statically typed data structures. It supports standard Python types such as NamedTuples, dataclasses, sets, and enums, enforcing a schema by performing type checks and casts as needed. It also facilitates dumping typed data structures back to JSON-like dictionaries and lists. This library is particularly useful for projects leveraging Mypy, as it guarantees data conformity to specified schemas at runtime. It is actively maintained, with frequent releases; the current version is 2.40.","status":"active","version":"2.40","language":"python","source_language":"en","source_url":"https://github.com/ltworf/typedload","tags":["typing","json","schema validation","dataclass","namedtuple","type hints","data loading"],"install":[{"cmd":"pip install typedload","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Used for defining typed classes, an alternative to dataclasses or NamedTuple. Not strictly required if using stdlib types.","package":"attrs","optional":true}],"imports":[{"symbol":"load","correct":"from typedload import load"},{"symbol":"dump","correct":"from typedload import dump"}],"quickstart":{"code":"import dataclasses\nfrom typing import NamedTuple, List\nfrom typedload import load, dump\n\n@dataclasses.dataclass\nclass User:\n    username: str\n    shell: str = 'bash'\n    sessions: List[str] = dataclasses.field(default_factory=list)\n\nclass Logins(NamedTuple):\n    users: List[User]\n\ndata_from_json = {\n    'users': [\n        { 'username': 'salvo', 'shell': 'bash', 'sessions': ['pts/4', 'tty7', 'pts/6'] },\n        { 'username': 'lop' }\n    ]\n}\n\n# Load the dictionary into typed data structures\nloaded_data: Logins = load(data_from_json, Logins)\nprint(f\"Loaded Data: {loaded_data}\")\nassert loaded_data.users[0].username == 'salvo'\nassert loaded_data.users[1].shell == 'bash' # Default value applied\n\n# Dump the typed data structure back to a dictionary\ndumped_data = dump(loaded_data)\nprint(f\"Dumped Data: {dumped_data}\")\nassert dumped_data['users'][0]['username'] == 'salvo'","lang":"python","description":"This example demonstrates how to define typed data structures using dataclasses and NamedTuple, then use `typedload.load` to convert a dictionary (typically from JSON) into these structures. It also shows `typedload.dump` for converting them back to a dictionary. Default values for fields are automatically handled during loading."},"warnings":[{"fix":"Prefer using tagged unions with `typing.Literal` to explicitly differentiate types. If untagged unions are necessary, ensure data unambiguously maps to a single type or be aware of potential non-deterministic behavior. Use `load(data, SomeUnion, uniondebugconflict=True)` for debugging.","message":"Untagged Unions can lead to non-deterministic loading results if input data matches multiple types within the union. While `typedload` supports untagged unions, it's safer and faster to use `Literal` fields to tag unions for explicit type identification. For debugging, `uniondebugconflict=True` can detect such ambiguities but incurs a performance cost.","severity":"gotcha","affected_versions":"2.x"},{"fix":"Always provide `None` explicitly for `Optional[T]` fields in input data if the value is `None`. For truly optional fields that can be omitted, define a default value (e.g., `field: str = 'default'` or `field: List[str] = dataclasses.field(default_factory=list)`).","message":"The distinction between `typing.Optional[T]` and a field with a default value is important. `Optional[T]` means the field *must* be present in the input data but can be `None`. A field with a default value, however, can be entirely *omitted* from the input data, and `typedload` will use the default. Misunderstanding this can lead to unexpected validation errors.","severity":"gotcha","affected_versions":"2.x"},{"fix":"Always specify the type argument for generic collections like `list`. Use `my_list: list[Any]` or `my_list: list[str]` (or any specific type) instead of `my_list: list`.","message":"Directly using a bare `list` (e.g., `my_list: list`) as a type annotation for loading into a dataclass field will cause a crash. This annotation is treated differently by `typedload` and is not equivalent to `list[typing.Any]` at runtime.","severity":"breaking","affected_versions":"2.x"},{"fix":"When dumping `datetime` objects and desiring ISO 8601 strings, ensure `isodates=True` is passed to the `dump` function (e.g., `typedload.dump(obj, isodates=True)`). If relying on the old integer list format, be aware it may be removed in future major versions.","message":"Since version 2.23, the default behavior for dumping `datetime.date`, `datetime.time`, and `datetime.datetime` objects has shifted. The previous method of dumping them as a list of integers (e.g., `[year, month, day, ...]`) is now deprecated. The recommended way is to dump them as ISO 8601 strings.","severity":"deprecated","affected_versions":">=2.23"},{"fix":"If all fields must always be present in the dumped output, regardless of whether their value matches a default, ensure that `typedload.dump` is configured to include all fields (e.g., check for an `omit_defaults=False` or similar option). Alternatively, if possible, avoid assigning default values to fields that must always be present in the serialized output.","message":"When dumping dataclass instances, fields whose values match their declared default values in the dataclass definition may be implicitly omitted from the serialized output. This behavior can lead to incomplete data being serialized, even if the field was explicitly populated during loading, if its value happens to match the default. This is often done to reduce payload size but can be unexpected.","severity":"gotcha","affected_versions":"2.x"}],"env_vars":null,"last_verified":"2026-05-12T16:22:32.958Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"pip install typedload","cause":"The 'typedload' library has not been installed in the current Python environment.","error":"ModuleNotFoundError: No module named 'typedload'"},{"fix":"Ensure the input data's type or value is compatible with the expected type for the field or target class.","cause":"The input data provided to `typedload.load()` cannot be converted to the target type specified.","error":"TypeError: 'hello' is not an int"},{"fix":"Ensure the input dictionary contains all required keys for the target type.","cause":"The input dictionary provided to `typedload.load()` is missing a required key for the target type (e.g., TypedDict, dataclass).","error":"KeyError: 'b'"},{"fix":"from typedload.exceptions import TypedloadException","cause":"The `TypedloadException` class is located within the `typedload.exceptions` submodule, not directly in the top-level `typedload` package.","error":"ImportError: cannot import name 'TypedloadException' from 'typedload'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":"2.40","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"18.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"18.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0,"mem_mb":0.5,"disk_size":"18M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.5,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.6,"disk_size":"19.9M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.6,"disk_size":"19.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"20M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"11.7M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"11.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.7,"disk_size":"11.5M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.7,"disk_size":"11.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.4,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"17.5M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"17.5M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.8,"import_time_s":0,"mem_mb":0.4,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.4,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}