doctest
,以确保我不向用户提供错误信息,因此我希望将其作为我的测试的一部分运行。我认为问题的根源并不是文档字符串本身,而是
doctest
模块如何读取我的扩展模块。如果我使用 Python2(对 Python2 编译的模块)运行 doctest
,则会得到我预期的输出:$ python -m doctest myext.so -v
...
1 items passed all tests:
98 tests in myext.so
98 tests in 1 items.
98 passed and 0 failed.
Test passed.
然而,当我使用Python3进行同样的操作时,我会遇到一个UnicodeDecodeError
错误:
$ python3 -m doctest myext3.so -v
Traceback (most recent call last):
...
File "/usr/local/Cellar/python3/3.3.3/Frameworks/Python.framework/Versions/3.3/lib/python3.3/doctest.py", line 223, in _load_testfile
return f.read(), filename
File "/usr/local/Cellar/python3/3.3.3/Frameworks/Python.framework/Versions/3.3/lib/python3.3/codecs.py", line 301, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcf in position 0: invalid continuation byte
为了获取更多信息,我使用完整的回溯信息通过
pytest
运行它:$ python3 -m pytest --doctest-glob "*.so" --full-trace
...
self = <encodings.utf_8.IncrementalDecoder object at 0x102ff5110>
input = b'\xcf\xfa\xed\xfe\x07\x00\x00\x01\x03\x00\x00\x00\x08\x00\x00\x00\r\x00\x00\x00\xd0\x05\x00\x00\x85\x00\x00\x00\x00\x...edString\x00_PyUnicode_FromString\x00_Py_BuildValue\x00__Py_FalseStruct\x00__Py_TrueStruct\x00dyld_stub_binder\x00\x00'
final = True
def decode(self, input, final=False):
# decode input (taking the buffer into account)
data = self.buffer + input
> (result, consumed) = self._buffer_decode(data, self.errors, final)
E UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcf in position 0: invalid continuation byte
/usr/local/Cellar/python3/3.3.3/Frameworks/Python.framework/Versions/3.3/lib/python3.3/codecs.py:301: UnicodeDecodeError
看起来doctest
实际上是读取.so
文件来获取文档字符串(而不是导入模块),但是Python3不知道如何解码输入。我可以尝试自己读取.so
文件并复制字节字符串和回溯信息来确认此事:
$ python3
Python 3.3.3 (default, Dec 10 2013, 20:13:18)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> open('myext3.so').read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.3.3/Frameworks/Python.framework/Versions/3.3/lib/python3.3/codecs.py", line 301, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcf in position 0: invalid continuation byte
>>> open('myext3.so', 'rb').read()
b'\xcf\xfa\xed\xfe\x07\x00\x00\x01\x03\x00\x00\x00\x08\x00\x00\x00\r\x00\x00\x00\xd0\x05...'
有其他人遇到过这个问题吗?是否有一种标准(或非标准)的方法可以让doctest
在Python3上执行C扩展模块的测试?
更新:我还应该补充一点,即我在Travis-CI上获得了相同的结果(请参见此处),因此它不是特定于我的本地构建。
doctest
,不知道它是一个内置模块。也许你的 PYTHONPATH 将版本 2 的模块放在版本 3 的模块之前了? - Mark Ransomsys.path
中硬编码的路径。此外,在第一个回溯中,您可以看到doctest.py
文件位于Python 3.3标准库位置,因此我不认为这是问题所在。感谢您的建议,请继续提供! - SethMMorton