You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法调试xml.etree.ElementTree及自定义XMLParser方法不生效排查

无法调试ElementTree类及自定义XMLParser子类方法不触发问题

问题场景

初始测试代码:

from xml.etree import ElementTree as ET

print(f"{ET.__file__}")
et = ET.parse("/tmp/pom.xml")
print(et)

输出:

/usr/local/Cellar/python@3.9/3.9.1_3/Frameworks/Python.framework/Versions/3.9/lib/python3.9/xml/etree/ElementTree.py
<xml.etree.ElementTree.ElementTree object at 0x10fef9a30>

尝试在ElementTree.py的XMLParser.__init__方法中设置断点,但断点完全未触发。随后在ElementTree.parse方法内添加断点:

def parse(self, source, parser=None):
    ...
    close_source = False
    if not hasattr(source, "read"):
        source = open(source, "rb")
        close_source = True
    try:
        if parser is None:
            # If no parser was specified, create a default XMLParser
            import pdb; pdb.set_trace()
            parser = XMLParser()
            if hasattr(parser, '_parse_whole'):

进入pdb交互后,尝试单步进入XMLParser()会直接跳到下一行。用inspect确认模块路径正确:

(Pdb) import inspect
(Pdb) inspect.getmodule(XMLParser)
<module 'xml.etree.ElementTree' from '/usr/local/Cellar/python@3.9/3.9.1_3/Frameworks/Python.framework/Versions/3.9/lib/python3.9/xml/etree/ElementTree.py'>

以上操作是为了排查自定义XMLParser子类的_start和_end方法未被调用的问题,子类代码如下:

class LineNumberingParser(ET.XMLParser):
    def _start(self, *args, **kwargs):
        element = super()._start(*args, **kwargs)
        element._start_line_number = self.parser.CurrentLineNumber
        print(f"----- {element.tag} {element._start_line_number}")
        return element

    def _end(self, *args, **kwargs):
        element = super()._end(*args, **kwargs)
        element._end_line_number = self.parser.CurrentLineNumber
        print(f"----- {element.tag} {element._end_line_number}")
        return element


parser = LineNumberingParser(target=ET.TreeBuilder(insert_comments=True))
et = ET.parse("/tmp/pom.xml", parser)

尝试给子类添加构造函数并单步进入父类构造方法,同样出现跳过行为,但能看到实例属性初始化正常(如self.target从None变为已初始化状态)。

排查更新

  1. 在XMLParser的__init__和_start等方法中添加print语句,完全无输出,说明实际运行的并非Python版本的实现,尽管inspect显示路径正确。
  2. 发现ElementTree.py模块末尾的代码:
# Import the C accelerators
try:
    # Element is going to be shadowed by the C implementation. We need to keep
    # the Python version of it accessible for some "creative" by external code
    # (see tests)
    _Element_Py = Element

    # Element, SubElement, ParseError, TreeBuilder, XMLParser, _set_factories
    from _elementtree import *
    from _elementtree import _set_factories
except ImportError:
    pass
else:
    _set_factories(Comment, ProcessingInstruction)

推测实际使用的是C原生实现,这就是pdb无法单步调试的原因。目前需要重新寻找获取XML元素行号的解决方案。
3. 找到测试模块中禁用C加速的逻辑,使用纯Python实现时,子类的_start和_end方法会被调用,但代码执行路径与C实现存在明显差异。

内容的提问来源于stack exchange,提问作者haridsv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:15:49