Skip to content
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
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ typing = [ # keep some of these pinned and bump periodically so there's fewer s
"pytest",
"pandas-stubs==2.3.0.250703",
"typing_extensions",
"mypy~=1.15.0",
"pyrefly==0.64.0",
"mypy==2.1.0",
"pyrefly==1.0.0",
Comment thread
dangotbanned marked this conversation as resolved.
"pyright",
"pyarrow-stubs==19.2",
"narwhals[dask]",
Expand Down Expand Up @@ -322,6 +322,7 @@ exclude_also = [
'if "(cudf|modin|pyspark|ibis)" in',
"if not .*.is_pandas",
"if is_ibis_table",
"if MYPY",
"except ModuleNotFoundError",
Comment thread
MarcoGorelli marked this conversation as resolved.
'request.applymarker\(pytest.mark.xfail',
'backend_version <',
Expand Down Expand Up @@ -386,6 +387,7 @@ ignore = [
"../../../**/Lib", # stdlib
"../../../**/typeshed*" # typeshed-fallback
]
defineConstant = { "MYPY" = false }

[tool.pyrefly]
search-path = ["src", "."]
Expand Down
6 changes: 5 additions & 1 deletion src/narwhals/_arrow/dataframe.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections.abc import Collection, Iterator, Mapping, Sequence
from typing import TYPE_CHECKING, Any, Literal, cast, overload
from typing import TYPE_CHECKING, Any, Final, Literal, cast, overload

import pyarrow as pa
import pyarrow.compute as pc
Expand Down Expand Up @@ -77,6 +77,8 @@
"full outer",
]

MYPY: Final = False


class ArrowDataFrame(
EagerDataFrame["ArrowSeries", "ArrowExpr", "pa.Table", "ChunkedArrayAny"]
Expand Down Expand Up @@ -320,6 +322,8 @@ def _select_multi_index(
# **Doesn't accept `ndarray`**
elif is_numpy_array_1d(columns):
selector = columns.tolist()
elif MYPY:
selector = columns # type: ignore[assignment]
else:
selector = columns
return self._with_native(self.native.select(selector))
Expand Down
19 changes: 16 additions & 3 deletions src/narwhals/_compliant/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from collections.abc import Iterator, Mapping, Sequence, Sized
from itertools import chain
from typing import TYPE_CHECKING, Any, Literal, Protocol, TypeVar, overload
from typing import TYPE_CHECKING, Any, Final, Literal, Protocol, TypeVar, overload

from narwhals._compliant.typing import (
CompliantDataFrameAny,
Expand Down Expand Up @@ -80,6 +80,8 @@

Incomplete: TypeAlias = Any

MYPY: Final = False

__all__ = ["CompliantDataFrame", "CompliantFrame", "CompliantLazyFrame", "EagerDataFrame"]

T = TypeVar("T")
Expand Down Expand Up @@ -434,11 +436,18 @@ def __getitem__( # noqa: C901, PLR0912
else:
compliant = compliant._select_multi_index(columns)
elif isinstance(columns, slice):
compliant = compliant._select_slice_name(columns)
if MYPY:
# https://github.com/python/mypy/issues/21508
compliant = compliant._select_slice_name(columns) # type: ignore[arg-type]
else:
compliant = compliant._select_slice_name(columns)
elif is_compliant_series(columns):
compliant = self._select_multi_name(columns.native)
elif is_sequence_like(columns):
compliant = self._select_multi_name(columns)
elif MYPY:
# https://github.com/python/mypy/issues/21508
pass
else:
assert_never(columns)

Expand All @@ -450,7 +459,11 @@ def __getitem__( # noqa: C901, PLR0912
elif is_compliant_series(rows):
compliant = compliant._gather(rows.native)
elif is_sized_multi_index_selector(rows):
compliant = compliant._gather(rows)
if MYPY: # noqa: SIM108
# https://github.com/python/mypy/issues/21508
compliant = compliant._gather(rows) # type: ignore[arg-type]
else:
compliant = compliant._gather(rows)
else:
assert_never(rows)

Expand Down
3 changes: 2 additions & 1 deletion src/narwhals/_compliant/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ def _remap_expr_name(
Arguments:
name: Name of a `nw.Expr` aggregation method.
"""
return cls._REMAP_AGGS.get(name, name)
result: NativeAggregationT_co = cls._REMAP_AGGS.get(name, name)
return result

@classmethod
def _leaf_name(cls, expr: DepthTrackingExprAny, /) -> NarwhalsAggregation | Any:
Expand Down
3 changes: 2 additions & 1 deletion src/narwhals/_compliant/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,8 @@ class EagerSeriesStructNamespace( # type: ignore[misc]
): ...


class EagerSeriesHist(Protocol[NativeSeriesT, _CountsT_co]):
# mypy says: `Covariant type variable "_CountsT_co" used in protocol where invariant one is expected`
class EagerSeriesHist(Protocol[NativeSeriesT, _CountsT_co]): # type: ignore[misc]
Comment thread
MarcoGorelli marked this conversation as resolved.
_series: EagerSeries[NativeSeriesT]
_breakpoint: bool
_data: HistData[NativeSeriesT, _CountsT_co]
Expand Down
4 changes: 2 additions & 2 deletions src/narwhals/_dask/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,5 +715,5 @@ def dt(self) -> DaskExprDateTimeNamespace:
last = not_implemented()

# namespaces
list: not_implemented = not_implemented() # type: ignore[assignment]
struct: not_implemented = not_implemented() # type: ignore[assignment]
list: Any = not_implemented()
struct: Any = not_implemented()
3 changes: 1 addition & 2 deletions src/narwhals/_duration.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ def to_timedelta(
msg = f"Creating timedelta with {self.unit} unit is not supported."
raise NotImplementedError(msg)
kwd = UNIT_TO_TIMEDELTA[self.unit]
# error: Keywords must be strings (bad mypy)
return dt.timedelta(**{kwd: self.multiple}) # type: ignore[misc]
Comment thread
MarcoGorelli marked this conversation as resolved.
return dt.timedelta(**{kwd: self.multiple})

@classmethod
def parse(cls, every: str) -> Interval:
Expand Down
2 changes: 1 addition & 1 deletion src/narwhals/_pandas_like/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ def pivot(
remapped = self._pivot_remap_column_names(
columns, n_on=len(on), n_values=len(values), separator=separator
)
result.columns = remapped # type: ignore[assignment]
Comment thread
MarcoGorelli marked this conversation as resolved.
result.columns = remapped
result.columns.names = [""]
return self._with_native(result.reset_index())

Expand Down
16 changes: 9 additions & 7 deletions src/narwhals/_polars/dataframe.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections.abc import Iterator, Mapping, Sequence, Sized
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeVar, cast, overload
from typing import TYPE_CHECKING, Any, Final, Generic, Literal, TypeVar, cast, overload

import polars as pl

Expand Down Expand Up @@ -64,6 +64,8 @@
T = TypeVar("T")
R = TypeVar("R")

MYPY: Final = False

Method: TypeAlias = "Callable[..., R]"
"""Generic alias representing all methods implemented via `__getattr__`.

Expand Down Expand Up @@ -222,7 +224,7 @@ def join(
return self._with_native(
self.native.join(
other=other.native,
how=how_native, # type: ignore[arg-type]
how=how_native,
left_on=left_on,
right_on=right_on,
suffix=suffix,
Expand Down Expand Up @@ -495,11 +497,11 @@ def __getitem__( # noqa: C901, PLR0912
else:
native = native[:, columns]
elif isinstance(columns, slice):
native = native.select(
self.columns[
slice(*convert_str_slice_to_int_slice(columns, self.columns))
]
)
if MYPY:
int_slice = convert_str_slice_to_int_slice(columns, self.columns) # type: ignore[arg-type]
else:
int_slice = convert_str_slice_to_int_slice(columns, self.columns)
native = native.select(self.columns[slice(*int_slice)])
elif is_compliant_series(columns):
native = native.select(columns.native.to_list())
elif is_sequence_like(columns):
Expand Down
2 changes: 1 addition & 1 deletion src/narwhals/_polars/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ class PolarsSelectorNamespace:
def __init__(self, context: _LimitedContext, /) -> None:
self._version = context._version

def by_dtype(self, dtypes: Iterable[DType]) -> PolarsExpr:
def by_dtype(self, dtypes: Iterable[IntoDType]) -> PolarsExpr:
native_dtypes = [
narwhals_to_native_dtype(dtype, self._version).__class__
if isinstance(dtype, type) and issubclass(dtype, DType)
Expand Down
4 changes: 2 additions & 2 deletions src/narwhals/_polars/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import abc
from functools import lru_cache
from typing import TYPE_CHECKING, Any, ClassVar, Final, Protocol, TypeVar, overload
from typing import TYPE_CHECKING, Any, ClassVar, Final, Protocol, TypeVar, cast, overload

import polars as pl

Expand Down Expand Up @@ -73,7 +73,7 @@ def extract_native(obj: _StoresNative[NativeT]) -> NativeT: ...
@overload
def extract_native(obj: T) -> T: ...
def extract_native(obj: _StoresNative[NativeT] | T) -> NativeT | T:
return obj.native if _is_compliant_polars(obj) else obj
return obj.native if _is_compliant_polars(obj) else cast("T", obj)


def _is_compliant_polars(
Expand Down
4 changes: 2 additions & 2 deletions test-plugin/test_plugin/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ def _with_version(self, version: Version) -> Self:
__native_namespace__ = not_implemented()

# Properties
schema = not_implemented() # type: ignore[assignment]
schema: Any = not_implemented()

# Static
_is_native = not_implemented() # type: ignore[assignment]
_is_native = not_implemented()

# Helpers
_iter_columns = not_implemented()
Expand Down
2 changes: 1 addition & 1 deletion tests/expr_and_series/over_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def test_over_anonymous_cumulative(
context = (
pytest.raises(NotImplementedError)
if df.implementation.is_pyarrow()
else pytest.raises(KeyError) # type: ignore[arg-type]
else pytest.raises(KeyError)
if df.implementation.is_modin()
or (df.implementation.is_pandas() and PANDAS_VERSION < (1, 3))
# TODO(unassigned): bug in old pandas + modin.
Expand Down
3 changes: 2 additions & 1 deletion tests/v1_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,8 @@ def __dataframe__(self) -> None: # pragma: no cover

mockdf = MockDf()
result = nw_v1.from_native(mockdf, eager_only=True, strict=False)
assert result is mockdf
# mypy issue?
assert result is mockdf # type: ignore[comparison-overlap]
Comment thread
MarcoGorelli marked this conversation as resolved.


def test_from_native_lazyframe() -> None:
Expand Down
Loading