attrs
attrs copied to clipboard
Typing of `optional` validator fails
Heya, minor issue with typing:
This passes mypy type checking:
@attr.s()
class MdParserConfig:
url_schemes: Optional[Iterable[str]] = attr.ib(
default=None,
validator=optional(deep_iterable(instance_of(str), instance_of((list, tuple)))),
)
but then weirdly changing the default to anything else fails, e.g.
@attr.s()
class MdParserConfig:
url_schemes: Optional[Iterable[str]] = attr.ib(
default=("http", "https"),
validator=optional(deep_iterable(instance_of(str), instance_of((list, tuple)))),
)
leads to:
error: Argument "validator" has incompatible type "Callable[[Any, Attribute[Union[List[Any], Tuple[Any, ...], None]], Union[List[Any], Tuple[Any, ...], None]], Any]"; expected "Union[Callable[[Any, Attribute[Tuple[str, str]], Tuple[str, str]], Any], Sequence[Callable[[Any, Attribute[Tuple[str, str]], Tuple[str, str]], Any]], None]" [arg-type]
for reference, this is my mypy configuration
[mypy]
show_error_codes = true
check_untyped_defs = true
strict_equality = true
no_implicit_optional = true
warn_unused_ignores = true
thanks in advance!
This is a known mypy issue. I can't seem to find the bug right now but it's because we're trying to make sure that the default and the validator and the type annotation all match and it doesn't know which type should take precedence. You can help mypy along by doing the following:
@attr.s()
class MdParserConfig:
url_schemes: Optional[Iterable[str]] = attr.ib(
default=cast(Optional[Iterable[str]], ("http", "https")),
validator=optional(deep_iterable(instance_of(str), instance_of((list, tuple)))),
)
thanks for the quick feedback, yep good suggestion, that works 👍