我正在测试一个从 C 重写为 Python 的模块,并且遇到了我在职业生涯中见过的一个奇怪的错误。带有测试的有问题的 Python 代码只有三行:
# MATCHERS is a list of compiled regular expression objects defined as a
# global in the top level of the module
print dir(MATCHERS[0])
# diff.Differ is a class implemented in C with thed Python API; zoneA/B Words are
# lists and CompareLines, isJunk, and SetStaticLine are functions
differ = diff.Differ(zoneAWords, zoneBWords, CompareLines, isJunk, SetStaticLine)
# Causes a TypeError
dir(MATCHERS[0])
这三行产生以下输出:
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'findall', 'finditer', 'flags', 'groupindex', 'groups', 'match', 'pattern', 'scanner', 'search', 'split', 'sub', 'subn']
Traceback (most recent call last):
File "Diff.py", line 1032, in <module>
main()
File "Diff.py", line 1019, in main
diffs = CompareFiles(sys.argv[1], sys.argv[2])
File "Diff.py", line 584, in CompareFiles
print dir(MATCHERS[0])
TypeError: eqTest must be a function
在创建用 C 编写的对象之前打印已编译的正则表达式对象的 dir() 可以正常工作,但之后简单地使用 dir() 会导致 TypeError。据我所知, dir() 没有办法导致 TypeError。TypeError 和与之关联的消息来自我的代码,作为对象的 eqTest 字段的自定义 setter 函数的一部分,但是对 dir() 的调用当然不会尝试将 eqTest 设置为任何内容;它已经在上一行成功设置。
这一切都让我相信 C 代码中出现了问题,从而产生了这种奇怪的行为。我目前的假设是缓冲区溢出;写入超出数组的边界会改变导致这些错误的某些东西。(要求 MATCHERS[0] 匹配一个字符串只会使 Python 崩溃而没有错误消息)我已经检查了一段时间的初始化代码,只是想我会检查是否还有其他可能导致这种情况的原因。
我的代码太长,无法在此处包含,并且在此处的 Pastebin 上;您可以忽略第 434 行之后的所有内容,因为它尚未执行。