Skip to content

attrs doesn't recognize ClassVar if not imported in Python 3.14 #1575

Description

@FlyingWolFox

The following code

from typing import TYPE_CHECKING

import attrs

if TYPE_CHECKING:
    from typing import ClassVar

@attrs.define
class T:
    t: ClassVar[str]

T()

results in:

Traceback (most recent call last):
  File "/tmp/test.py", line 12, in <module>
    T()
    ~^^
TypeError: T.__init__() missing 1 required positional argument: 't'

Since the if TYPE_CHECKING block doesn't run, ClassVar isn't defined and attrs can't evaluate the ForwardRef or doesn't recognize ClassVar:

>>> attrs.fields_dict(T)["t"]
Attribute(name='t', default=NOTHING, validator=None, repr=True, eq=True, eq_key=None, order=True, order_key=None, hash=None, init=True, metadata=mappingproxy({}), type=ForwardRef('ClassVar[str]', is_class=True, owner=<class '__main__.T'>), converter=None, kw_only=False, inherited=False, on_setattr=None, alias='t')

Before Python 3.14, T's definition would only run if you used a string annotation or from __future__ import annotations (which if used with 3.14, the above code runs fine), but with the new annotations behavior the class definition runs fine and this error appears. This is actually issue for dataclasses too, as I get the same error with them.

I'm not sure if this is fixable, but decided to report it, because it catches you by surprise

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions