python-attrs / python-attrs/attrs
question about mypy error with optional() validator and non-None default
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.8k
- Forks
- 480
- Avg merge
- 2h 15m
- Merged PRs (30d)
- 2
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?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the diagnostic from the attrbug.py example with attrs 19.1.0 and Python 3.7.2. Read the typing around validators.optional and attr.ib, then check how defaults and validators are represented to mypy. Done means establishing whether the reported incompatibility is expected and identifying the relevant project behavior or typing change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100