11from __future__ import annotations
22
33import re
4- from typing import TYPE_CHECKING , Any
4+ from typing import TYPE_CHECKING , Any , Literal
55
66import pandas as pd
77import pytest
2020
2121if TYPE_CHECKING :
2222 from collections .abc import Mapping
23+ from pathlib import Path
2324 from types import ModuleType
2425
26+ from typing_extensions import TypeAlias
27+
2528 from narwhals ._typing import EagerAllowed , _LazyOnly , _SparkLike
29+ from narwhals .typing import FileSource
30+
31+ IOSourceKind : TypeAlias = Literal ["str" , "Path" , "PathLike" ]
2632
2733data : Mapping [str , Any ] = {"a" : [1 , 2 , 3 ], "b" : [4.5 , 6.7 , 8.9 ], "z" : ["x" , "y" , "w" ]}
2834skipif_pandas_lt_1_5 = pytest .mark .skipif (
3238spark_like_backend = pytest .mark .parametrize ("backend" , ["pyspark" , "sqlframe" ])
3339
3440
35- @pytest .fixture (scope = "module" )
36- def csv_path (tmp_path_factory : pytest .TempPathFactory ) -> str :
41+ class MockPathLike :
42+ def __init__ (self , path : Path ) -> None :
43+ self ._super_secret : Path = path
44+
45+ def __fspath__ (self ) -> str :
46+ return self ._super_secret .__fspath__ ()
47+
48+
49+ def _into_file_source (source : Path , which : IOSourceKind , / ) -> FileSource :
50+ mapping : Mapping [IOSourceKind , FileSource ] = {
51+ "str" : str (source ),
52+ "Path" : source ,
53+ "PathLike" : MockPathLike (source ),
54+ }
55+ return mapping [which ]
56+
57+
58+ @pytest .fixture (scope = "module" , params = ["str" , "Path" , "PathLike" ])
59+ def csv_path (
60+ tmp_path_factory : pytest .TempPathFactory , request : pytest .FixtureRequest
61+ ) -> FileSource :
3762 fp = tmp_path_factory .mktemp ("data" ) / "file.csv"
38- filepath = str (fp )
39- pl .DataFrame (data ).write_csv (filepath )
40- return filepath
63+ pl .DataFrame (data ).write_csv (fp )
64+ return _into_file_source (fp , request .param )
4165
4266
43- @pytest .fixture (scope = "module" )
44- def parquet_path (tmp_path_factory : pytest .TempPathFactory ) -> str :
67+ @pytest .fixture (scope = "module" , params = ["str" , "Path" , "PathLike" ])
68+ def parquet_path (
69+ tmp_path_factory : pytest .TempPathFactory , request : pytest .FixtureRequest
70+ ) -> FileSource :
4571 fp = tmp_path_factory .mktemp ("data" ) / "file.parquet"
46- filepath = str (fp )
47- pl .DataFrame (data ).write_parquet (filepath )
48- return filepath
72+ pl .DataFrame (data ).write_parquet (fp )
73+ return _into_file_source (fp , request .param )
4974
5075
5176def assert_equal_eager (result : nw .DataFrame [Any ]) -> None :
@@ -62,23 +87,23 @@ def native_namespace(cb: Constructor, /) -> ModuleType:
6287 return nw .get_native_namespace (nw .from_native (cb (data ))) # type: ignore[no-any-return]
6388
6489
65- def test_read_csv (csv_path : str , eager_backend : EagerAllowed ) -> None :
90+ def test_read_csv (csv_path : FileSource , eager_backend : EagerAllowed ) -> None :
6691 assert_equal_eager (nw .read_csv (csv_path , backend = eager_backend ))
6792
6893
6994@skipif_pandas_lt_1_5
70- def test_read_csv_kwargs (csv_path : str ) -> None :
95+ def test_read_csv_kwargs (csv_path : FileSource ) -> None :
7196 assert_equal_eager (nw .read_csv (csv_path , backend = pd , engine = "pyarrow" ))
7297
7398
7499@lazy_core_backend
75- def test_read_csv_raise_with_lazy (csv_path : str , backend : _LazyOnly ) -> None :
100+ def test_read_csv_raise_with_lazy (backend : _LazyOnly ) -> None :
76101 pytest .importorskip (backend )
77102 with pytest .raises (ValueError , match = "Expected eager backend, found" ):
78- nw .read_csv (csv_path , backend = backend ) # type: ignore[arg-type]
103+ nw .read_csv ("unused.csv" , backend = backend ) # type: ignore[arg-type]
79104
80105
81- def test_scan_csv (csv_path : str , constructor : Constructor ) -> None :
106+ def test_scan_csv (csv_path : FileSource , constructor : Constructor ) -> None :
82107 kwargs : dict [str , Any ]
83108 if "sqlframe" in str (constructor ):
84109 kwargs = {"session" : sqlframe_session (), "inferSchema" : True , "header" : True }
@@ -91,29 +116,29 @@ def test_scan_csv(csv_path: str, constructor: Constructor) -> None:
91116
92117
93118@skipif_pandas_lt_1_5
94- def test_scan_csv_kwargs (csv_path : str ) -> None :
119+ def test_scan_csv_kwargs (csv_path : FileSource ) -> None :
95120 assert_equal_data (nw .scan_csv (csv_path , backend = pd , engine = "pyarrow" ), data )
96121
97122
98123@skipif_pandas_lt_1_5
99- def test_read_parquet (parquet_path : str , eager_backend : EagerAllowed ) -> None :
124+ def test_read_parquet (parquet_path : FileSource , eager_backend : EagerAllowed ) -> None :
100125 assert_equal_eager (nw .read_parquet (parquet_path , backend = eager_backend ))
101126
102127
103128@skipif_pandas_lt_1_5
104- def test_read_parquet_kwargs (parquet_path : str ) -> None :
129+ def test_read_parquet_kwargs (parquet_path : FileSource ) -> None :
105130 assert_equal_eager (nw .read_parquet (parquet_path , backend = pd , engine = "pyarrow" ))
106131
107132
108133@lazy_core_backend
109- def test_read_parquet_raise_with_lazy (parquet_path : str , backend : _LazyOnly ) -> None :
134+ def test_read_parquet_raise_with_lazy (backend : _LazyOnly ) -> None :
110135 pytest .importorskip (backend )
111136 with pytest .raises (ValueError , match = "Expected eager backend, found" ):
112- nw .read_parquet (parquet_path , backend = backend ) # type: ignore[arg-type]
137+ nw .read_parquet ("unused.parquet" , backend = backend ) # type: ignore[arg-type]
113138
114139
115140@skipif_pandas_lt_1_5
116- def test_scan_parquet (parquet_path : str , constructor : Constructor ) -> None :
141+ def test_scan_parquet (parquet_path : FileSource , constructor : Constructor ) -> None :
117142 kwargs : dict [str , Any ]
118143 if "sqlframe" in str (constructor ):
119144 kwargs = {"session" : sqlframe_session (), "inferSchema" : True }
@@ -126,16 +151,16 @@ def test_scan_parquet(parquet_path: str, constructor: Constructor) -> None:
126151
127152
128153@skipif_pandas_lt_1_5
129- def test_scan_parquet_kwargs (parquet_path : str ) -> None :
154+ def test_scan_parquet_kwargs (parquet_path : FileSource ) -> None :
130155 assert_equal_lazy (nw .scan_parquet (parquet_path , backend = pd , engine = "pyarrow" ))
131156
132157
133158@spark_like_backend
134159@pytest .mark .parametrize ("scan_method" , ["scan_csv" , "scan_parquet" ])
135160def test_scan_fail_spark_like_without_session (
136- parquet_path : str , backend : _SparkLike , scan_method : str
161+ backend : _SparkLike , scan_method : str
137162) -> None :
138163 pytest .importorskip (backend )
139164 pattern = re .compile (r"spark.+backend.+require.+session" , re .IGNORECASE )
140165 with pytest .raises (ValueError , match = pattern ):
141- getattr (nw , scan_method )(parquet_path , backend = backend )
166+ getattr (nw , scan_method )("unused.csv" , backend = backend )
0 commit comments