Skip to content

Conversation

@dangotbanned
Copy link
Member

@dangotbanned dangotbanned commented Mar 16, 2025

What type of PR is this? (check all applicable)

  • πŸ’Ύ Refactor
  • ✨ Feature
  • πŸ› Bug Fix
  • πŸ”§ Optimization
  • πŸ“ Documentation
  • βœ… Test
  • 🐳 Other

Related issues

Checklist

  • Code follows style guide (ruff)
  • Tests added
  • Documented the changes

If you have comments or can explain your changes, please do so below

  • mypy is happy
  • pyright still had 7 errors
    • mypy disagrees that those are errors
    • I side with pyright in (3648814)

@dangotbanned dangotbanned added fix typing pandas-like Issue is related to pandas-like backends labels Mar 16, 2025
The stubs don't return `Self` for all types, so `pyright` is right
@dangotbanned dangotbanned marked this pull request as ready for review March 16, 2025 22:44
@dangotbanned
Copy link
Member Author

I tried for about 30 mins to get PandasLikeDataframe[DataFrameT] working.

Throwing in the towel on that for now 😞

mypy yelling

narwhals\_pandas_like\utils.py:819: error: Redundant cast to "DataFrame"  [redundant-cast]
        return cast("DataFrameT", result)
               ^
narwhals\_pandas_like\dataframe.py:233: error: Call to untyped function "get_indexer" in typed context  [no-untyped-call]
                        self._native_frame.columns.get_indexer(item[1]),
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:352: error: Incompatible return value type (got "list[dict[Hashable, Any]]", expected "list[tuple[Any, ...]] | list[dict[str, Any]]")  [return-value]
            return self._native_frame.to_dict(orient="records")  # pyright: ignore[reportReturnType]
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:389: error: Argument 1 to "object_native_to_narwhals_dtype" has incompatible type "Series[Any]"; expected "PandasLikeSeries"  [arg-type]
                    self._native_frame[col],  # pyright: ignore[reportArgumentType]
                    ^~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:411: error: Return type "PandasLikeDataFrame[DataFrame]" of "select" incompatible with return type "PandasLikeDataFrame[DataFrameT]" in supertype "CompliantDataFrame"  [override]
        def select(self: PandasLikeDataFrame, *exprs: PandasLikeExpr) -> PandasLikeDataFrame:
        ^
narwhals\_pandas_like\dataframe.py:426: error: Return type "PandasLikeDataFrame[DataFrame]" of "drop_nulls" incompatible with return type "PandasLikeDataFrame[DataFrameT]" in supertype "CompliantDataFrame"  [override]
        def drop_nulls(
        ^
narwhals\_pandas_like\dataframe.py:457: error: Return type "PandasLikeDataFrame[DataFrame]" of "filter" incompatible with return type "PandasLikeDataFrame[DataFrameT]" in supertype "CompliantDataFrame"  [override]
        def filter(
        ^
narwhals\_pandas_like\dataframe.py:533: error: No overload variant of "sort_values" of "DataFrame" matches argument types "list[str]", "bool | list[bool]", "str"  [call-overload]
                df.sort_values(list(by), ascending=ascending, na_position=na_position),
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:533: note: Possible overload variants:
narwhals\_pandas_like\dataframe.py:533: note:     def sort_values(self, by: str | Sequence[str], *, axis: Literal['index', 0] | Literal['columns', 1] = ..., ascending: bool | Sequence[bool] = ..., kind: Literal['quicksort', 'mergesort', 'heapsort', 'stable'] = ..., na_position: Literal['first', 'last'] = ..., ignore_index: bool = ..., inplace: Literal[True], key: Callable[..., Any] | None = ...) -> None
narwhals\_pandas_like\dataframe.py:533: note:     def sort_values(self, by: str | Sequence[str], *, axis: Literal['index', 0] | Literal['columns', 1] = ..., ascending: bool | Sequence[bool] = ..., kind: Literal['quicksort', 'mergesort', 'heapsort', 'stable'] = ..., na_position: Literal['first', 'last'] = ..., ignore_index: bool = ..., inplace: Literal[False] = ..., key: Callable[..., Any] | None = ...) -> DataFrame
narwhals\_pandas_like\dataframe.py:641: error: Argument "how" to "merge" of "DataFrame" has incompatible type "Literal['leftanti']"; expected "Literal['left', 'right', 'outer', 'inner'] | Literal['cross']"  [arg-type]
                            how="leftanti",  # pyright: ignore[reportArgumentType]
                                ^~~~~~~~~~
narwhals\_pandas_like\dataframe.py:781: error: No overload variant of "drop_duplicates" of "DataFrame" matches argument types "Sequence[str] | None", "object"  [call-overload]
                self._native_frame.drop_duplicates(subset=subset, keep=mapped_keep),
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:781: note: Possible overload variants:
narwhals\_pandas_like\dataframe.py:781: note:     def drop_duplicates(self, subset: Hashable | Iterable[Hashable] | None = ..., *, keep: Literal['first', 'last'] | bool = ..., inplace: Literal[True], ignore_index: bool = ...) -> None       
narwhals\_pandas_like\dataframe.py:781: note:     def drop_duplicates(self, subset: Hashable | Iterable[Hashable] | None = ..., *, keep: Literal['first', 'last'] | bool = ..., inplace: Literal[False] = ..., ignore_index: bool = ...) -> DataFrame
narwhals\_pandas_like\dataframe.py:840: error: Incompatible return value type (got "dict[Hashable, Any]", expected "dict[str, Any]")  [return-value]
            return self._native_frame.to_dict(orient="list")  # pyright: ignore[reportReturnType]
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:896: error: "Series[Any]" not callable  [operator]
                return self._native_frame.to_pandas()  # pyright: ignore[reportCallIssue]
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:898: error: "Series[Any]" not callable  [operator]
                return self._native_frame._to_pandas()  # pyright: ignore[reportCallIssue]
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:908: error: "Series[Any]" not callable  [operator]
                return pl.from_pandas(self._native_frame.to_pandas())  # pyright: ignore[reportCallIssue]
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:910: error: "Series[Any]" not callable  [operator]
                return pl.from_pandas(self._native_frame._to_pandas())  # pyright: ignore[reportCallIssue]
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:989: error: Expected iterable as variadic argument  [misc]
                values = [c for c in self.columns if c not in {*on, *index}]
                                                              ^~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:995: error: Expected iterable as variadic argument  [misc]
                    frame.groupby([*on, *index])
                                  ^~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1012: error: "ndarray[Any, Any]" has no attribute "to_arrow"  [attr-defined]
                    col: sorted(self._native_frame[col].unique().to_arrow().to_pylist())  # pyright: ignore[reportAttributeAccessIssue]
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1021: error: "ndarray[Any, Any]" has no attribute "to_arrow"  [attr-defined]
                    col: self._native_frame[col].unique().to_arrow().to_pylist()  # pyright: ignore[reportAttributeAccessIssue]
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1025: error: Value expression in dictionary comprehension has incompatible type "str"; expected type "list[Any]"  [misc]
                uniques = {col: self._native_frame[col].unique().tolist() for col in on}
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1043: error: Incompatible types in assignment (expression has type "list[str]", variable has type "Index[str]")  [assignment]
            result.columns = new_columns
                             ^~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1049: error: "Series[Any]" not callable  [operator]
                return self._native_frame.to_arrow(preserve_index=False)  # pyright: ignore[reportCallIssue]
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1120: error: Cannot determine type of "other_columns"  [has-type]
                exploded_frame = native_frame[[*other_columns, columns[0]]].explode(
                                                ^~~~~~~~~~~~~
narwhals\_pandas_like\dataframe.py:1129: error: Cannot determine type of "exploded_series"  [has-type]
                    plx.concat([exploded_frame, *exploded_series], axis=1)[original_columns],
                                                 ^~~~~~~~~~~~~~~
narwhals\_pandas_like\group_by.py:68: error: Need type annotation for "_grouped"  [var-annotated]
                self._grouped = native_frame.groupby(
                                ^
narwhals\_pandas_like\expr.py:267: error: No overload variant of "groupby" of "DataFrame" matches argument type "Sequence[str]"  [call-overload]
                        rolling = df._native_frame.groupby(partition_by)[  # pyright: ignore[reportArgumentType, reportCallIssue]
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\expr.py:267: note: Possible overload variants:
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: str | bytes | date | datetime | timedelta | <7 more items> | complex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] 
| None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[str | bytes | date | datetime | timedelta | <7 more items> | complex, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: str | bytes | date | datetime | timedelta | <7 more items> | complex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] 
| None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[str | bytes | date | datetime | timedelta | <7 more items> | complex, Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: DatetimeIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timestamp, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: DatetimeIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timestamp, Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: TimedeltaIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timedelta, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: TimedeltaIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timedelta, Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: PeriodIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Period, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: PeriodIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool 
= ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Period, Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def [IntervalT: Interval[Any]] groupby(self, by: IntervalIndex[IntervalT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[IntervalT, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def [IntervalT: Interval[Any]] groupby(self, by: IntervalIndex[IntervalT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[IntervalT, Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: MultiIndex | tuple[Any, ...] | list[Any] | ufunc | Callable[..., Any] | list[ufunc | Callable[..., Any]] | list[Series[Any]] | <7 more items> | None = ..., axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[tuple[Any, ...], Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: MultiIndex | tuple[Any, ...] | list[Any] | ufunc | Callable[..., Any] | list[ufunc | Callable[..., Any]] | list[Series[Any]] | <7 more items> | None = ..., axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[tuple[Any, ...], Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def [SeriesByT: str | bytes | date | bool | int | <6 more items>] groupby(self, by: Series[SeriesByT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[SeriesByT, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def [SeriesByT: str | bytes | date | bool | int | <6 more items>] groupby(self, by: Series[SeriesByT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[SeriesByT, Literal[False]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: CategoricalIndex[Any] | Index[Any] | Series[Any], axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Any, Literal[True]]
narwhals\_pandas_like\expr.py:267: note:     def groupby(self, by: CategoricalIndex[Any] | Index[Any] | Series[Any], axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Any, Literal[False]]
narwhals\_pandas_like\expr.py:273: error: No overload variant of "groupby" of "DataFrame" matches argument type "Sequence[str]"  [call-overload]
                        res_native = df._native_frame.groupby(partition_by)[  # pyright: ignore[reportArgumentType, reportCallIssue]
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
narwhals\_pandas_like\expr.py:273: note: Possible overload variants:
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: str | bytes | date | datetime | timedelta | <7 more items> | complex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] 
| None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[str | bytes | date | datetime | timedelta | <7 more items> | complex, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: str | bytes | date | datetime | timedelta | <7 more items> | complex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] 
| None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[str | bytes | date | datetime | timedelta | <7 more items> | complex, Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: DatetimeIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timestamp, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: DatetimeIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timestamp, Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: TimedeltaIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timedelta, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: TimedeltaIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Timedelta, Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: PeriodIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Period, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: PeriodIndex, axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool 
= ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Period, Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def [IntervalT: Interval[Any]] groupby(self, by: IntervalIndex[IntervalT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[IntervalT, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def [IntervalT: Interval[Any]] groupby(self, by: IntervalIndex[IntervalT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[IntervalT, Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: MultiIndex | tuple[Any, ...] | list[Any] | ufunc | Callable[..., Any] | list[ufunc | Callable[..., Any]] | list[Series[Any]] | <7 more items> | None = ..., axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[tuple[Any, ...], Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: MultiIndex | tuple[Any, ...] | list[Any] | ufunc | Callable[..., Any] | list[ufunc | Callable[..., Any]] | list[Series[Any]] | <7 more items> | None = ..., axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[tuple[Any, ...], Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def [SeriesByT: str | bytes | date | bool | int | <6 more items>] groupby(self, by: Series[SeriesByT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[SeriesByT, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def [SeriesByT: str | bytes | date | bool | int | <6 more items>] groupby(self, by: Series[SeriesByT], axis: Literal['index', 0, _NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[SeriesByT, Literal[False]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: CategoricalIndex[Any] | Index[Any] | Series[Any], axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[True] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Any, Literal[True]]
narwhals\_pandas_like\expr.py:273: note:     def groupby(self, by: CategoricalIndex[Any] | Index[Any] | Series[Any], axis: Literal['index', 0] | Literal[_NoDefault.no_default] = ..., level: Hashable | Sequence[Hashable] | None = ..., as_index: Literal[False] = ..., sort: bool = ..., group_keys: bool = ..., observed: bool | Literal[_NoDefault.no_default] = ..., dropna: bool = ...) -> DataFrameGroupBy[Any, Literal[False]]
Found 27 errors in 4 files (checked 355 source files)

@MarcoGorelli
Copy link
Member

does this make any user-facing difference? if not, then internally i think i'd prefer to just use pandas, as modin doesn't export types, neither does cudf

@dangotbanned
Copy link
Member Author

does this make any user-facing difference? if not, then internally i think i'd prefer to just use pandas

Right now - it doesn't even make an internal difference, since we don't type PandasLikeDataFrame.native.

The general idea is this:

SeriesT = TypeVar(
    "SeriesT", pd.Series[Any], mpd.Series, cudf.Series[Any], default=pd.Series[Any]
)

Means exactly one of those types, defaulting to pd.Series[Any] instead of Unknown.

I think that theoretically describes what you'd want - and accounts for missing imports for non-pandas.

However ...

as modin doesn't export types, neither does cudf

@MarcoGorelli well that certainly throws a spanner into this whole idea πŸ˜„

Note

This is low-priority, mainly just wanting to be able to get some IDE feedback to understand the current code better

@dangotbanned
Copy link
Member Author

Closing in favor of the simpler (pandas-only) version in #2368

dangotbanned added a commit that referenced this pull request Jun 21, 2025
- Somewhat of a resurrection of #2227
- But this time building on #2693
MarcoGorelli pushed a commit that referenced this pull request Jun 26, 2025
* chore(typing): Kinda type `pandas_like.utils.`select_columns_by_name`

- Somewhat of a resurrection of #2227
- But this time building on #2693

* chore(typing): "Fix" `pandas_like.utils.(set_index|rename)`

* chore(typing): `NativeSeriesT` in `calculate_timestamp_date`

Confused why this (seemingly unrelated) change triggered the `[has-type]` in `concat_str`

* chore: `NativeSeriesT` in `calculate_timestamp_datetime`

* fix(typing): Flip operands, use `ndarray.all`

Resolves #2714 (comment)
Did this before in https://github.com/narwhals-dev/narwhals/blob/0f37267b3d05b8f5d7a37ef8f0b43647f4afec48/narwhals/_pandas_like/utils.py#L767
@dangotbanned dangotbanned deleted the pandas-like-type-var branch September 2, 2025 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix low priority pandas-like Issue is related to pandas-like backends typing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants