-
-
Notifications
You must be signed in to change notification settings - Fork 133
Unquoted forward references in 3.14 don't work #740
Copy link
Copy link
Closed
Description
Minimal reproduction:
# /// script
# requires-python = ">=3.14"
# dependencies = [
# "attrs>=26.1.0",
# "cattrs>=26.1.0",
# ]
# ///
from attrs import define
from cattrs import structure, unstructure
@define
class A:
a: A | None
v = A(None)
print(v)
print(unstructure(v))
print(structure(unstructure(v), A))Output:
A(a=None)
{'a': None}
Traceback (most recent call last):
File "/tmp/asdf/a.py", line 21, in <module>
print(structure(unstructure(v), A))
~~~~~~~~~^^^^^^^^^^^^^^^^^^^
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/converters.py", line 591, in structure
return self._structure_func.dispatch(cl)(obj, cl)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/dispatch.py", line 133, in dispatch_without_caching
res = self._function_dispatch.dispatch(typ)
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/dispatch.py", line 76, in dispatch
return handler(typ)
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/converters.py", line 1314, in gen_structure_attrs_fromdict
return make_dict_structure_fn(
cl,
...<5 lines>...
**attrib_overrides,
)
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/gen/__init__.py", line 831, in make_dict_structure_fn
return make_dict_structure_fn_from_attrs(
attrs,
...<9 lines>...
**kwargs,
)
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/gen/__init__.py", line 450, in make_dict_structure_fn_from_attrs
handler = find_structure_handler(
a, t, converter, _cattrs_prefer_attrib_converters
)
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/gen/_shared.py", line 74, in find_structure_handler
handler = c.get_structure_hook(type, cache_result=False)
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/converters.py", line 609, in get_structure_hook
else self._structure_func.dispatch_without_caching(type)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/dispatch.py", line 134, in dispatch_without_caching
return res if res is not None else self._fallback_factory(typ)
~~~~~~~~~~~~~~~~~~~~~~^^^^^
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/converters.py", line 1062, in <lambda>
structure_fallback_factory: HookFactory[StructureHook] = lambda t: raise_error(
~~~~~~~~~~~^
None, t
^^^^^^^
),
^
File "/home/_/.cache/uv/environments-v2/a-9e6cd7d0ec75859d/lib/python3.14/site-packages/cattrs/fns.py", line 22, in raise_error
raise StructureHandlerNotFoundError(msg, type_=cl)
cattrs.errors.StructureHandlerNotFoundError: Unsupported type: ForwardRef('A | None', is_class=True, owner=<class '__main__.A'>). Register a structure hook for it.One workaround is to put quotes around A | None.
Interestingly, the unquoted version does work in 3.13 with from __future__ import annotations.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels