|
5 | 5 | from importlib.util import find_spec |
6 | 6 | from typing import TYPE_CHECKING |
7 | 7 | from typing import Any |
| 8 | +from typing import Callable |
8 | 9 | from typing import Iterable |
9 | 10 | from typing import Literal |
10 | 11 | from typing import cast |
|
18 | 19 |
|
19 | 20 | if TYPE_CHECKING: |
20 | 21 | from typing_extensions import Self |
| 22 | + from typing_extensions import assert_type |
21 | 23 |
|
22 | 24 | from narwhals.utils import Version |
23 | 25 |
|
@@ -360,10 +362,63 @@ def test_from_native_lazyframe() -> None: |
360 | 362 | stable_lazy = nw.from_native(lf_pl) |
361 | 363 | unstable_lazy = unstable_nw.from_native(lf_pl) |
362 | 364 | if TYPE_CHECKING: |
363 | | - from typing_extensions import assert_type |
364 | | - |
365 | 365 | assert_type(stable_lazy, nw.LazyFrame[pl.LazyFrame]) |
366 | 366 | assert_type(unstable_lazy, unstable_nw.LazyFrame[pl.LazyFrame]) |
367 | 367 |
|
368 | 368 | assert isinstance(stable_lazy, nw.LazyFrame) |
369 | 369 | assert isinstance(unstable_lazy, unstable_nw.LazyFrame) |
| 370 | + |
| 371 | + |
| 372 | +def test_series_recursive() -> None: |
| 373 | + """https://github.com/narwhals-dev/narwhals/issues/2239.""" |
| 374 | + pytest.importorskip("polars") |
| 375 | + import polars as pl |
| 376 | + |
| 377 | + pl_series = pl.Series(name="test", values=[1, 2, 3]) |
| 378 | + nw_series = unstable_nw.from_native(pl_series, series_only=True) |
| 379 | + with pytest.raises(AssertionError): |
| 380 | + unstable_nw.Series(nw_series, level="full") |
| 381 | + |
| 382 | + nw_series_early_return = unstable_nw.from_native(nw_series, series_only=True) |
| 383 | + |
| 384 | + if TYPE_CHECKING: |
| 385 | + assert_type(pl_series, pl.Series) |
| 386 | + assert_type(nw_series, unstable_nw.Series[pl.Series]) |
| 387 | + |
| 388 | + nw_series_depth_2 = unstable_nw.Series(nw_series, level="full") # type: ignore[var-annotated] |
| 389 | + # NOTE: Checking that the type is `Series[Unknown]` |
| 390 | + assert_type(nw_series_depth_2, unstable_nw.Series) # type: ignore[type-arg] |
| 391 | + assert_type(nw_series_early_return, unstable_nw.Series[pl.Series]) |
| 392 | + |
| 393 | + |
| 394 | +def test_series_recursive_v1() -> None: |
| 395 | + """https://github.com/narwhals-dev/narwhals/issues/2239.""" |
| 396 | + pytest.importorskip("polars") |
| 397 | + import polars as pl |
| 398 | + |
| 399 | + pl_series = pl.Series(name="test", values=[1, 2, 3]) |
| 400 | + nw_series = nw.from_native(pl_series, series_only=True) |
| 401 | + with pytest.raises(AssertionError): |
| 402 | + nw.Series(nw_series, level="full") |
| 403 | + |
| 404 | + nw_series_early_return = nw.from_native(nw_series, series_only=True) |
| 405 | + |
| 406 | + if TYPE_CHECKING: |
| 407 | + assert_type(pl_series, pl.Series) |
| 408 | + assert_type(nw_series, nw.Series[pl.Series]) |
| 409 | + |
| 410 | + nw_series_depth_2 = nw.Series(nw_series, level="full") |
| 411 | + # NOTE: `Unknown` isn't possible for `v1`, as it has a `TypeVar` default |
| 412 | + assert_type(nw_series_depth_2, nw.Series[Any]) |
| 413 | + assert_type(nw_series_early_return, nw.Series[pl.Series]) |
| 414 | + |
| 415 | + |
| 416 | +@pytest.mark.parametrize("from_native", [unstable_nw.from_native, nw.from_native]) |
| 417 | +def test_from_native_invalid_keywords(from_native: Callable[..., Any]) -> None: |
| 418 | + pattern = r"from_native.+unexpected.+keyword.+bad_1" |
| 419 | + |
| 420 | + with pytest.raises(TypeError, match=pattern): |
| 421 | + from_native(data, bad_1="invalid") |
| 422 | + |
| 423 | + with pytest.raises(TypeError, match=pattern): |
| 424 | + from_native(data, bad_1="invalid", bad_2="also invalid") |
0 commit comments