Skip to content

Commit 0efc21b

Browse files
simonjayhawkinsmroeschke
authored andcommitted
TYP: setter for index/columns property-like (AxisProperty) (pandas-dev#46565)
Co-authored-by: Matthew Roeschke <[email protected]>
1 parent 6117fad commit 0efc21b

File tree

7 files changed

+43
-21
lines changed

7 files changed

+43
-21
lines changed

pandas/_libs/properties.pyi

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
1-
# pyright: reportIncompleteStub = false
2-
from typing import Any
1+
from typing import (
2+
Sequence,
3+
overload,
4+
)
5+
6+
from pandas._typing import (
7+
AnyArrayLike,
8+
DataFrame,
9+
Index,
10+
Series,
11+
)
312

413
# note: this is a lie to make type checkers happy (they special
514
# case property). cache_readonly uses attribute names similar to
615
# property (fget) but it does not provide fset and fdel.
716
cache_readonly = property
817

9-
def __getattr__(name: str) -> Any: ... # incomplete
18+
class AxisProperty:
19+
20+
axis: int
21+
def __init__(self, axis: int = ..., doc: str = ...) -> None: ...
22+
@overload
23+
def __get__(self, obj: DataFrame | Series, type) -> Index: ...
24+
@overload
25+
def __get__(self, obj: None, type) -> AxisProperty: ...
26+
def __set__(
27+
self, obj: DataFrame | Series, value: AnyArrayLike | Sequence
28+
) -> None: ...

pandas/core/apply.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,12 @@ def transform(self) -> DataFrame | Series:
235235
and not obj.empty
236236
):
237237
raise ValueError("Transform function failed")
238+
# error: Argument 1 to "__get__" of "AxisProperty" has incompatible type
239+
# "Union[Series, DataFrame, GroupBy[Any], SeriesGroupBy,
240+
# DataFrameGroupBy, BaseWindow, Resampler]"; expected "Union[DataFrame,
241+
# Series]"
238242
if not isinstance(result, (ABCSeries, ABCDataFrame)) or not result.index.equals(
239-
obj.index
243+
obj.index # type:ignore[arg-type]
240244
):
241245
raise ValueError("Function did not transform")
242246

@@ -645,7 +649,11 @@ class NDFrameApply(Apply):
645649

646650
@property
647651
def index(self) -> Index:
648-
return self.obj.index
652+
# error: Argument 1 to "__get__" of "AxisProperty" has incompatible type
653+
# "Union[Series, DataFrame, GroupBy[Any], SeriesGroupBy,
654+
# DataFrameGroupBy, BaseWindow, Resampler]"; expected "Union[DataFrame,
655+
# Series]"
656+
return self.obj.index # type:ignore[arg-type]
649657

650658
@property
651659
def agg_axis(self) -> Index:

pandas/core/frame.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -11199,12 +11199,10 @@ def isin(self, values) -> DataFrame:
1119911199
_info_axis_number = 1
1120011200
_info_axis_name = "columns"
1120111201

11202-
index: Index = properties.AxisProperty(
11202+
index = properties.AxisProperty(
1120311203
axis=1, doc="The index (row labels) of the DataFrame."
1120411204
)
11205-
columns: Index = properties.AxisProperty(
11206-
axis=0, doc="The column labels of the DataFrame."
11207-
)
11205+
columns = properties.AxisProperty(axis=0, doc="The column labels of the DataFrame.")
1120811206

1120911207
@property
1121011208
def _AXIS_NUMBERS(self) -> dict[str, int]:

pandas/core/generic.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
to_offset,
3838
)
3939
from pandas._typing import (
40+
AnyArrayLike,
4041
ArrayLike,
4142
Axis,
4243
CompressionOptions,
@@ -757,7 +758,7 @@ def _set_axis_nocheck(self, labels, axis: Axis, inplace: bool_t):
757758
obj.set_axis(labels, axis=axis, inplace=True)
758759
return obj
759760

760-
def _set_axis(self, axis: int, labels: Index) -> None:
761+
def _set_axis(self, axis: int, labels: AnyArrayLike | Sequence) -> None:
761762
labels = ensure_index(labels)
762763
self._mgr.set_axis(axis, labels)
763764
self._clear_item_cache()

pandas/core/groupby/generic.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,9 @@ def aggregate(self, func=None, *args, engine=None, engine_kwargs=None, **kwargs)
275275
func = maybe_mangle_lambdas(func)
276276
ret = self._aggregate_multiple_funcs(func)
277277
if relabeling:
278-
# error: Incompatible types in assignment (expression has type
279-
# "Optional[List[str]]", variable has type "Index")
280-
ret.columns = columns # type: ignore[assignment]
278+
# columns is not narrowed by mypy from relabeling flag
279+
assert columns is not None # for mypy
280+
ret.columns = columns
281281
return ret
282282

283283
else:

pandas/core/series.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from pandas._libs.lib import no_default
3434
from pandas._typing import (
3535
AggFuncType,
36+
AnyArrayLike,
3637
ArrayLike,
3738
Axis,
3839
Dtype,
@@ -553,7 +554,7 @@ def _constructor_expanddim(self) -> Callable[..., DataFrame]:
553554
def _can_hold_na(self) -> bool:
554555
return self._mgr._can_hold_na
555556

556-
def _set_axis(self, axis: int, labels) -> None:
557+
def _set_axis(self, axis: int, labels: AnyArrayLike | Sequence) -> None:
557558
"""
558559
Override generic, we want to set the _typ here.
559560
@@ -5813,7 +5814,7 @@ def mask(
58135814
_info_axis_number = 0
58145815
_info_axis_name = "index"
58155816

5816-
index: Index = properties.AxisProperty(
5817+
index = properties.AxisProperty(
58175818
axis=0, doc="The index (axis labels) of the Series."
58185819
)
58195820

pandas/io/parsers/arrow_parser_wrapper.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,7 @@ def _finalize_output(self, frame: DataFrame) -> DataFrame:
105105
multi_index_named = False
106106
frame.columns = self.names
107107
# we only need the frame not the names
108-
# error: Incompatible types in assignment (expression has type
109-
# "Union[List[Union[Union[str, int, float, bool], Union[Period, Timestamp,
110-
# Timedelta, Any]]], Index]", variable has type "Index") [assignment]
111-
frame.columns, frame = self._do_date_conversions( # type: ignore[assignment]
112-
frame.columns, frame
113-
)
108+
frame.columns, frame = self._do_date_conversions(frame.columns, frame)
114109
if self.index_col is not None:
115110
for i, item in enumerate(self.index_col):
116111
if is_integer(item):

0 commit comments

Comments
 (0)