Fix deep_iterable, deep_mapping validator type stubs (#533)

Use bound type variables for iterables and mappings of the validated item types, so mypy does not erroneously require both the iterable attribute validated by deep_iterable and the item type validated by the first argument of deep_iterable to have the same type. This fixes #531.
This commit is contained in:
Michał Masłowski 2019-05-27 16:28:27 +02:00 committed by David Euresti
parent 669e69daa0
commit 45adbb9fbb
3 changed files with 62 additions and 8 deletions

View File

@ -0,0 +1,2 @@
Fixed ``attr.validators.deep_iterable()``
and ``attr.validators.deep_mapping()`` type stubs.

View File

@ -1,7 +1,22 @@
from typing import Container, List, Union, TypeVar, Type, Any, Optional, Tuple
from typing import (
Container,
List,
Union,
TypeVar,
Type,
Any,
Optional,
Tuple,
Iterable,
Mapping,
)
from . import _ValidatorType
_T = TypeVar("_T")
_I = TypeVar("_I", bound=Iterable[_T])
_K = TypeVar("_K")
_V = TypeVar("_V")
_M = TypeVar("_V", bound=Mapping[_K, _V])
def instance_of(
type: Union[Tuple[Type[_T], ...], Type[_T]]
@ -14,11 +29,11 @@ def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
def deep_iterable(
member_validator: _ValidatorType[_T],
iterable_validator: Optional[_ValidatorType[_T]],
) -> _ValidatorType[_T]: ...
iterable_validator: Optional[_ValidatorType[_I]] = ...,
) -> _ValidatorType[_I]: ...
def deep_mapping(
key_validator: _ValidatorType[_T],
value_validator: _ValidatorType[_T],
mapping_validator: Optional[_ValidatorType[_T]],
) -> _ValidatorType[_T]: ...
key_validator: _ValidatorType[_K],
value_validator: _ValidatorType[_V],
mapping_validator: Optional[_ValidatorType[_M]] = ...,
) -> _ValidatorType[_M]: ...
def is_callable() -> _ValidatorType[_T]: ...

View File

@ -1,4 +1,4 @@
from typing import Any, List
from typing import Any, Dict, List, Tuple
import attr
@ -114,3 +114,40 @@ except Error as e:
# ConvCDefaultIfNone(1)
# ConvCDefaultIfNone(None)
# Validators
@attr.s
class Validated:
a = attr.ib(
type=List[C],
validator=attr.validators.deep_iterable(
attr.validators.instance_of(C), attr.validators.instance_of(list)
),
)
a = attr.ib(
type=Tuple[C],
validator=attr.validators.deep_iterable(
attr.validators.instance_of(C), attr.validators.instance_of(tuple)
),
)
b = attr.ib(
type=List[C],
validator=attr.validators.deep_iterable(
attr.validators.instance_of(C)
),
)
c = attr.ib(
type=Dict[C, D],
validator=attr.validators.deep_mapping(
attr.validators.instance_of(C),
attr.validators.instance_of(D),
attr.validators.instance_of(dict),
),
)
d = attr.ib(
type=Dict[C, D],
validator=attr.validators.deep_mapping(
attr.validators.instance_of(C), attr.validators.instance_of(D)
),
)