Skip to content

simon-ging/typedattr

Repository files navigation

typedattr

build 3.7 status build 3.9 status coverage version

Deprecated:

  • Attribute parsing capabilities have been moved to typedparser
  • Other utilities have been moved to packg
  • This code and pypi package may be deleted at some point.

Typechecking and conversion utility for attrs

Parses a dictionary into an attrs instance. Contains other generic object, type and cache utilities.

Install

Requires python>=3.7

Note: 0.2 breaks some backwards compatibility. Use 0.1 or update your code.

pip install typedattr

Quickstart

Define the class hierarchy and parse the input using attrs_from_dict:

from attrs import define
from typing import Optional
from typedattr import attrs_from_dict

@define
class Cfg:
    foo: int = 12
    bar: Optional[int] = None

print(attrs_from_dict(Cfg, {"foo": 1, "bar": 2}))
# Cfg(foo=1, bar=2)


@define
class CfgNested:
    sub_cfg: Cfg = None

print(attrs_from_dict(CfgNested, {"sub_cfg": {"foo": 1, "bar": 2}}))
# CfgNested(sub_cfg=Cfg(foo=1, bar=2))

Features

  • Nested checking and conversion of python standard types
  • Supports old and new style typing (e.g. typing.List and list)
  • Supports positional and keyword arguments in classes
  • Can also typecheck existing attrs instances
  • Allows custom conversions, by default converts source type str to target type Path and int to float
  • Allows to redefine which objects will be recursed into, by default recurses into standard containers (list, dict, etc.)
  • @definenumpy decorator for equality check if the instances contains numpy arrays

Strict mode (default)

  • Convert everything to the target type, e.g. if the input is a list and the annotation is a tuple, the output will be a tuple
  • Raise errors if types cannot be matched, there are unknown fields in the input or abstract annotation types are used (e.g. Sequence)

Non-strict mode

Enabled by calling attrs_from_dict with strict=False

  • No conversion except for creating the attrs instance from the dict
  • Ignore silently if types cannot be matched or abstract annotation types are used
  • Unknown fields in the input will be added to the attrs instance if possible (see the hint below about slots)

Skip unknowns

Set skip_unknowns=True to ignore all unknown input fields.

Hints

The following behaviour stems from the attrs package:

  • New attributes cannot to be added after class definition to an attrs instance, unless it is created with @define(slots=False) Explanation
  • Untyped fields or "ClassVar" typed fields will be ignored by @attrs.define and therefore also by this library.

Other utilities in the package

  • Const: An alternative to enum.Enum for defining constants
  • cacheutils: Cache objects to disk / to memory
  • objutils: Various utilities like nested modification of dicts
  • Type definitions and other utilities

Install locally and run tests

Clone repository and cd into, then:

pip install -e .
pip install -U pytest pytest-cov pylint
pylint typedattr

# run tests for python>=3.7
python -m pytest --cov
pylint tests

# run tests for python>=3.9
python -m pytest tests tests_py39 --cov
pylint tests 
pylint tests_py39

Alternatives

This library should be useful for off-the-shelf typechecking and conversion of dicts to attrs instances.

For more complex or other related use cases there are many alternatives: cattrs, attrs-strict, pydantic, dataconf, omegaconf to name a few.

About

Typed conversion of dictionaries to attrs instances

Resources

License

Stars

Watchers

Forks

Packages

No packages published