Description
With attrs 19.1.0/py 3.7.2, I have the following attrbug.py
:
from typing import Optional
from attr import validators
import attr
@attr.s
class DoesntWorkWithMyPy:
required_bool: bool = attr.ib(
validator=validators.optional(validators.instance_of(bool)),
default=False,
)
optional_bool: Optional[bool] = attr.ib(
validator=validators.instance_of(bool),
default=False,
)
@attr.s
class DoesWorkWithMyPy:
required_bool: bool = attr.ib(
validator=validators.instance_of(bool),
default=False,
)
if __name__ == "__main__":
# neither of these raises, because all attribs specify defaults
DoesWorkWithMyPy()
DoesntWorkWithMyPy()
Running mypy, I see thee following (I think wrong?) error:
$ mypy attrbug.py
attrbug.py:9: error: Argument "validator" has incompatible type "Callable[[Any, Attribute[Optional[bool]], Optional[bool]], Any]"; expected "Union[Callable[[Any, Attribute[bool], bool], Any], Sequence[Callable[[Any, Attribute[bool], bool], Any]], None]"
That's from the required_bool
attribute of the DoesntWorkWithMyPy
class. MyPy doesn't complain about any of the other invocations used here, as you can see, and I don't think it probably ought to complain about this one either.
I think what's going on is that I have said that the attribute is non-Optional on the class (because I specify a default value), but uses an "optional" validator. I had (originally) specified it there so that instances could be created without specifying a value for this parameter, assuming that the validators & converters happen before the default is applied; it seems however that the default applies before the validator, which is why both optional_bool
and DoesWorkWithMyPy.required_bool
work. Is this new understanding correct & reliable?