Skip to content
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

Make IndexOpsMixin (and Index) generic #760

Merged
merged 25 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4929ecb
interpolate method
twoertwein Aug 2, 2023
2775a58
WIP
twoertwein Aug 2, 2023
9e40ddf
mypy handles Never differently - at least asssert that the method nev…
twoertwein Aug 3, 2023
68abe4d
use Self
twoertwein Aug 3, 2023
2cfbdb0
a few more S1/Self
twoertwein Aug 3, 2023
ebcc389
fix tests
twoertwein Aug 3, 2023
24d42fa
more tests
twoertwein Aug 3, 2023
f3802d3
add an ignore to let mypy pass
twoertwein Aug 3, 2023
92eab41
compat with old python versions
twoertwein Aug 3, 2023
6e04d8e
fix CategoricalIndex; MultiIndex should probably be Index[tuple[S1, .…
twoertwein Aug 3, 2023
e7a2d3b
Revert "interpolate method"
twoertwein Aug 3, 2023
d12a72a
many more overloads for subclasses (I wish pandas would not handle su…
twoertwein Aug 4, 2023
87c62d0
remove PandasObject - it caused the pyright issues but it provides no…
twoertwein Aug 4, 2023
9ce5fc4
works (except for np.ndarray)
twoertwein Aug 4, 2023
05b9c15
Merge remote-tracking branch 'upstream/main' into iter_interpolate
twoertwein Aug 8, 2023
d32f534
address the easy-to-fix comments
twoertwein Aug 8, 2023
4f13109
overloads for numpy
twoertwein Aug 9, 2023
bd39625
did numexpr break the CI?
twoertwein Aug 9, 2023
8c48567
lie: df.columns -> Index[str]
twoertwein Aug 9, 2023
67f5e8d
new ruff has far more pyi rules
twoertwein Aug 9, 2023
566c918
Make it clear that both mypy&pyright infer Never; but only pyright de…
twoertwein Aug 10, 2023
ff5ee58
use type aliases instead of npt
twoertwein Aug 10, 2023
c8d2019
fix issue with floordiv for mypy
Dr-Irv Aug 13, 2023
585c93b
fix comment in arraylike
Dr-Irv Aug 13, 2023
7ac1ea5
Merge pull request #3 from Dr-Irv/pr760
twoertwein Aug 14, 2023
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.282
rev: v0.0.283
hooks:
- id: ruff
args: [
Expand Down
18 changes: 7 additions & 11 deletions pandas-stubs/_libs/tslibs/timedeltas.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,11 @@ import numpy as np
import pandas as pd
from pandas import (
DatetimeIndex,
Index,
PeriodIndex,
Series,
TimedeltaIndex,
)
from pandas.core.indexes.base import (
_FloatIndexType,
_IntIndexType,
)
from pandas.core.series import (
TimedeltaSeries,
TimestampSeries,
Expand Down Expand Up @@ -245,7 +242,7 @@ class Timedelta(timedelta):
@overload
def __mul__(self, other: Series[float]) -> TimedeltaSeries: ...
@overload
def __mul__(self, other: _IntIndexType | _FloatIndexType) -> TimedeltaIndex: ...
def __mul__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ...
@overload
def __rmul__(self, other: float) -> Timedelta: ...
@overload
Expand All @@ -254,8 +251,9 @@ class Timedelta(timedelta):
def __rmul__(self, other: Series[int]) -> TimedeltaSeries: ...
@overload
def __rmul__(self, other: Series[float]) -> TimedeltaSeries: ...
# maybe related to https://github.com/python/mypy/issues/10755
@overload
def __rmul__(self, other: _IntIndexType | _FloatIndexType) -> TimedeltaIndex: ...
def __rmul__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ... # type: ignore[misc]
# Override due to more types supported than dt.timedelta
# error: Signature of "__floordiv__" incompatible with supertype "timedelta"
@overload # type: ignore[override]
Expand All @@ -271,9 +269,7 @@ class Timedelta(timedelta):
self, other: npt.NDArray[np.timedelta64]
) -> npt.NDArray[np.int_]: ...
@overload
def __floordiv__(
self, other: _IntIndexType | _FloatIndexType
) -> TimedeltaIndex: ...
def __floordiv__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ...
@overload
def __floordiv__(self, other: Series[int]) -> TimedeltaSeries: ...
@overload
Expand Down Expand Up @@ -306,7 +302,7 @@ class Timedelta(timedelta):
@overload
def __truediv__(self, other: Series[float]) -> TimedeltaSeries: ...
@overload
def __truediv__(self, other: _IntIndexType | _FloatIndexType) -> TimedeltaIndex: ...
def __truediv__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ...
def __rtruediv__(self, other: timedelta | Timedelta | NaTType) -> float: ...
# Override due to more types supported than dt.timedelta
@overload
Expand Down Expand Up @@ -338,7 +334,7 @@ class Timedelta(timedelta):
@overload
def __mod__(self, other: Series[int] | Series[float]) -> TimedeltaSeries: ...
@overload
def __mod__(self, other: _IntIndexType | _FloatIndexType) -> TimedeltaIndex: ...
def __mod__(self, other: Index[int] | Index[float]) -> TimedeltaIndex: ...
@overload
def __mod__(
self, other: npt.NDArray[np.integer] | npt.NDArray[np.floating]
Expand Down
47 changes: 17 additions & 30 deletions pandas-stubs/_typing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ DtypeBackend: TypeAlias = Literal["pyarrow", "numpy_nullable"]

BooleanDtypeArg: TypeAlias = (
# Builtin bool type and its string alias
type[bool] # noqa: PYI030
type[bool] # noqa: PYI030,PYI055
| Literal["bool"]
# Pandas nullable boolean type and its string alias
| pd.BooleanDtype
Expand All @@ -105,7 +105,7 @@ BooleanDtypeArg: TypeAlias = (
)
IntDtypeArg: TypeAlias = (
# Builtin integer type and its string alias
type[int] # noqa: PYI030
type[int] # noqa: PYI030,PYI055
| Literal["int"]
# Pandas nullable integer types and their string aliases
| pd.Int8Dtype
Expand Down Expand Up @@ -137,7 +137,7 @@ IntDtypeArg: TypeAlias = (
)
UIntDtypeArg: TypeAlias = (
# Pandas nullable unsigned integer types and their string aliases
pd.UInt8Dtype # noqa: PYI030
pd.UInt8Dtype # noqa: PYI030,PYI055
| pd.UInt16Dtype
| pd.UInt32Dtype
| pd.UInt64Dtype
Expand Down Expand Up @@ -166,7 +166,7 @@ UIntDtypeArg: TypeAlias = (
)
FloatDtypeArg: TypeAlias = (
# Builtin float type and its string alias
type[float] # noqa: PYI030
type[float] # noqa: PYI030,PYI055
| Literal["float"]
# Pandas nullable float types and their string aliases
| pd.Float32Dtype
Expand Down Expand Up @@ -197,7 +197,7 @@ FloatDtypeArg: TypeAlias = (
)
ComplexDtypeArg: TypeAlias = (
# Builtin complex type and its string alias
type[complex] # noqa: PYI030
type[complex] # noqa: PYI030,PYI055
| Literal["complex"]
# Numpy complex types and their aliases
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.csingle
Expand Down Expand Up @@ -326,7 +326,7 @@ TimestampDtypeArg: TypeAlias = Literal[

StrDtypeArg: TypeAlias = (
# Builtin str type and its string alias
type[str] # noqa: PYI030
type[str] # noqa: PYI030,PYI055
| Literal["str"]
# Pandas nullable string type and its string alias
| pd.StringDtype
Expand All @@ -340,7 +340,7 @@ StrDtypeArg: TypeAlias = (
)
BytesDtypeArg: TypeAlias = (
# Builtin bytes type and its string alias
type[bytes] # noqa: PYI030
type[bytes] # noqa: PYI030,PYI055
| Literal["bytes"]
# Numpy bytes type and its string alias
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.bytes_
Expand All @@ -353,7 +353,7 @@ CategoryDtypeArg: TypeAlias = CategoricalDtype | Literal["category"]

ObjectDtypeArg: TypeAlias = (
# Builtin object type and its string alias
type[object] # noqa: PYI030
type[object] # noqa: PYI030,PYI055
| Literal["object"]
# Numpy object type and its string alias
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.object_
Expand Down Expand Up @@ -483,6 +483,8 @@ ScalarT = TypeVar("ScalarT", bound=Scalar)
np_ndarray_int64: TypeAlias = npt.NDArray[np.int64]
np_ndarray_int: TypeAlias = npt.NDArray[np.signedinteger]
np_ndarray_anyint: TypeAlias = npt.NDArray[np.integer]
np_ndarray_float: TypeAlias = npt.NDArray[np.floating]
np_ndarray_complex: TypeAlias = npt.NDArray[np.complexfloating]
np_ndarray_bool: TypeAlias = npt.NDArray[np.bool_]
np_ndarray_str: TypeAlias = npt.NDArray[np.str_]

Expand Down Expand Up @@ -511,19 +513,12 @@ S1 = TypeVar(
| float
| complex
| Dtype
| Timestamp
| Timedelta
| datetime.datetime # includes pd.Timestamp
| datetime.timedelta # includes pd.Timedelta
| Period
| Interval[int]
| Interval[float]
| Interval[Timestamp]
| Interval[Timedelta]
| Interval[int | float | Timestamp | Timedelta]
| CategoricalDtype,
)
T1 = TypeVar(
"T1", str, int, np.int64, np.uint64, np.float64, float, np.dtype[np.generic]
)
T2 = TypeVar("T2", str, int)

IndexingInt: TypeAlias = (
int | np.int_ | np.integer | np.unsignedinteger | np.signedinteger | np.int8
Expand Down Expand Up @@ -601,14 +596,9 @@ ByT = TypeVar(
| int
| float
| complex
| Timestamp
| Timedelta
| Scalar
| Period
| Interval[int]
| Interval[float]
| Interval[Timestamp]
| Interval[Timedelta]
| Interval[int | float | Timestamp | Timedelta]
| tuple,
)
# Use a distinct SeriesByT when using groupby with Series of known dtype.
Expand All @@ -622,13 +612,10 @@ SeriesByT = TypeVar(
| int
| float
| complex
| Timestamp
| Timedelta
| datetime.datetime
| datetime.timedelta
| Period
| Interval[int]
| Interval[float]
| Interval[Timestamp]
| Interval[Timedelta],
| Interval[int | float | Timestamp | Timedelta],
)
GroupByObjectNonScalar: TypeAlias = (
tuple
Expand Down
3 changes: 0 additions & 3 deletions pandas-stubs/core/accessor.pyi
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
from typing import Any

class DirNamesMixin:
def __dir__(self): ...
Dr-Irv marked this conversation as resolved.
Show resolved Hide resolved

class PandasDelegate: ...

def delegate_names(
Expand Down
4 changes: 3 additions & 1 deletion pandas-stubs/core/arraylike.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ class OpsMixin:
def __rmul__(self, other: Any) -> Self: ...
def __truediv__(self, other: Any) -> Self: ...
def __rtruediv__(self, other: Any) -> Self: ...
def __floordiv__(self, other: Any) -> Self: ...
# __floordiv__ is handled by subclasses that specify only the valid values
# that can be passed
# def __floordiv__(self, other: Any) -> Self: ...
def __rfloordiv__(self, other: Any) -> Self: ...
def __mod__(self, other: Any) -> Self: ...
def __rmod__(self, other: Any) -> Self: ...
Expand Down
9 changes: 3 additions & 6 deletions pandas-stubs/core/arrays/categorical.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ import numpy as np
from pandas import Series
from pandas.core.accessor import PandasDelegate as PandasDelegate
from pandas.core.arrays.base import ExtensionArray as ExtensionArray
from pandas.core.base import (
NoNewAttributesMixin as NoNewAttributesMixin,
PandasObject as PandasObject,
)
from pandas.core.base import NoNewAttributesMixin as NoNewAttributesMixin
from pandas.core.indexes.base import Index

from pandas._typing import (
Expand All @@ -33,7 +30,7 @@ from pandas.core.dtypes.dtypes import CategoricalDtype as CategoricalDtype

def contains(cat, key, container): ...

class Categorical(ExtensionArray, PandasObject):
class Categorical(ExtensionArray):
__array_priority__: int = ...
def __init__(
self,
Expand Down Expand Up @@ -185,7 +182,7 @@ class Categorical(ExtensionArray, PandasObject):
def repeat(self, repeats, axis=...): ...
def isin(self, values): ...

class CategoricalAccessor(PandasDelegate, PandasObject, NoNewAttributesMixin):
class CategoricalAccessor(PandasDelegate, NoNewAttributesMixin):
def __init__(self, data) -> None: ...
@property
def codes(self) -> Series[int]: ...
Expand Down
3 changes: 1 addition & 2 deletions pandas-stubs/core/arrays/sparse/array.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ from pandas.core.arrays import (
ExtensionArray,
ExtensionOpsMixin,
)
from pandas.core.base import PandasObject

from pandas._typing import TakeIndexer

class SparseArray(PandasObject, ExtensionArray, ExtensionOpsMixin):
class SparseArray(ExtensionArray, ExtensionOpsMixin):
def __init__(
self,
data,
Expand Down
25 changes: 11 additions & 14 deletions pandas-stubs/core/base.pyi
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
from typing import (
Generic,
Iterator,
Literal,
)

import numpy as np
from pandas import Index
from pandas.core.accessor import DirNamesMixin
from pandas.core.arraylike import OpsMixin
from pandas.core.arrays import ExtensionArray
from pandas.core.arrays.categorical import Categorical
from typing_extensions import Self

from pandas._typing import (
S1,
AxisIndex,
NaPosition,
NDFrameT,
Scalar,
npt,
)

class PandasObject(DirNamesMixin):
def __sizeof__(self) -> int: ...

class NoNewAttributesMixin:
def __setattr__(self, key, value) -> None: ...

class SelectionMixin(Generic[NDFrameT]):
def ndim(self) -> int: ...
def __getitem__(self, key): ...

class IndexOpsMixin(OpsMixin):
class IndexOpsMixin(OpsMixin, Generic[S1]):
__array_priority__: int = ...
def transpose(self, *args, **kwargs) -> IndexOpsMixin: ...
def transpose(self, *args, **kwargs) -> Self: ...
@property
def T(self) -> IndexOpsMixin: ...
def T(self) -> Self: ...
@property
def shape(self) -> tuple: ...
@property
def ndim(self) -> int: ...
def item(self): ...
def item(self) -> S1: ...
@property
def nbytes(self) -> int: ...
@property
Expand All @@ -61,9 +60,9 @@ class IndexOpsMixin(OpsMixin):
def argmin(
self, axis: AxisIndex | None = ..., skipna: bool = ..., *args, **kwargs
) -> np.int64: ...
def tolist(self) -> list: ...
def to_list(self) -> list: ...
def __iter__(self): ...
def tolist(self) -> list[S1]: ...
def to_list(self) -> list[S1]: ...
def __iter__(self) -> Iterator[S1]: ...
@property
def hasnans(self) -> bool: ...
def value_counts(
Expand All @@ -87,6 +86,4 @@ class IndexOpsMixin(OpsMixin):
def searchsorted(
self, value, side: Literal["left", "right"] = ..., sorter=...
) -> int | list[int]: ...
def drop_duplicates(
self, *, keep: NaPosition | Literal[False] = ...
) -> IndexOpsMixin: ...
def drop_duplicates(self, *, keep: NaPosition | Literal[False] = ...) -> Self: ...
1 change: 0 additions & 1 deletion pandas-stubs/core/computation/ops.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class Term:
def ndim(self) -> int: ...

class Constant(Term):
def __init__(self, value, env, side=..., encoding=...) -> None: ...
twoertwein marked this conversation as resolved.
Show resolved Hide resolved
@property
def name(self): ...

Expand Down
2 changes: 1 addition & 1 deletion pandas-stubs/core/computation/pytables.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Term(ops.Term):
def value(self, new_value) -> None: ...

class Constant(Term):
def __init__(self, value, env: PyTablesScope, side=..., encoding=...) -> None: ...
def __init__(self, name, env: PyTablesScope, side=..., encoding=...) -> None: ...

class BinOp(ops.BinOp):
op: str
Expand Down
6 changes: 5 additions & 1 deletion pandas-stubs/core/frame.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,7 @@ class DataFrame(NDFrame, OpsMixin):
@property
def at(self): ... # Not sure what to do with this yet; look at source
@property
def columns(self) -> Index: ...
def columns(self) -> Index[str]: ...
@columns.setter # setter needs to be right next to getter; otherwise mypy complains
def columns(
self, cols: AnyArrayLike | list[HashableT] | tuple[HashableT, ...]
Expand Down Expand Up @@ -2275,3 +2275,7 @@ class DataFrame(NDFrame, OpsMixin):
level: Level | None = ...,
drop_level: _bool = ...,
) -> DataFrame | Series: ...
# floordiv overload
def __floordiv__(
self, other: float | DataFrame | Series[int] | Series[float]
) -> Self: ...
3 changes: 1 addition & 2 deletions pandas-stubs/core/generic.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ from typing import (

import numpy as np
from pandas import Index
from pandas.core.base import PandasObject
import pandas.core.indexing as indexing
from pandas.core.series import Series
import sqlalchemy.engine
Expand Down Expand Up @@ -54,7 +53,7 @@ from pandas.io.sql import SQLTable
_bool = bool
_str = str

class NDFrame(PandasObject, indexing.IndexingMixin):
class NDFrame(indexing.IndexingMixin):
__hash__: ClassVar[None] # type: ignore[assignment]

def set_flags(
Expand Down
Loading