From 29009af4050fbc0c42a9a1aca3163cf1c6e29745 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Sat, 21 Jun 2025 11:16:29 +0100 Subject: [PATCH 1/3] chore(typing): Widen `_utils` signatures In light of (https://github.com/narwhals-dev/narwhals/issues/2706#issuecomment-2993481552) Splitting out a change from https://github.com/narwhals-dev/narwhals/blob/7bb0d0df3d2f75bc903aa9fc2abf0ecc5a61f432/narwhals/_utils.py#L1194 With that, I noticed a few others that also didn't need all the features of `Sequence` --- narwhals/_utils.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/narwhals/_utils.py b/narwhals/_utils.py index 09a6cfc0f2..93da5f2d9f 100644 --- a/narwhals/_utils.py +++ b/narwhals/_utils.py @@ -2,7 +2,7 @@ import os import re -from collections.abc import Container, Iterable, Iterator, Mapping, Sequence +from collections.abc import Collection, Container, Iterable, Iterator, Mapping, Sequence from datetime import timezone from enum import Enum, auto from functools import lru_cache, wraps @@ -1181,7 +1181,7 @@ def is_ordered_categorical(series: Series[Any]) -> bool: def generate_unique_token( - n_bytes: int, columns: Sequence[str] + n_bytes: int, columns: Container[str] ) -> str: # pragma: no cover msg = ( "Use `generate_temporary_column_name` instead. `generate_unique_token` is " @@ -1191,7 +1191,7 @@ def generate_unique_token( return generate_temporary_column_name(n_bytes=n_bytes, columns=columns) -def generate_temporary_column_name(n_bytes: int, columns: Sequence[str]) -> str: +def generate_temporary_column_name(n_bytes: int, columns: Container[str]) -> str: """Generates a unique column name that is not present in the given list of columns. It relies on [python secrets token_hex](https://docs.python.org/3/library/secrets.html#secrets.token_hex) @@ -1489,7 +1489,7 @@ def generate_repr(header: str, native_repr: str) -> str: def check_columns_exist( - subset: Sequence[str], /, *, available: Sequence[str] + subset: Collection[str], /, *, available: Collection[str] ) -> ColumnNotFoundError | None: if missing := set(subset).difference(available): return ColumnNotFoundError.from_missing_and_available_column_names( @@ -1498,7 +1498,7 @@ def check_columns_exist( return None -def check_column_names_are_unique(columns: Sequence[str]) -> None: +def check_column_names_are_unique(columns: Collection[str]) -> None: len_unique_columns = len(set(columns)) if len(columns) != len_unique_columns: from collections import Counter @@ -1622,7 +1622,7 @@ def supports_arrow_c_stream(obj: Any) -> TypeIs[ArrowStreamExportable]: def _remap_full_join_keys( - left_on: Sequence[str], right_on: Sequence[str], suffix: str + left_on: Collection[str], right_on: Collection[str], suffix: str ) -> dict[str, str]: """Remap join keys to avoid collisions. From 2aba1c81d82c2d2a42e3df0c37d6419d1c5cda7c Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Sat, 21 Jun 2025 11:18:21 +0100 Subject: [PATCH 2/3] fix(typing): Update propagated signatures The type here is dependent on `check_columns_exist` See https://github.com/narwhals-dev/narwhals/pull/2495#discussion_r2105807548 --- narwhals/exceptions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/narwhals/exceptions.py b/narwhals/exceptions.py index e9e7e3d26f..afb08fa8f3 100644 --- a/narwhals/exceptions.py +++ b/narwhals/exceptions.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from collections.abc import Iterable, Sequence + from collections.abc import Collection, Iterable class NarwhalsError(ValueError): @@ -35,7 +35,7 @@ def __init__(self, message: str) -> None: @classmethod def from_missing_and_available_column_names( - cls, missing_columns: Iterable[str], available_columns: Sequence[str], / + cls, missing_columns: Iterable[str], available_columns: Collection[str], / ) -> ColumnNotFoundError: message = ( f"The following columns were not found: {sorted(missing_columns)}" From bb1b0842a7f1255785da1759014fef6a38909a2f Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Sat, 21 Jun 2025 11:20:57 +0100 Subject: [PATCH 3/3] chore(typing): Remove now-unused type ignore `list[str] | _1DArray` is assignable to `Collection[str]` Previously, failed on `Sequence[str]` due to `numpy` --- narwhals/_pandas_like/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/narwhals/_pandas_like/utils.py b/narwhals/_pandas_like/utils.py index a2028bdd9d..5cea196b15 100644 --- a/narwhals/_pandas_like/utils.py +++ b/narwhals/_pandas_like/utils.py @@ -576,7 +576,7 @@ def select_columns_by_name( # See https://github.com/narwhals-dev/narwhals/issues/1349#issuecomment-2470118122 # for why we need this if error := check_columns_exist( - column_names, # type: ignore[arg-type] + column_names, available=df.columns.tolist(), # type: ignore[attr-defined] ): raise error @@ -585,7 +585,7 @@ def select_columns_by_name( return df[column_names] # type: ignore[index] except KeyError as e: if error := check_columns_exist( - column_names, # type: ignore[arg-type] + column_names, available=df.columns.tolist(), # type: ignore[attr-defined] ): raise error from e