Using the attrs libary and Python 3.6, I thought the following would allow me to specify that x
and y
can only contain integers:
import attr
@attr.s
class C:
x : List[int] = attr.ib() # not working
y = attr.ib(type=List[int]) # not working either
Both of the commented lines throw a NameError: name 'List' is not defined
.
The reasons I expected that to work are these:
(1) The types section of the attr documentation includes the following passage: "attrs
also allows you to associate a type with an attribute using either the type argument to attr.ib() or – as of Python 3.6 – using PEP 526-annotations". It then demonstrates both methods:
@attr.s
class C:
x = attr.ib(type=int)
y: int = attr.ib()
(2) PEP 526 states that the following syntax for type annotation is valid: primes: List[int] = []
.
The syntax is indeed valid. But the generic type annotation objects added by PEP 484 are not in the builtins namespace, but in the typing
module.
So, you need to do what all of the examples in the attrs
docs you linked, and PEP 484, PEP 483, PEP 526, and the typing
docs do:
from typing import List
Also, note that this is just an annotation. You can still write c = C(x=[], y=[1.0])
and you won't get a TypeError
. As the docs you linked say:
attrs
itself doesn’t have any features that work on top of type metadata yet. However it’s useful for writing your own validators or serialization frameworks.
It's not at all clear what attrs
should do with this metadata. It's a central part of the design of PEP 483/PEP 484 that type annotations are nothing more than annotations are runtime, and do not affect the types of values or what's legal to store where; they're only there to be used by static type checkers and other tools that runs separately from Python.
In particular, Mypy (the reference-standard static type checker), some linters, and some IDEs should flag this as an error. If they don't support attrib
annotations yet, they're almost certainly working on it (since they're roughly equivalent to annotated attributes in 3.7/PEP 557 dataclass
).
来源:https://stackoverflow.com/questions/49472632/how-to-specify-that-an-attribute-must-be-a-list-of-say-integers-not-just-a-li