Skip to content

Structure when input is already partially structured #78

Open
@nathanielford

Description

@nathanielford
  • cattrs version: 0.9.0
  • Python version: 3.7.5
  • Operating System: Mac OSX

Description

I am attempting to structure a blob of data into a recursive structure, where part of the blob has already been structured. When it reaches a key that already has a structured value, it errors out. After reading through the documentation it's unclear how to get around this issue.

What I would expect to happen is if a given key already has (valid) structured data, it includes it as is, rather than attempting to (and failing to) structure it.

I'm not sure if I am missing an obvious workaround (converter or hook?), or if this would require a PR to run a check of some sort before attempting to structure a sub-element.

What I Did

This is a minimal example:

from attr import dataclass
from cattr import structure, unstructure

@dataclass(auto_attribs=True)
class B:
    name: str


@dataclass(auto_attribs=True)
class A:
    name: str
    subber: B


dx = {
    "name": "alphas",
    "subber": {
        "name": "subclass"
    }
}

a = structure(dx, A)
print(a)
b = structure(dx.get("subber"), B)
print(b)
dy = {
    "name": "tau",
    "subber": unstructure(b)
}
a2 = structure(dy, A)
print(a2)
dz = {
    "name": "omega",
    "subber": b
}
a3 = structure(dz, A)

The above produces the following output:

A(name='alphas', subber=B(name='subclass'))
B(name='subclass')
A(name='tau', subber=B(name='subclass'))
Traceback (most recent call last):
  File "/Users/nford/Library/Preferences/IntelliJIdea2019.2/scratches/dc.py", line 46, in <module>
    a3 = structure(dz, A)
  File "/Users/nford/echelon/rolevp/echelon/.venv/lib/python3.7/site-packages/cattr/converters.py", line 178, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
  File "/Users/nford/echelon/rolevp/echelon/.venv/lib/python3.7/site-packages/cattr/converters.py", line 298, in structure_attrs_fromdict
    conv_obj[name] = dispatch(type_)(val, type_)
  File "/Users/nford/echelon/rolevp/echelon/.venv/lib/python3.7/site-packages/cattr/converters.py", line 285, in structure_attrs_fromdict
    conv_obj = obj.copy()  # Dict of converted parameters.
AttributeError: 'B' object has no attribute 'copy'

But what I am hoping to achieve is:

A(name='alpha', subber=B(name='subclass'))
B(name='subclass')
A(name='tau', subber=B(name='subclass'))
A(name='omega', subber=B(name='subclass'))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions