diff --git a/changelog.d/782.change.rst b/changelog.d/782.change.rst new file mode 100644 index 000000000..9314ccf29 --- /dev/null +++ b/changelog.d/782.change.rst @@ -0,0 +1 @@ +``ClassVar``\ s are now also detected if they come from `typing-extensions `_. diff --git a/src/attr/_make.py b/src/attr/_make.py index 3b02bbb15..d0a251112 100644 --- a/src/attr/_make.py +++ b/src/attr/_make.py @@ -41,7 +41,12 @@ _tuple_property_pat = ( " {attr_name} = _attrs_property(_attrs_itemgetter({index}))" ) -_classvar_prefixes = ("typing.ClassVar", "t.ClassVar", "ClassVar") +_classvar_prefixes = ( + "typing.ClassVar", + "t.ClassVar", + "ClassVar", + "typing_extensions.ClassVar", +) # we don't use a double-underscore prefix because that triggers # name mangling when trying to create a slot for the field # (when slots=True) diff --git a/tests/test_annotations.py b/tests/test_annotations.py index 203b8ddee..2df6311b2 100644 --- a/tests/test_annotations.py +++ b/tests/test_annotations.py @@ -418,6 +418,18 @@ class C: foo=typing.Optional[typing.Any], ) + @pytest.mark.parametrize("slots", [True, False]) + def test_typing_extensions_classvar(self, slots): + """ + If ClassVar is coming from typing_extensions, it is recognized too. + """ + + @attr.s(auto_attribs=True, slots=slots) + class C: + cls_var: "typing_extensions.ClassVar" = 23 # noqa + + assert_init_annotations(C) + def test_keyword_only_auto_attribs(self): """ `kw_only` propagates to attributes defined via `auto_attribs`.