Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a5490c0
pyproject.toml
FBruzzesi Nov 17, 2025
54d2a25
ruff: narwhals, no zip
FBruzzesi Nov 17, 2025
0662940
ruff: tests, no zip
FBruzzesi Nov 17, 2025
c327000
rm zip_strict
FBruzzesi Nov 17, 2025
31b5dd7
zip(..., strict=False)
FBruzzesi Nov 17, 2025
3768e2c
rm Union[...]
FBruzzesi Nov 17, 2025
0bd10c7
bump min pandas & modin versions
FBruzzesi Nov 17, 2025
ebb1ace
ruff
FBruzzesi Nov 17, 2025
575731e
github actions
FBruzzesi Nov 17, 2025
a7f920b
merge main
FBruzzesi Nov 17, 2025
48a61a1
old pandas paths
FBruzzesi Nov 17, 2025
14acbe4
merge main
FBruzzesi Mar 30, 2026
bce15a0
simplify pandas-like scatter
FBruzzesi Mar 30, 2026
7fbddfa
merge main
FBruzzesi Apr 4, 2026
69ec76a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 4, 2026
6180766
merge main
FBruzzesi Apr 6, 2026
a42fe54
fix typing, thanks @dangotbanned
FBruzzesi Apr 7, 2026
3098143
merge main
FBruzzesi Apr 12, 2026
75c6c52
change pretty_old_versions pandas to 1.4.1 due to downcasting regression
FBruzzesi Apr 12, 2026
632e01b
rollback use of | in union types that require forward references
FBruzzesi Apr 12, 2026
5cd241e
Forgot to change assertion -- where is my mind?
FBruzzesi Apr 12, 2026
b170ecc
Merge branch 'main' into deps/bump-py310
dangotbanned Apr 13, 2026
06d8d2f
merge main, solve conflicts
FBruzzesi Apr 14, 2026
6b78515
Follow @dangotbanned suggestion for zip(..., strict=False)
FBruzzesi Apr 14, 2026
1b2af81
merge main, solve conflicts
FBruzzesi Apr 18, 2026
ff36aad
Merge branch 'main' into deps/bump-py310
FBruzzesi Apr 18, 2026
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 .github/workflows/downstream_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ jobs:
validoopsie:
strategy:
matrix:
python-version: ["3.9", "3.12"] # 3.9 and 3.12 are enough to cover all the tests
python-version: ["3.10", "3.13"] # these are enough to cover all the tests
os: ["ubuntu-latest"]
runs-on: ${{ matrix.os }}
steps:
Expand Down
42 changes: 32 additions & 10 deletions .github/workflows/extremes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
minimum_versions:
strategy:
matrix:
python-version: ["3.9"]
python-version: ["3.10"]
os: [ubuntu-latest]

runs-on: ${{ matrix.os }}
Expand All @@ -27,7 +27,18 @@ jobs:
cache-suffix: min-versions-${{ matrix.python-version }}
cache-dependency-glob: "pyproject.toml"
- name: install-minimum-versions
run: uv pip install pipdeptree tox virtualenv setuptools pandas==1.1.3 polars==0.20.4 numpy==1.19.3 pyarrow==13.0.0 "pyarrow-stubs<17" scipy==1.6.0 scikit-learn==1.1.0 duckdb==1.1 tzdata
run: |
uv pip install \
pipdeptree tox virtualenv setuptools tzdata \
pandas==1.3.4 \
polars==0.20.4 \
numpy==1.21.4 \
pyarrow==13.0.0 \
"pyarrow-stubs<17" \
scipy==1.7.3 \
scikit-learn==1.1.0 \
duckdb==1.1 \
--system
- name: install-reqs
run: |
uv pip install -e . --group tests
Expand All @@ -36,11 +47,11 @@ jobs:
- name: Assert dependencies
run: |
DEPS=$(uv pip freeze)
echo "$DEPS" | grep 'pandas==1.1.3'
echo "$DEPS" | grep 'pandas==1.3.4'
echo "$DEPS" | grep 'polars==0.20.4'
echo "$DEPS" | grep 'numpy==1.19.3'
echo "$DEPS" | grep 'numpy==1.21.4'
echo "$DEPS" | grep 'pyarrow==13.0.0'
echo "$DEPS" | grep 'scipy==1.6.0'
echo "$DEPS" | grep 'scipy==1.7.3'
echo "$DEPS" | grep 'scikit-learn==1.1.0'
echo "$DEPS" | grep 'duckdb==1.1'
- name: Run pytest
Expand All @@ -49,7 +60,7 @@ jobs:
pretty_old_versions:
strategy:
matrix:
python-version: ["3.9"]
python-version: ["3.10"]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -64,7 +75,18 @@ jobs:
cache-suffix: pretty-old-versions-${{ matrix.python-version }}
cache-dependency-glob: "pyproject.toml"
- name: install-pretty-old-versions
run: uv pip install pipdeptree tox virtualenv setuptools pandas==1.1.5 polars==0.20.4 numpy==1.19.3 pyarrow==14.0.0 "pyarrow-stubs<17" scipy==1.6.0 scikit-learn==1.1.0 duckdb==1.2 tzdata
run: |
uv pip install \
pipdeptree tox virtualenv setuptools tzdata \
pandas==1.4.1 \
polars==0.20.4 \
numpy==1.22.0 \
pyarrow==14.0.0 \
"pyarrow-stubs<17" \
scipy==1.8.0 \
scikit-learn==1.1.0 \
duckdb==1.2 \
--system
- name: install-reqs
run: uv pip install -e . --group tests
- name: show-deps
Expand All @@ -74,11 +96,11 @@ jobs:
- name: Assert pretty old versions dependencies
run : |
DEPS=$(uv pip freeze)
echo "$DEPS" | grep 'pandas==1.1.5'
echo "$DEPS" | grep 'pandas==1.4.1'
echo "$DEPS" | grep 'polars==0.20.4'
echo "$DEPS" | grep 'numpy==1.19.3'
echo "$DEPS" | grep 'numpy==1.22.0'
echo "$DEPS" | grep 'pyarrow==14.0.0'
echo "$DEPS" | grep 'scipy==1.6.0'
echo "$DEPS" | grep 'scipy==1.8.0'
echo "$DEPS" | grep 'scikit-learn==1.1.0'
echo "$DEPS" | grep 'duckdb==1.2'
- name: Run pytest
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ env:
PYTEST_ADDOPTS: "--numprocesses=logical"
UV_SYSTEM_PYTHON: 1
jobs:
pytest-39:
pytest-310:
strategy:
matrix:
python-version: ["3.9"]
python-version: ["3.10"]
os: [windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -23,7 +23,7 @@ jobs:
uses: astral-sh/setup-uv@v7
with:
enable-cache: "true"
cache-suffix: pytest-39-${{ matrix.python-version }}
cache-suffix: pytest-310-${{ matrix.python-version }}
cache-dependency-glob: "pyproject.toml"
- name: install-reqs
run: uv pip install -e ".[pandas,polars,pyarrow]" --group tests
Expand All @@ -37,7 +37,7 @@ jobs:
pytest-windows:
strategy:
matrix:
python-version: ["3.10", "3.12"]
python-version: ["3.10", "3.13"]
os: [windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/random_ci_pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
tox:
strategy:
matrix:
python-version: ["3.9"]
python-version: ["3.10"]
os: [ubuntu-latest]

runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ repos:
# TODO(unassigned): replace with ruff once https://github.com/astral-sh/ruff/issues/2302 is addressed.
name: flake8-typing-imports
alias: flake8-typing-imports
entry: flake8 --select TYP --min-python-version=3.9.0
entry: flake8 --select TYP --min-python-version=3.10.0
# Keep in sync with `darglint` so the same venv is reused.
additional_dependencies: [darglint==1.8.1, flake8-typing-imports==1.17.0]
- repo: local
Expand Down
12 changes: 6 additions & 6 deletions narwhals/_arrow/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
parse_columns_to_drop,
scale_bytes,
supports_arrow_c_stream,
zip_strict,
)
from narwhals.dependencies import is_numpy_array_1d
from narwhals.exceptions import ShapeError
Expand All @@ -35,10 +34,11 @@
from io import BytesIO
from pathlib import Path
from types import ModuleType
from typing import TypeAlias

import pandas as pd
import polars as pl
from typing_extensions import Self, TypeAlias, TypeIs
from typing_extensions import Self, TypeIs

from narwhals._arrow.expr import ArrowExpr
from narwhals._arrow.group_by import ArrowGroupBy
Expand Down Expand Up @@ -253,7 +253,7 @@ def rows(self, *, named: bool) -> list[tuple[Any, ...]] | list[dict[str, Any]]:
return self.native.to_pylist()

def iter_columns(self) -> Iterator[ArrowSeries]:
for name, series in zip_strict(self.columns, self.native.itercolumns()):
for name, series in zip(self.columns, self.native.itercolumns(), strict=True):
yield ArrowSeries.from_native(series, context=self, name=name)

_iter_columns = iter_columns
Expand All @@ -267,7 +267,7 @@ def iter_rows(
if not named:
for i in range(0, num_rows, buffer_size):
rows = df[i : i + buffer_size].to_pydict().values()
yield from zip_strict(*rows)
yield from zip(*rows, strict=True)
else:
for i in range(0, num_rows, buffer_size):
yield from df[i : i + buffer_size].to_pylist()
Expand Down Expand Up @@ -479,7 +479,7 @@ def sort(self, *by: str, descending: bool | Sequence[bool], nulls_last: bool) ->
else:
sorting = [
(key, "descending" if is_descending else "ascending")
for key, is_descending in zip_strict(by, descending)
for key, is_descending in zip(by, descending, strict=True)
]

null_placement = "at_end" if nulls_last else "at_start"
Expand All @@ -496,7 +496,7 @@ def top_k(self, k: int, *, by: Iterable[str], reverse: bool | Sequence[bool]) ->
else:
sorting = [
(key, "ascending" if is_ascending else "descending")
for key, is_ascending in zip_strict(by, reverse)
for key, is_ascending in zip(by, reverse, strict=True)
]
return self._with_native(
self.native.take(pc.select_k_unstable(self.native, k, sorting)), # type: ignore[call-overload]
Expand Down
2 changes: 1 addition & 1 deletion narwhals/_arrow/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def func(df: ArrowDataFrame) -> Sequence[ArrowSeries]: # noqa: PLR0914

group_keys: list[str] = []
encoded_cols: list[ArrowExpr] = []
for col_name, has_null in zip(partition_tbl.columns, has_nulls):
for col_name, has_null in zip(partition_tbl.columns, has_nulls, strict=False):
if not has_null:
group_keys.append(col_name)
else:
Expand Down
2 changes: 1 addition & 1 deletion narwhals/_arrow/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def agg(self, *exprs: ArrowExpr) -> ArrowDataFrame:
new_column_names = [new_column_names[i] for i in index_map]
result_simple = result_simple.rename_columns(new_column_names)
return self.compliant._with_native(result_simple).rename(
dict(zip(self._keys, self._output_key_names))
dict(zip(self._keys, self._output_key_names, strict=False))
)

def __iter__(self) -> Iterator[tuple[Any, ArrowDataFrame]]:
Expand Down
9 changes: 5 additions & 4 deletions narwhals/_arrow/series.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Callable, Literal, cast, overload
from typing import TYPE_CHECKING, Any, Literal, cast, overload

import pyarrow as pa
import pyarrow.compute as pc
Expand Down Expand Up @@ -37,12 +37,13 @@
from narwhals.exceptions import InvalidOperationError, ShapeError

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator, Sequence
from collections.abc import Callable, Iterable, Iterator, Sequence
from types import ModuleType
from typing import TypeAlias

import pandas as pd
import polars as pl
from typing_extensions import Self, TypeAlias, TypeIs
from typing_extensions import Self, TypeIs

from narwhals._arrow.dataframe import ArrowDataFrame
from narwhals._arrow.namespace import ArrowNamespace
Expand Down Expand Up @@ -203,7 +204,7 @@ def from_numpy(cls, data: Into1DArray, /, *, context: _LimitedContext) -> Self:
def _align_full_broadcast(cls, *series: Self) -> Sequence[Self]:
lengths = [len(s) for s in series]
target_length = max(
length for length, s in zip(lengths, series) if not s._broadcast
length for length, s in zip(lengths, series, strict=False) if not s._broadcast
)
fast_path = all(_len == target_length for _len in lengths)
if fast_path:
Expand Down
7 changes: 3 additions & 4 deletions narwhals/_arrow/series_dt.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Callable, ClassVar, cast
from typing import TYPE_CHECKING, Any, ClassVar, cast

import pyarrow as pa
import pyarrow.compute as pc
Expand All @@ -22,9 +22,8 @@
from narwhals._duration import Interval

if TYPE_CHECKING:
from collections.abc import Mapping

from typing_extensions import TypeAlias
from collections.abc import Callable, Mapping
from typing import TypeAlias

from narwhals._arrow.series import ArrowSeries
from narwhals._arrow.typing import ChunkedArrayAny, ScalarAny
Expand Down
8 changes: 1 addition & 7 deletions narwhals/_arrow/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@
)

if TYPE_CHECKING:
import sys
from typing import Generic, Literal

if sys.version_info >= (3, 10):
from typing import TypeAlias
else:
from typing_extensions import TypeAlias
from typing import Generic, Literal, TypeAlias

import pyarrow as pa
from pyarrow.__lib_pxi.table import (
Expand Down
4 changes: 2 additions & 2 deletions narwhals/_arrow/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator, Mapping
from typing import Literal
from typing import Literal, TypeAlias

from typing_extensions import TypeAlias, TypeIs
from typing_extensions import TypeIs

from narwhals._arrow.series import ArrowSeries
from narwhals._arrow.typing import (
Expand Down
2 changes: 1 addition & 1 deletion narwhals/_compliant/any_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from narwhals._utils import CompliantT_co, _StoresCompliant

if TYPE_CHECKING:
from typing import Callable
from collections.abc import Callable

from narwhals._compliant.typing import Accessor
from narwhals.typing import NonNestedLiteral, TimeUnit
Expand Down
9 changes: 7 additions & 2 deletions narwhals/_compliant/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@
from io import BytesIO
from pathlib import Path
from types import ModuleType
from typing import TypeAlias

import pandas as pd
import polars as pl
import pyarrow as pa
from typing_extensions import Self, TypeAlias
from typing_extensions import Self

from narwhals._compliant.group_by import CompliantGroupBy, DataFrameGroupBy
from narwhals._compliant.namespace import EagerNamespace
Expand Down Expand Up @@ -419,7 +420,11 @@ def __getitem__( # noqa: C901, PLR0912
return compliant.select()
if is_boolean_selector(columns):
compliant = compliant.simple_select(
*(col for col, select in zip(compliant.columns, columns) if select)
*(
col
for col, select in zip(compliant.columns, columns, strict=False)
if select
)
)
elif is_index_selector(columns):
if is_slice_index(columns) or is_range(columns):
Expand Down
Loading
Loading