Closed
Description
Versions
- cattrs version: 23.1.2
- Python version: 3.11
- Operating System: Ubuntu 22.03
Description
Hi, first of all I want to thank you for adding the support for structuring and destructuring of Final
attributes in cattrs
23. I've been using it throughout my codebase ever since and it's proven very useful. Unfortunately, I might have run into a bug of this new feature. In particular, cattrs
fails when attempting to structure Final
sequences.
Example
The following minimal example
from typing import Final
import attr
from cattrs.preconf.json import JsonConverter
@attr.s(init=True)
class Foo:
foo: Final[list[float]] = attr.ib()
converter = JsonConverter()
converter.loads('{ "foo": [0.12] }', Foo)
results in the error
---------------------------------------------------------------------------
ClassValidationError Traceback (most recent call last)
Cell In[2], line 11
8 foo: Final[list[float]] = attr.ib()
10 converter = JsonConverter()
---> 11 converter.loads('{ "foo": [0.12] }', Foo)
File ... python3.11/site-packages/cattrs/preconf/json.py:19, in JsonConverter.loads(self, data, cl, **kwargs)
18 def loads(self, data: Union[bytes, str], cl: Type[T], **kwargs: Any) -> T:
---> 19 return self.structure(loads(data, **kwargs), cl)
File ... python3.11/site-packages/cattrs/converters.py:334, in BaseConverter.structure(self, obj, cl)
332 def structure(self, obj: Any, cl: Type[T]) -> T:
333 """Convert unstructured Python data structures to structured data."""
--> 334 return self._structure_func.dispatch(cl)(obj, cl)
File <cattrs generated structure __main__.Foo>:9, in structure_Foo(o, _, __cl, __c_cve, __c_avn, __c_structure_foo, __c_type_foo)
7 e.__notes__ = getattr(e, '__notes__', []) + [__c_avn("Structuring class Foo @ attribute foo", "foo", __c_type_foo)]
8 errors.append(e)
----> 9 if errors: raise __c_cve('While structuring ' + 'Foo', errors, __cl)
10 try:
11 return __cl(
ClassValidationError: While structuring Foo (1 sub-exception)
The same issue happens also if a tuple
or a generic Sequence
are used instead of a list
. Moreover, if the Final
from the definition of Foo
is removed, then the json string is structured correctly and without errors.