IPython IFrame 接收 Path 后报 replace 参数错误,先转换再转义
IPython 对 IFrame 的地址做 HTML 转义时,旧实现会误调用 Path.replace。显式转成字符串或采用修复版本,再检查转义结果与实际页面加载。
把本地 HTML 路径交给 IFrame 后,Notebook 显示时报 TypeError: Path.replace() takes 2 positional arguments but 3 were given,可以先查 src 是否是 pathlib.Path。IPython 9.16.0 的一条回归路径会在生成 HTML 表示时触发这个错误,文件是否存在并不是这条异常的判断依据。
下面的写法原本可以用于表示本地页面:
from pathlib import Path
from IPython.display import IFrame
frame = IFrame(src=Path("report&a.html"), width=640, height=480)
html = frame._repr_html_()
这里显式调用 HTML 表示,只是为了定位显示阶段。正常 Notebook 可以由显示系统自动调用它;创建对象成功,不能证明接下来显示时也不会出错。
旧实现新增了对 src 的 html.escape 处理。这个函数需要字符串,并会调用字符串的 replace;Path 上同名的方法却是移动文件路径,参数合同完全不同。因此,异常里的 replace 不表示需要重命名 HTML 文件,也不该通过改权限来处理。
在转义之前转换地址
如果当前环境暂时不能更新,可以在自己的调用处明确传入字符串:
from pathlib import Path
from IPython.display import IFrame
path = Path("report&a.html")
frame = IFrame(src=str(path), width=640, height=480)
html = frame._repr_html_()
assert "report&a.html" in html
转换后仍要保留 HTML 转义。文件名含 & 时,生成 HTML 属性中的文字应为 &;让页面能够显示,不等于应把路径直接拼进未经转义的 HTML。
IPython 9.17.1 的正式代码已经在转义前执行 str(self.src)。对支持这份版本的项目环境,可按已有依赖流程固定并验收:
python -m pip install "ipython==9.17.1"
python -c "from importlib.metadata import version; print(version('ipython'))"
Notebook 内核与终端可能使用不同的解释器。更新后要核对内核环境,并重新启动仍加载旧模块的内核,再运行最初的 Path 输入,而不是只测改成字符串后的绕法。若 IFrame 来自分析工具生成的报告,也要通过该工具原有的显示入口检查,确认它确实使用了这套 IPython。
验收分两步:先确认 HTML 表示能生成,且含特殊字符的地址仍正确转义;再从 Notebook 实际加载预期页面。第二步若失败,要继续核对文件、相对路径和页面服务方式。str(Path) 不负责 URL 编码,也不会自动把一个本地路径变成浏览器能访问的地址。
这项修复针对 Path 与 HTML 转义接口的衔接,不保证任意对象都能作为地址。原环境的 Python、操作系统与上层报告工具版本没有明确给出,不能据此把所有 IFrame 显示失败都归到同一条回归。


