python-attrs / python-attrs/cattrs

Importing `annotations` from `__future__` causes a StructureHandlerNotFoundError

Open
#293 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.1k
Forks
159
Avg merge
12h 21m
Merged PRs (30d)
6

Description

  • cattrs version: 22.1.0
  • Python version: 3.10.1
  • Operating System: Ubuntu
Description

Importing annotations from __future__ causes a StructureHandlerNotFoundError, whereas my registered structure function works fine when I do not import annotations from __future__.

What I Did

I ran a Python script with the following contents:

# from __future__ import annotations

from typing import Any

import attr
from cattrs import Converter


@attr.frozen
class C:
    a: int


def structure_int(val: str, type_: Any) -> int:
    return int(val)


c = Converter()
c.register_structure_hook(int, structure_int)

result = c.structure_attrs_fromtuple(["1"], C)
print(result)

When the first line is commented out, it works fine and prints the following as expected:

C(a=1)

When the first line is not commented out, it causes the following error:

Traceback (most recent call last):
  File ".../.config/JetBrains/PyCharmCE2022.1/scratches/scratch_7.py", line 21, in <module>
    result = c.structure_attrs_fromtuple(["1"], C)
  File ".../.pyenv/versions/edgar-3.10/lib/python3.10/site-packages/cattrs/converters.py", line 403, in structure_attrs_fromtuple
    converted = self._structure_attribute(a, value)
  File ".../.pyenv/versions/edgar-3.10/lib/python3.10/site-packages/cattrs/converters.py", line 422, in _structure_attribute
    return self._structure_func.dispatch(type_)(value, type_)
  File ".../.pyenv/versions/edgar-3.10/lib/python3.10/site-packages/cattrs/converters.py", line 344, in _structure_error
    raise StructureHandlerNotFoundError(msg, type_=cl)
cattrs.errors.StructureHandlerNotFoundError: Unsupported type: 'int'. Register a structure hook for it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the example with and without from __future__ import annotations, then inspect cattrs/converters.py around structure_attrs_fromtuple, _structure_attribute, and _structure_error from the traceback. Trace how the attribute annotation is resolved and why the registered int hook is not reached. Done means the future-annotations variant structures C(a=1) and the regression is covered by a test.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.