Skip to content

Make operations on set take AbstractSet[object] #1533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions stdlib/2/__builtin__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,9 @@ class set(MutableSet[_T], Generic[_T]):
def discard(self, element: _T) -> None: ...
def intersection(self, *s: Iterable[Any]) -> Set[_T]: ...
def intersection_update(self, *s: Iterable[Any]) -> None: ...
def isdisjoint(self, s: Iterable[Any]) -> bool: ...
def issubset(self, s: Iterable[Any]) -> bool: ...
def issuperset(self, s: Iterable[Any]) -> bool: ...
def isdisjoint(self, s: Iterable[object]) -> bool: ...
def issubset(self, s: Iterable[object]) -> bool: ...
def issuperset(self, s: Iterable[object]) -> bool: ...
def pop(self) -> _T: ...
def remove(self, element: _T) -> None: ...
def symmetric_difference(self, s: Iterable[_T]) -> Set[_T]: ...
Expand All @@ -613,18 +613,18 @@ class set(MutableSet[_T], Generic[_T]):
def __contains__(self, o: object) -> bool: ...
def __iter__(self) -> Iterator[_T]: ...
def __str__(self) -> str: ...
def __and__(self, s: AbstractSet[Any]) -> Set[_T]: ...
def __iand__(self, s: AbstractSet[Any]) -> Set[_T]: ...
def __and__(self, s: AbstractSet[object]) -> Set[_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[Any]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[Any]) -> Set[_T]: ...
def __sub__(self, s: AbstractSet[object]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[object]) -> 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[Any]) -> bool: ...
def __lt__(self, s: AbstractSet[Any]) -> bool: ...
def __ge__(self, s: AbstractSet[Any]) -> bool: ...
def __gt__(self, s: AbstractSet[Any]) -> bool: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...
def __lt__(self, s: AbstractSet[object]) -> bool: ...
def __ge__(self, s: AbstractSet[object]) -> bool: ...
def __gt__(self, s: AbstractSet[object]) -> bool: ...
# TODO more set operations

class frozenset(AbstractSet[_T], Generic[_T]):
Expand All @@ -633,11 +633,11 @@ class frozenset(AbstractSet[_T], Generic[_T]):
@overload
def __init__(self, iterable: Iterable[_T]) -> None: ...
def copy(self) -> FrozenSet[_T]: ...
def difference(self, *s: Iterable[Any]) -> FrozenSet[_T]: ...
def intersection(self, *s: Iterable[Any]) -> FrozenSet[_T]: ...
def difference(self, *s: Iterable[object]) -> FrozenSet[_T]: ...
def intersection(self, *s: Iterable[object]) -> FrozenSet[_T]: ...
def isdisjoint(self, s: Iterable[_T]) -> bool: ...
def issubset(self, s: Iterable[Any]) -> bool: ...
def issuperset(self, s: Iterable[Any]) -> bool: ...
def issubset(self, s: Iterable[object]) -> bool: ...
def issuperset(self, s: Iterable[object]) -> bool: ...
def symmetric_difference(self, s: Iterable[_T]) -> FrozenSet[_T]: ...
def union(self, *s: Iterable[_T]) -> FrozenSet[_T]: ...
def __len__(self) -> int: ...
Expand All @@ -648,10 +648,10 @@ class frozenset(AbstractSet[_T], Generic[_T]):
def __or__(self, s: AbstractSet[_S]) -> FrozenSet[Union[_T, _S]]: ...
def __sub__(self, s: AbstractSet[_T]) -> FrozenSet[_T]: ...
def __xor__(self, s: AbstractSet[_S]) -> FrozenSet[Union[_T, _S]]: ...
def __le__(self, s: AbstractSet[Any]) -> bool: ...
def __lt__(self, s: AbstractSet[Any]) -> bool: ...
def __ge__(self, s: AbstractSet[Any]) -> bool: ...
def __gt__(self, s: AbstractSet[Any]) -> bool: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...
def __lt__(self, s: AbstractSet[object]) -> bool: ...
def __ge__(self, s: AbstractSet[object]) -> bool: ...
def __gt__(self, s: AbstractSet[object]) -> bool: ...

class enumerate(Iterator[Tuple[int, _T]], Generic[_T]):
def __init__(self, iterable: Iterable[_T], start: int = 0) -> None: ...
Expand Down
38 changes: 19 additions & 19 deletions stdlib/3/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -664,10 +664,10 @@ class set(MutableSet[_T], Generic[_T]):
def add(self, element: _T) -> None: ...
def clear(self) -> None: ...
def copy(self) -> Set[_T]: ...
def difference(self, *s: Iterable[Any]) -> Set[_T]: ...
def difference_update(self, *s: Iterable[Any]) -> None: ...
def difference(self, *s: Iterable[object]) -> Set[_T]: ...
def difference_update(self, *s: Iterable[object]) -> None: ...
def discard(self, element: _T) -> None: ...
def intersection(self, *s: Iterable[Any]) -> Set[_T]: ...
def intersection(self, *s: Iterable[object]) -> Set[_T]: ...
def intersection_update(self, *s: Iterable[Any]) -> None: ...
def isdisjoint(self, s: Iterable[Any]) -> bool: ...
def issubset(self, s: Iterable[Any]) -> bool: ...
Expand All @@ -682,28 +682,28 @@ class set(MutableSet[_T], Generic[_T]):
def __contains__(self, o: object) -> bool: ...
def __iter__(self) -> Iterator[_T]: ...
def __str__(self) -> str: ...
def __and__(self, s: AbstractSet[Any]) -> Set[_T]: ...
def __iand__(self, s: AbstractSet[Any]) -> Set[_T]: ...
def __and__(self, s: AbstractSet[object]) -> Set[_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[Any]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[Any]) -> Set[_T]: ...
def __sub__(self, s: AbstractSet[object]) -> Set[_T]: ...
def __isub__(self, s: AbstractSet[object]) -> 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[Any]) -> bool: ...
def __lt__(self, s: AbstractSet[Any]) -> bool: ...
def __ge__(self, s: AbstractSet[Any]) -> bool: ...
def __gt__(self, s: AbstractSet[Any]) -> bool: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...
def __lt__(self, s: AbstractSet[object]) -> bool: ...
def __ge__(self, s: AbstractSet[object]) -> bool: ...
def __gt__(self, s: AbstractSet[object]) -> bool: ...
# TODO more set operations

class frozenset(AbstractSet[_T], Generic[_T]):
def __init__(self, iterable: Iterable[_T] = ...) -> None: ...
def copy(self) -> FrozenSet[_T]: ...
def difference(self, *s: Iterable[Any]) -> FrozenSet[_T]: ...
def intersection(self, *s: Iterable[Any]) -> FrozenSet[_T]: ...
def difference(self, *s: Iterable[object]) -> FrozenSet[_T]: ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, __sub__ below (which is implemented the same way in C) takes AbstractSet[_T]; I'm not sure why we can't specify _T here.

Copy link
Contributor Author

@ilinum ilinum Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, good catch both of these should be the same.

However, I think we should change the __sub__ function, in order to allow the following code:

from typing import Set, Union, FrozenSet

s1 = frozenset([1, 2])  # type: FrozenSet[int]
s2 = frozenset([1, '2'])  # type: FrozenSet[Union[str, int]]

# currently, mypy  you an error on the following line but I don't think it should.
s3 = s1 - s2  # type: FrozenSet[int]

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense from the perspective of minimizing false positives. It seems a shame that mypy won't tell you if you're mixing sets of different types in your operations (which is surely often a bug), but we should generally err on the side of reducing false positives.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should first decide how to do that for ==; then maybe we'll be able to generalize for other operations on other objects. I think for == there's probably already an open issue.

def intersection(self, *s: Iterable[object]) -> FrozenSet[_T]: ...
def isdisjoint(self, s: Iterable[_T]) -> bool: ...
def issubset(self, s: Iterable[Any]) -> bool: ...
def issuperset(self, s: Iterable[Any]) -> bool: ...
def issubset(self, s: Iterable[object]) -> bool: ...
def issuperset(self, s: Iterable[object]) -> bool: ...
def symmetric_difference(self, s: Iterable[_T]) -> FrozenSet[_T]: ...
def union(self, *s: Iterable[_T]) -> FrozenSet[_T]: ...
def __len__(self) -> int: ...
Expand All @@ -714,10 +714,10 @@ class frozenset(AbstractSet[_T], Generic[_T]):
def __or__(self, s: AbstractSet[_S]) -> FrozenSet[Union[_T, _S]]: ...
def __sub__(self, s: AbstractSet[_T]) -> FrozenSet[_T]: ...
def __xor__(self, s: AbstractSet[_S]) -> FrozenSet[Union[_T, _S]]: ...
def __le__(self, s: AbstractSet[Any]) -> bool: ...
def __lt__(self, s: AbstractSet[Any]) -> bool: ...
def __ge__(self, s: AbstractSet[Any]) -> bool: ...
def __gt__(self, s: AbstractSet[Any]) -> bool: ...
def __le__(self, s: AbstractSet[object]) -> bool: ...
def __lt__(self, s: AbstractSet[object]) -> bool: ...
def __ge__(self, s: AbstractSet[object]) -> bool: ...
def __gt__(self, s: AbstractSet[object]) -> bool: ...

class enumerate(Iterator[Tuple[int, _T]], Generic[_T]):
def __init__(self, iterable: Iterable[_T], start: int = 0) -> None: ...
Expand Down