Modernize docs some more (#885)
* Modernize docs some more * Fix doctest * Tweak docs * Update docs/examples.rst Co-authored-by: Hynek Schlawack <hs@ox.cx>
This commit is contained in:
parent
3833e4f496
commit
bd0d0cc9fe
|
@ -199,7 +199,6 @@ For that, `attr.asdict` offers a callback that decides whether an attribute shou
|
||||||
|
|
||||||
.. doctest::
|
.. doctest::
|
||||||
|
|
||||||
>>> from typing import List
|
|
||||||
>>> from attr import asdict
|
>>> from attr import asdict
|
||||||
|
|
||||||
>>> @define
|
>>> @define
|
||||||
|
@ -209,7 +208,7 @@ For that, `attr.asdict` offers a callback that decides whether an attribute shou
|
||||||
|
|
||||||
>>> @define
|
>>> @define
|
||||||
... class UserList:
|
... class UserList:
|
||||||
... users: List[User]
|
... users: list[User]
|
||||||
|
|
||||||
>>> asdict(UserList([User("jane@doe.invalid", "s33kred"),
|
>>> asdict(UserList([User("jane@doe.invalid", "s33kred"),
|
||||||
... User("joe@doe.invalid", "p4ssw0rd")]),
|
... 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
|
>>> @define
|
||||||
... class AutoC:
|
... class AutoC:
|
||||||
... cls_var: typing.ClassVar[int] = 5 # this one is ignored
|
... cls_var: typing.ClassVar[int] = 5 # this one is ignored
|
||||||
... l: typing.List[int] = Factory(list)
|
... l: list[int] = Factory(list)
|
||||||
... x: int = 1
|
... x: int = 1
|
||||||
... foo: str = "every attrib needs a type if auto_attribs=True"
|
... foo: str = "every attrib needs a type if auto_attribs=True"
|
||||||
... bar: typing.Any = None
|
... bar: typing.Any = None
|
||||||
>>> fields(AutoC).l.type
|
>>> fields(AutoC).l.type
|
||||||
typing.List[int]
|
list[int]
|
||||||
>>> fields(AutoC).x.type
|
>>> fields(AutoC).x.type
|
||||||
<class 'int'>
|
<class 'int'>
|
||||||
>>> fields(AutoC).foo.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.
|
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`.
|
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.
|
This will replace the *type* attribute in the respective fields.
|
||||||
|
|
||||||
.. doctest::
|
.. doctest::
|
||||||
|
|
||||||
>>> import typing
|
|
||||||
>>> from attr import fields, resolve_types
|
>>> from attr import fields, resolve_types
|
||||||
|
|
||||||
>>> @define
|
>>> @define
|
||||||
... class A:
|
... class A:
|
||||||
... a: typing.List['A']
|
... a: 'list[A]'
|
||||||
... b: 'B'
|
... b: 'B'
|
||||||
...
|
...
|
||||||
>>> @define
|
>>> @define
|
||||||
|
@ -541,16 +539,21 @@ This will replace the *type* attribute in the respective fields.
|
||||||
... a: A
|
... a: A
|
||||||
...
|
...
|
||||||
>>> fields(A).a.type
|
>>> fields(A).a.type
|
||||||
typing.List[ForwardRef('A')]
|
'list[A]'
|
||||||
>>> fields(A).b.type
|
>>> fields(A).b.type
|
||||||
'B'
|
'B'
|
||||||
>>> resolve_types(A, globals(), locals())
|
>>> resolve_types(A, globals(), locals())
|
||||||
<class 'A'>
|
<class 'A'>
|
||||||
>>> fields(A).a.type
|
>>> fields(A).a.type
|
||||||
typing.List[A]
|
list[A]
|
||||||
>>> fields(A).b.type
|
>>> fields(A).b.type
|
||||||
<class 'B'>
|
<class 'B'>
|
||||||
|
|
||||||
|
.. 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::
|
.. warning::
|
||||||
|
|
||||||
``attrs`` itself doesn't have any features that work on top of type metadata *yet*.
|
``attrs`` itself doesn't have any features that work on top of type metadata *yet*.
|
||||||
|
|
|
@ -10,12 +10,11 @@ That means that on modern Python versions, the declaration part of the example f
|
||||||
.. doctest::
|
.. doctest::
|
||||||
|
|
||||||
>>> import attr
|
>>> import attr
|
||||||
>>> import typing
|
|
||||||
|
|
||||||
>>> @attr.s(auto_attribs=True)
|
>>> @attr.s(auto_attribs=True)
|
||||||
... class SomeClass:
|
... class SomeClass:
|
||||||
... a_number: int = 42
|
... 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 = SomeClass(1, [1, 2, 3])
|
||||||
>>> sc
|
>>> sc
|
||||||
|
@ -71,7 +70,7 @@ To mypy, this code is equivalent to the one above:
|
||||||
@attr.s
|
@attr.s
|
||||||
class SomeClass(object):
|
class SomeClass(object):
|
||||||
a_number = attr.ib(default=42) # type: int
|
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
|
pyright
|
||||||
|
@ -86,7 +85,7 @@ Given the following definition, ``pyright`` will generate static type signatures
|
||||||
@attr.define
|
@attr.define
|
||||||
class SomeClass:
|
class SomeClass:
|
||||||
a_number: int = 42
|
a_number: int = 42
|
||||||
list_of_numbers: typing.List[int] = attr.field(factory=list)
|
list_of_numbers: list[int] = attr.field(factory=list)
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue