-
-
Notifications
You must be signed in to change notification settings - Fork 143
add operators for Index #504
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,40 @@ | ||
from typing import ( | ||
Any, | ||
Protocol, | ||
TypeVar, | ||
) | ||
|
||
from pandas import DataFrame | ||
|
||
class OpsMixinProtocol(Protocol): ... | ||
_OpsMixinT = TypeVar("_OpsMixinT", bound=OpsMixin) | ||
|
||
class OpsMixin: | ||
def __eq__(self: OpsMixinProtocol, other: object) -> DataFrame: ... # type: ignore[override] | ||
def __ne__(self: OpsMixinProtocol, other: object) -> DataFrame: ... # type: ignore[override] | ||
def __lt__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __le__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __gt__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __ge__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __eq__(self: _OpsMixinT, other: object) -> _OpsMixinT: ... # type: ignore[override] | ||
def __ne__(self: _OpsMixinT, other: object) -> _OpsMixinT: ... # type: ignore[override] | ||
def __lt__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __le__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __gt__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __ge__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
# ------------------------------------------------------------- | ||
# Logical Methods | ||
def __and__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rand__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __or__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __ror__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __xor__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rxor__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __and__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rand__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __or__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __ror__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __xor__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rxor__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
# ------------------------------------------------------------- | ||
# Arithmetic Methods | ||
def __add__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __radd__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __sub__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rsub__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __mul__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rmul__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __truediv__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rtruediv__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __floordiv__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rfloordiv__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __mod__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rmod__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __divmod__( | ||
self: OpsMixinProtocol, other: DataFrame | ||
) -> tuple[DataFrame, DataFrame]: ... | ||
def __rdivmod__( | ||
self: OpsMixinProtocol, other: DataFrame | ||
) -> tuple[DataFrame, DataFrame]: ... | ||
def __pow__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __rpow__(self: OpsMixinProtocol, other: Any) -> DataFrame: ... | ||
def __add__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __radd__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __sub__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rsub__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __mul__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rmul__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __truediv__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rtruediv__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __floordiv__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rfloordiv__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __mod__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rmod__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __divmod__(self: _OpsMixinT, other: Any) -> tuple[_OpsMixinT, _OpsMixinT]: ... | ||
def __rdivmod__(self: _OpsMixinT, other: Any) -> tuple[_OpsMixinT, _OpsMixinT]: ... | ||
def __pow__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... | ||
def __rpow__(self: _OpsMixinT, other: Any) -> _OpsMixinT: ... |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,14 +13,18 @@ | |
from numpy import typing as npt | ||
import pandas as pd | ||
from pandas.core.indexes.numeric import NumericIndex | ||
from typing_extensions import assert_type | ||
from typing_extensions import ( | ||
Never, | ||
assert_type, | ||
) | ||
|
||
from pandas._typing import Scalar | ||
|
||
if TYPE_CHECKING: | ||
from pandas._typing import IndexIterScalar | ||
|
||
from tests import ( | ||
TYPE_CHECKING_INVALID_USAGE, | ||
check, | ||
pytest_warns_bounded, | ||
) | ||
|
@@ -684,3 +688,72 @@ def test_sorted_and_list() -> None: | |
), | ||
list, | ||
) | ||
|
||
|
||
def test_index_operators() -> None: | ||
# GH 405 | ||
i1 = pd.Index([1, 2, 3]) | ||
i2 = pd.Index([4, 5, 6]) | ||
|
||
check(assert_type(i1 + i2, pd.Index), pd.Index) | ||
check(assert_type(i1 + 10, pd.Index), pd.Index) | ||
check(assert_type(10 + i1, pd.Index), pd.Index) | ||
check(assert_type(i1 - i2, pd.Index), pd.Index) | ||
check(assert_type(i1 - 10, pd.Index), pd.Index) | ||
check(assert_type(10 - i1, pd.Index), pd.Index) | ||
check(assert_type(i1 * i2, pd.Index), pd.Index) | ||
check(assert_type(i1 * 10, pd.Index), pd.Index) | ||
check(assert_type(10 * i1, pd.Index), pd.Index) | ||
check(assert_type(i1 / i2, pd.Index), pd.Index) | ||
check(assert_type(i1 / 10, pd.Index), pd.Index) | ||
check(assert_type(10 / i1, pd.Index), pd.Index) | ||
check(assert_type(i1 // i2, pd.Index), pd.Index) | ||
check(assert_type(i1 // 10, pd.Index), pd.Index) | ||
check(assert_type(10 // i1, pd.Index), pd.Index) | ||
check(assert_type(i1**i2, pd.Index), pd.Index) | ||
check(assert_type(i1**2, pd.Index), pd.Index) | ||
check(assert_type(2**i1, pd.Index), pd.Index) | ||
check(assert_type(i1 % i2, pd.Index), pd.Index) | ||
check(assert_type(i1 % 10, pd.Index), pd.Index) | ||
check(assert_type(10 % i1, pd.Index), pd.Index) | ||
check(assert_type(divmod(i1, i2), Tuple[pd.Index, pd.Index]), tuple) | ||
check(assert_type(divmod(i1, 10), Tuple[pd.Index, pd.Index]), tuple) | ||
check(assert_type(divmod(10, i1), Tuple[pd.Index, pd.Index]), tuple) | ||
|
||
if TYPE_CHECKING_INVALID_USAGE: | ||
assert_type( | ||
i1 & i2, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( # type: ignore[assert-type] | ||
i1 & 10, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( # type: ignore[assert-type] | ||
10 & i1, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( | ||
i1 | i2, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( # type: ignore[assert-type] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some of the checks have an ignore for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has to do with how |
||
i1 | 10, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( # type: ignore[assert-type] | ||
10 | i1, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( | ||
i1 ^ i2, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( # type: ignore[assert-type] | ||
i1 ^ 10, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) | ||
assert_type( # type: ignore[assert-type] | ||
10 ^ i1, # type:ignore[operator] # pyright: ignore[reportGeneralTypeIssues] | ||
Never, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed but could also check the tuple elements:
check(..., tuple, pd.Index)