
pytest 7 起已弃用 `py.path.local`(包括 `fspath` 参数),8.0 版本将彻底移除;虽非强制要求你项目中所有路径逻辑立即改用 `pathlib`,但测试框架内部路径接口已全面转向 `pathlib.path`,为保障兼容性与长期可维护性,迁移至 `pathlib` 是必要之举。
pytest 自 7.0 版本起正式开启从 py.path.local 到标准库 pathlib.Path 的迁移进程。核心变化在于:测试节点(如 Function、Class、Module)构造器中原本接受 fspath: py.path.local 的参数已被标记为废弃,取而代之的是统一要求传入 path: pathlib.Path 实例。你遇到的 PytestRemovedIn8Warning 正是这一过渡的关键信号——它并非仅影响 pytest 内部实现,更会波及任何显式依赖 py.path.local 或旧版路径对象(如通过 path.py 库创建的 path 对象)参与测试收集、插件开发或自定义 Item 构造的代码。
⚠️ 需明确:
- path.py 库本身未被 pytest 强制禁用,你仍可在测试逻辑中使用它做路径计算(如 Path("data") / "input.txt");
- 但只要它被传递给 pytest 的 Node 构造函数(例如 pytest.Function.from_parent(..., fspath=...))、或被用作 pytest 插件钩子(如 pytest_collect_file)的返回路径对象,就会触发警告并在 pytest 8 中报错。
✅ 正确迁移实践示例:
# ❌ 过时写法(触发 PytestRemovedIn8Warning)
from path import Path
import pytest
def test_with_old_path():
p = Path("tests/data/sample.json")
# 若此处 p 被意外传入 pytest 内部路径接口(如自定义 collector),将出问题
# ✅ 推荐写法:统一使用 pathlib.Path
from pathlib import Path
def test_with_pathlib():
p = Path("tests/data/sample.json")
assert p.exists()
# 所有路径操作均基于标准库,且与 pytest 8+ 完全兼容
# ✅ 自定义收集器中正确传参(关键!)
def pytest_collect_file(parent, file_path):
if file_path.suffix == ".json":
# ✅ file_path 已是 pathlib.Path(pytest 7+ 默认行为)
return JsonFile.from_parent(parent, path=file_path) # ← 使用 path=,而非 fspath=? 注意事项:
- 不要冻结 pytest 版本规避问题——这会阻碍安全更新与新特性接入;
- pathlib.Path 与 path.py 行为存在差异(如 Path("a") / "b" 返回 Path,而 path("a") / "b" 返回 path),批量替换需配合充分测试;
- 若使用第三方插件(如 pytest-datafiles、pytest-asyncio 等),请确认其已适配 pytest 7+/pathlib;旧版插件可能成为迁移阻塞点。
总结:迁移不是“推荐”,而是面向 pytest 8+ 的事实必需。尽早将测试代码中的路径对象统一为 pathlib.Path,不仅能消除警告、避免未来中断,更能提升代码标准化程度与跨环境鲁棒性。从 from path import Path 到 from pathlib import Path 的一行改动,是保障测试基础设施长期稳定的关键一步。










