diff --git a/docs/examples.rst b/docs/examples.rst index 03d7e38d3..075f4e0c6 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -199,7 +199,6 @@ For that, `attr.asdict` offers a callback that decides whether an attribute shou .. doctest:: - >>> from typing import List >>> from attr import asdict >>> @define @@ -209,7 +208,7 @@ For that, `attr.asdict` offers a callback that decides whether an attribute shou >>> @define ... class UserList: - ... users: List[User] + ... users: list[User] >>> asdict(UserList([User("jane@doe.invalid", "s33kred"), ... User("joe@doe.invalid", "p4ssw0rd")]), @@ -503,12 +502,12 @@ If you don't mind annotating *all* attributes, you can even drop the `field` and >>> @define ... class AutoC: ... cls_var: typing.ClassVar[int] = 5 # this one is ignored - ... l: typing.List[int] = Factory(list) + ... l: list[int] = Factory(list) ... x: int = 1 ... foo: str = "every attrib needs a type if auto_attribs=True" ... bar: typing.Any = None >>> fields(AutoC).l.type - typing.List[int] + list[int] >>> fields(AutoC).x.type >>> fields(AutoC).foo.type @@ -522,18 +521,17 @@ If you don't mind annotating *all* attributes, you can even drop the `field` and The generated ``__init__`` method will have an attribute called ``__annotations__`` that contains this type information. -If your annotations contain strings (e.g. forward references), +If your annotations contain forward references, you can resolve these after all references have been defined by using :func:`attr.resolve_types`. This will replace the *type* attribute in the respective fields. .. doctest:: - >>> import typing >>> from attr import fields, resolve_types >>> @define ... class A: - ... a: typing.List['A'] + ... a: 'list[A]' ... b: 'B' ... >>> @define @@ -541,16 +539,21 @@ This will replace the *type* attribute in the respective fields. ... a: A ... >>> fields(A).a.type - typing.List[ForwardRef('A')] + 'list[A]' >>> fields(A).b.type 'B' >>> resolve_types(A, globals(), locals()) >>> fields(A).a.type - typing.List[A] + list[A] >>> fields(A).b.type +.. note:: + + If you find yourself using string type annotations to handle forward references, wrap the entire type annotation in quotes instead of only the type you need a forward reference to (so ``'list[A]'`` instead of ``list['A']``). + This is a limitation of the Python typing system. + .. warning:: ``attrs`` itself doesn't have any features that work on top of type metadata *yet*. diff --git a/docs/types.rst b/docs/types.rst index 19bb07930..5a71c393e 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -10,12 +10,11 @@ That means that on modern Python versions, the declaration part of the example f .. doctest:: >>> import attr - >>> import typing >>> @attr.s(auto_attribs=True) ... class SomeClass: ... a_number: int = 42 - ... list_of_numbers: typing.List[int] = attr.Factory(list) + ... list_of_numbers: list[int] = attr.Factory(list) >>> sc = SomeClass(1, [1, 2, 3]) >>> sc @@ -71,7 +70,7 @@ To mypy, this code is equivalent to the one above: @attr.s class SomeClass(object): a_number = attr.ib(default=42) # type: int - list_of_numbers = attr.ib(factory=list, type=typing.List[int]) + list_of_numbers = attr.ib(factory=list, type=list[int]) pyright @@ -86,7 +85,7 @@ Given the following definition, ``pyright`` will generate static type signatures @attr.define class SomeClass: a_number: int = 42 - list_of_numbers: typing.List[int] = attr.field(factory=list) + list_of_numbers: list[int] = attr.field(factory=list) .. warning::