@@ -31,54 +31,95 @@ def ignore_xlrd_time_clock_warning():
31
31
yield
32
32
33
33
34
+ read_ext_params = [".xls" , ".xlsx" , ".xlsm" , ".ods" ]
35
+ engine_params = [
36
+ # Add any engines to test here
37
+ # When defusedxml is installed it triggers deprecation warnings for
38
+ # xlrd and openpyxl, so catch those here
39
+ pytest .param (
40
+ "xlrd" ,
41
+ marks = [
42
+ td .skip_if_no ("xlrd" ),
43
+ pytest .mark .filterwarnings ("ignore:.*(tree\\ .iter|html argument)" ),
44
+ ],
45
+ ),
46
+ pytest .param (
47
+ "openpyxl" ,
48
+ marks = [
49
+ td .skip_if_no ("openpyxl" ),
50
+ pytest .mark .filterwarnings ("ignore:.*html argument" ),
51
+ ],
52
+ ),
53
+ pytest .param (
54
+ None ,
55
+ marks = [
56
+ td .skip_if_no ("xlrd" ),
57
+ pytest .mark .filterwarnings ("ignore:.*(tree\\ .iter|html argument)" ),
58
+ ],
59
+ ),
60
+ pytest .param ("odf" , marks = td .skip_if_no ("odf" )),
61
+ ]
62
+
63
+
64
+ def _is_valid_engine_ext_pair (engine , read_ext : str ) -> bool :
65
+ """
66
+ Filter out invalid (engine, ext) pairs instead of skipping, as that
67
+ produces 500+ pytest.skips.
68
+ """
69
+ engine = engine .values [0 ]
70
+ if engine == "openpyxl" and read_ext == ".xls" :
71
+ return False
72
+ if engine == "odf" and read_ext != ".ods" :
73
+ return False
74
+ if read_ext == ".ods" and engine != "odf" :
75
+ return False
76
+ return True
77
+
78
+
79
+ def _transfer_marks (engine , read_ext ):
80
+ """
81
+ engine gives us a pytest.param objec with some marks, read_ext is just
82
+ a string. We need to generate a new pytest.param inheriting the marks.
83
+ """
84
+ values = engine .values + (read_ext ,)
85
+ new_param = pytest .param (values , marks = engine .marks )
86
+ return new_param
87
+
88
+
34
89
@pytest .fixture (
90
+ autouse = True ,
35
91
params = [
36
- # Add any engines to test here
37
- # When defusedxml is installed it triggers deprecation warnings for
38
- # xlrd and openpyxl, so catch those here
39
- pytest .param (
40
- "xlrd" ,
41
- marks = [
42
- td .skip_if_no ("xlrd" ),
43
- pytest .mark .filterwarnings ("ignore:.*(tree\\ .iter|html argument)" ),
44
- ],
45
- ),
46
- pytest .param (
47
- "openpyxl" ,
48
- marks = [
49
- td .skip_if_no ("openpyxl" ),
50
- pytest .mark .filterwarnings ("ignore:.*html argument" ),
51
- ],
52
- ),
53
- pytest .param (
54
- None ,
55
- marks = [
56
- td .skip_if_no ("xlrd" ),
57
- pytest .mark .filterwarnings ("ignore:.*(tree\\ .iter|html argument)" ),
58
- ],
59
- ),
60
- pytest .param ("odf" , marks = td .skip_if_no ("odf" )),
61
- ]
92
+ _transfer_marks (eng , ext )
93
+ for eng in engine_params
94
+ for ext in read_ext_params
95
+ if _is_valid_engine_ext_pair (eng , ext )
96
+ ],
62
97
)
63
- def engine (request ):
98
+ def engine_and_read_ext (request ):
64
99
"""
65
- A fixture for Excel reader engines .
100
+ Fixture for Excel reader engine and read_ext, only including valid pairs .
66
101
"""
67
102
return request .param
68
103
69
104
105
+ @pytest .fixture
106
+ def engine (engine_and_read_ext ):
107
+ engine , read_ext = engine_and_read_ext
108
+ return engine
109
+
110
+
111
+ @pytest .fixture
112
+ def read_ext (engine_and_read_ext ):
113
+ engine , read_ext = engine_and_read_ext
114
+ return read_ext
115
+
116
+
70
117
class TestReaders :
71
118
@pytest .fixture (autouse = True )
72
- def cd_and_set_engine (self , engine , datapath , monkeypatch , read_ext ):
119
+ def cd_and_set_engine (self , engine , datapath , monkeypatch ):
73
120
"""
74
121
Change directory and set engine for read_excel calls.
75
122
"""
76
- if engine == "openpyxl" and read_ext == ".xls" :
77
- pytest .skip ()
78
- if engine == "odf" and read_ext != ".ods" :
79
- pytest .skip ()
80
- if read_ext == ".ods" and engine != "odf" :
81
- pytest .skip ()
82
123
83
124
func = partial (pd .read_excel , engine = engine )
84
125
monkeypatch .chdir (datapath ("io" , "data" , "excel" ))
@@ -806,16 +847,10 @@ def test_read_excel_squeeze(self, read_ext):
806
847
807
848
class TestExcelFileRead :
808
849
@pytest .fixture (autouse = True )
809
- def cd_and_set_engine (self , engine , datapath , monkeypatch , read_ext ):
850
+ def cd_and_set_engine (self , engine , datapath , monkeypatch ):
810
851
"""
811
852
Change directory and set engine for ExcelFile objects.
812
853
"""
813
- if engine == "odf" and read_ext != ".ods" :
814
- pytest .skip ()
815
- if read_ext == ".ods" and engine != "odf" :
816
- pytest .skip ()
817
- if engine == "openpyxl" and read_ext == ".xls" :
818
- pytest .skip ()
819
854
820
855
func = partial (pd .ExcelFile , engine = engine )
821
856
monkeypatch .chdir (datapath ("io" , "data" , "excel" ))
0 commit comments