使用pytest运行shapely.geometry.box()触发Segmentation fault问题排查
Shapely代码在pytest中触发段错误但直接运行正常的问题分析
问题复现
- 以下代码通过pytest运行时抛出
Fatal Python error: Segmentation fault:
from shapely import geometry def test_geometry_box(self) -> None: geom = geometry.box(*[1, 2, 3, 4])
- 但将代码放在独立文件中直接运行完全正常:
from shapely import geometry geom = geometry.box(*[1, 2, 3, 4])
环境信息
- Shapely版本:1.8.4
- 安装方式:通过Poetry使用
Shapely = "^1"配置安装
栈追踪信息
.../test.py Fatal Python error: Segmentation fault Thread 0x000000030a67f000 (most recent call first): File ".../threading.py", line 316 in wait File ".../threading.py", line 581 in wait File ".../site-packages/tqdm/_monitor.py", line 60 in run File ".../threading.py", line 980 in _bootstrap_inner File ".../threading.py", line 937 in _bootstrap Current thread 0x00000002045dce00 (most recent call first): File ".../site-packages/shapely/geometry/polygon.py", line 539 in geos_polygon_from_py File ".../site-packages/shapely/geometry/polygon.py", line 261 in __init__ File ".../site-packages/shapely/geometry/geo.py", line 64 in box File "/test.py", line 55 in test_geometry_box File ".../site-packages/_pytest/python.py", line 192 in pytest_pyfunc_call File ".../site-packages/pluggy/_callers.py", line 39 in _multicall File ".../site-packages/pluggy/_manager.py", line 80 in _hookexec File ".../site-packages/pluggy/_hooks.py", line 265 in __call__ File ".../site-packages/_pytest/python.py", line 1761 in runtest File ".../site-packages/_pytest/runner.py", line 166 in pytest_runtest_call File ".../site-packages/pluggy/_callers.py", line 39 in _multicall File ".../site-packages/pluggy/_manager.py", line 80 in _hookexec File ".../site-packages/pluggy/_hooks.py", line 265 in __call__ File ".../site-packages/_pytest/runner.py", line 259 in <lambda> File ".../site-packages/_pytest/runner.py", line 338 in from_call File ".../site-packages/_pytest/runner.py", line 258 in call_runtest_hook File ".../site-packages/_pytest/runner.py", line 219 in call_and_report File ".../site-packages/_pytest/runner.py", line 130 in runtestprotocol File ".../site-packages/_pytest/runner.py", line 111 in pytest_runtest_protocol File ".../site-packages/pluggy/_callers.py", line 39 in _multicall File ".../site-packages/pluggy/_manager.py", line 80 in _hookexec File ".../site-packages/pluggy/_hooks.py", line 265 in __call__ File ".../site-packages/_pytest/main.py", line 347 in pytest_runtestloop File ".../site-packages/pluggy/_callers.py", line 39 in _multicall File ".../site-packages/pluggy/_manager.py", line 80 in _hookexec File ".../site-packages/pluggy/_hooks.py", line 265 in __call__ File ".../site-packages/_pytest/main.py", line 322 in _main File ".../site-packages/_pytest/main.py", line 268 in wrap_session File ".../site-packages/_pytest/main.py", line 315 in pytest_cmdline_main File ".../site-packages/pluggy/_callers.py", line 39 in _multicall File ".../site-packages/pluggy/_manager.py", line 80 in _hookexec File ".../site-packages/pluggy/_hooks.py", line 265 in __call__ File ".../site-packages/_pytest/config/__init__.py", line 164 in main File ".../site-packages/_pytest/config/__init__.py", line 187 in console_main File ".../pytest", line 8 in <module> zsh: segmentation fault pytest
原因分析
段错误发生在Shapely调用GEOS库创建多边形的底层逻辑中,仅在pytest环境触发的核心原因包括:
- 多线程环境冲突:pytest的测试运行机制(如默认线程复用、并行测试)与Shapely 1.8.4依赖的GEOS库线程安全机制不兼容。栈追踪中出现的
tqdm监控线程,可能引发GEOS资源访问的竞争冲突。 - 版本兼容性缺陷:Shapely 1.x系列存在已知的多线程环境下段错误问题,后续2.x版本重构了底层GEOS交互逻辑,已修复这类稳定性问题。
- 依赖版本不匹配:Poetry安装的依赖中,可能存在GEOS库与Shapely版本不兼容的情况,单线程直接运行时掩盖了冲突,但pytest的多线程/多进程环境触发了问题。
解决方案
- 升级Shapely版本:将Poetry依赖改为
Shapely = "^2.0",升级到2.x系列,彻底解决线程安全相关的底层问题。 - 禁用pytest并行机制:运行pytest时添加
-n 1参数强制单进程运行,或修改pytest.ini配置禁用并行测试,避免多线程环境触发GEOS的线程安全问题。 - 排除tqdm干扰:如果测试中用到
tqdm,可以设置环境变量TQDM_DISABLE_MONITOR=1临时禁用其监控线程,消除线程竞争诱因。
内容的提问来源于stack exchange,提问作者Jamie.Sgro
相关产品推荐
相关产品推荐

