attrs icon indicating copy to clipboard operation
attrs copied to clipboard

TypeError resolving types when field name shadows builtin type

Open chrisguillory opened this issue 3 years ago • 1 comments

The following Python 3.10 code fails.

from __future__ import annotations
import attr

@attr.s(auto_attribs=True, slots=False)
class FloatValue:
    float: float = None

@attr.s(auto_attribs=True, slots=True)
class FloatValueSlots:
    float: float = None

attr.resolve_types(FloatValue)  # succeeds
attr.resolve_types(FloatValueSlots)  # fails

with:

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    attr.resolve_types(FloatValueSlots)
  File ".venv/lib/python3.10/site-packages/attr/_funcs.py", line 412, in resolve_types
    hints = typing.get_type_hints(cls, globalns=globalns, localns=localns)
  File "python/3.10.4/lib/python3.10/typing.py", line 1832, in get_type_hints
    value = _eval_type(value, base_globals, base_locals)
  File "python/3.10.4/lib/python3.10/typing.py", line 327, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "python/3.10.4/lib/python3.10/typing.py", line 693, in _evaluate
    type_ = _type_check(
  File "python/3.10.4/lib/python3.10/typing.py", line 176, in _type_check
    raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Forward references must evaluate to types. Got <member 'float' of 'FloatValueSlots' objects>.

I believe a workaround can be to use builtins.float, but wanted to flag to see if support for this use case should be added to attr.resolve_types. Thanks for attrs!

Edit: Another workaround is to set the local namespace.

attr.resolve_types(FloatValueSlots, local_ns={})  # succeeds

chrisguillory avatar May 28 '22 15:05 chrisguillory

Oof yeah I don't think we can do anything about this internally? Glad to have a Google-able issue with a workaround in any case. :)

hynek avatar May 30 '22 12:05 hynek