Loosen some types to avoid pain in real-life situations (#4870)

In this diff:
* Loosen `set.__[i]sub__()` to allow typical use cases (that work at runtime). Namely, allow removing `unicode` from a set of `str`, and allow removing optional values from non-optional sets.
* Avoid using union return types in `cryptography` deserialization functions.
* Tune `SupportsItems` so that `dict` implements it on Python 2.

Co-authored-by: Ivan Levkivskyi <ilevkivskyi@dropbox.com>
This commit is contained in:
Ivan Levkivskyi
2020-12-29 18:31:14 +00:00
committed by GitHub
parent 1ae3158174
commit fb753c4226
5 changed files with 29 additions and 13 deletions

View File

@@ -737,8 +737,14 @@ class set(MutableSet[_T], Generic[_T]):
def __iand__(self, s: AbstractSet[object]) -> Set[_T]: ...
def __or__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __ior__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __sub__(self, s: AbstractSet[_T]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[_T]) -> Set[_T]: ...
@overload
def __sub__(self: Set[str], s: AbstractSet[Optional[Text]]) -> Set[_T]: ...
@overload
def __sub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ...
@overload # type: ignore
def __isub__(self: Set[str], s: AbstractSet[Optional[Text]]) -> Set[_T]: ...
@overload
def __isub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ...
def __xor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __ixor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...

View File

@@ -737,8 +737,14 @@ class set(MutableSet[_T], Generic[_T]):
def __iand__(self, s: AbstractSet[object]) -> Set[_T]: ...
def __or__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __ior__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __sub__(self, s: AbstractSet[_T]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[_T]) -> Set[_T]: ...
@overload
def __sub__(self: Set[str], s: AbstractSet[Optional[Text]]) -> Set[_T]: ...
@overload
def __sub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ...
@overload # type: ignore
def __isub__(self: Set[str], s: AbstractSet[Optional[Text]]) -> Set[_T]: ...
@overload
def __isub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ...
def __xor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __ixor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...

View File

@@ -34,7 +34,11 @@ SupportsLessThanT = TypeVar("SupportsLessThanT", bound=SupportsLessThan) # noqa
# Mapping-like protocols
class SupportsItems(Protocol[_KT_co, _VT_co]):
def items(self) -> AbstractSet[Tuple[_KT_co, _VT_co]]: ...
if sys.version_info >= (3,):
def items(self) -> AbstractSet[Tuple[_KT_co, _VT_co]]: ...
else:
# We want dictionaries to support this on Python 2.
def items(self) -> Iterable[Tuple[_KT_co, _VT_co]]: ...
class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]):
def keys(self) -> Iterable[_KT]: ...

View File

@@ -807,8 +807,8 @@ class set(MutableSet[_T], Generic[_T]):
def __iand__(self, s: AbstractSet[object]) -> Set[_T]: ...
def __or__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __ior__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __sub__(self, s: AbstractSet[_T]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[_T]) -> Set[_T]: ...
def __sub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ...
def __xor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __ixor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...