@@ -56,20 +56,41 @@ def pytest_addoption(parser):
5656
5757@pytest .hookimpl (hookwrapper = True )
5858def pytest_runtest_call (item ):
59- """Convert pandas requirement exceptions to skips."""
59+ """Convert pandas requirement exceptions and missing pyarrow imports to skips."""
6060 outcome = yield
6161
6262 # TODO: Remove skip when Pandas releases for 3.14. After, consider bumping to 3.15 # noqa: TD002,TD003
6363 if sys .version_info [:2 ] == (3 , 14 ):
6464 try :
6565 outcome .get_result ()
66- except duckdb .InvalidInputException as e :
67- if "'pandas' is required for this operation but it was not installed" in str (e ):
68- pytest .skip ("pandas not available - test requires pandas functionality" )
66+ except (duckdb .InvalidInputException , ImportError ) as e :
67+ if isinstance (e , ImportError ) and e .name == "pyarrow" :
68+ pytest .skip (f"pyarrow not available - { item .name } requires pyarrow" )
69+ elif "'pandas' is required for this operation but it was not installed" in str (e ):
70+ pytest .skip (f"pandas not available - { item .name } requires pandas functionality" )
6971 else :
7072 raise
7173
7274
75+ @pytest .hookimpl (hookwrapper = True )
76+ def pytest_make_collect_report (collector ):
77+ """Wrap module collection to catch pyarrow import errors on Python 3.14.
78+
79+ If we're on Python 3.14 and a test module raises ModuleNotFoundError
80+ for 'pyarrow', mark the entire module as xfailed rather than failing collection.
81+ """
82+ outcome = yield
83+ result = outcome .get_result ()
84+
85+ if sys .version_info [:2 ] == (3 , 14 ):
86+ # Only handle failures from module collectors
87+ if result .failed and collector .__class__ .__name__ == "Module" :
88+ longrepr = str (result .longrepr )
89+ if "ModuleNotFoundError: No module named 'pyarrow'" in longrepr :
90+ result .outcome = "skipped"
91+ result .longrepr = f"XFAIL: pyarrow not available { collector .name } ({ longrepr .strip ()} )"
92+
93+
7394def pytest_collection_modifyitems (config , items ):
7495 tests_to_skip = config .getoption ("--skiplist" )
7596 if not tests_to_skip :
0 commit comments