简体   繁体   English

UnicodeDecodeError,在traceback.print_exc()内部包含sys.stdout

[英]UnicodeDecodeError with the sys.stdout inside traceback.print_exc()

I am getting UnicodeDecodeError with the traceback.print_exc(file=sys.stdout) . 我正在使用traceback.print_exc(file=sys.stdout)得到UnicodeDecodeError I am using Python3.4 and did not get the problem with Python2.7. 我正在使用Python3.4,但没有遇到Python2.7问题。

Am I missing something here? 我在这里想念什么吗? How can I make sure that sys.stdout passes the correct encoded/decoded to the traceback.print_exc() ? 如何确保sys.stdout将正确的编码/解码方式传递给traceback.print_exc()

My code looks something similar to this: 我的代码类似于以下内容:

try:
    # do something which might throw an exception
except Exception as e:
    # do something
    traceback.print_exc(file=sys.stdout) # Here I am getting the error

Error log: 错误日志:

  traceback.print_exc(file=sys.stdout)
  File "C:\Python34\lib\traceback.py", line 252, in print_exc
    print_exception(*sys.exc_info(), limit=limit, file=file, chain=chain)
  File "C:\Python34\lib\traceback.py", line 169, in print_exception
    for line in _format_exception_iter(etype, value, tb, limit, chain):
  File "C:\Python34\lib\traceback.py", line 153, in _format_exception_iter
    yield from _format_list_iter(_extract_tb_iter(tb, limit=limit))
  File "C:\Python34\lib\traceback.py", line 18, in _format_list_iter
    for filename, lineno, name, line in extracted_list:
  File "C:\Python34\lib\traceback.py", line 65, in _extract_tb_or_stack_iter
    line = linecache.getline(filename, lineno, f.f_globals)
  File "C:\Python34\lib\linecache.py", line 15, in getline
    lines = getlines(filename, module_globals)
  File "C:\Python34\lib\linecache.py", line 41, in getlines
    return updatecache(filename, module_globals)
  File "C:\Python34\lib\linecache.py", line 127, in updatecache
    lines = fp.readlines()
  File "C:\Python34\lib\codecs.py", line 313, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe7 in position 5213: invalid continuation byte

The traceback module wants to include source code lines with the traceback. 追溯模块希望在追溯中包括源代码行。 Normally, a traceback consists only of pointers to source code, not the source code itself, as Python has been executing the compiled bytecode. 通常,回溯仅包含指向源代码的指针,而不包含源代码本身,因为Python一直在执行已编译的字节码。 In the bytecode are hints as to exactly what source code line the bytecode came from. 字节码中有关于字节码来自哪个源代码行的提示。

To then show the sourcecode, the actual source is read from disk, using the linecache module. 为了显示源代码,使用linecache模块从磁盘读取实际源。 This also means that Python has to determine the encoding for those files too. 这也意味着Python也必须确定这些文件的编码。 The default encoding for a Python 3 source file is UTF-8, but you can set a PEP 263 comment to let Python know if you are deviating from that. Python 3源文件的默认编码为UTF-8,但是您可以设置PEP 263注释以让Python知道您是否对此有所偏离。

Because source code is read after the code is already loaded and a traceback took place, it is possible that you changed the source code after starting the script, or there was a byte cache file (in a __pycache__ subdirectory) that appeared to be fresh but was no longer matching your source files. 因为已经在加载代码并进行了追溯之后才读取源代码,所以有可能您在启动脚本之后更改了源代码, 或者有一个字节缓存文件(位于__pycache__子目录中)看起来很新鲜,但不再与您的源文件匹配。

Either way, when you started the script, Python was able to re-use a bytecache file or read the source code just fine and run your code. 无论哪种方式,启动脚本时,Python都可以重新使用字节缓存文件或很好地读取源代码并运行您的代码。 But when the traceback was being printed, at least one of the source code files was no longer decodable as UTF-8. 但是,在打印回溯时,至少其中一个源代码文件不再可解码为UTF-8。

If you can reliably reproduce the traceback (so start the Python script again without encoding problems but printing the traceback fails), it is most likely a stale bytecode file somewhere, one that could even hold pointers to a filename that now contains nothing but binary data, not plain source. 如果您可以可靠地重现追溯(因此,请重新启动Python脚本而不会出现编码问题,但是打印追溯失败),则它很可能是某个地方的旧字节码文件,甚至可以保存指向文件名的指针,该文件名现在仅包含二进制数据,不是简单的来源。

If you know how to use the pdb module , add a pdb.set_trace() call before the traceback.print_exc() call and trace what filenames are being loaded from by the linecache module. 如果您知道如何使用pdb模块 ,请在traceback.print_exc()调用之前添加pdb.set_trace()调用,并跟踪linecache模块正在从中加载哪些文件名。

Otherwise edit your C:\\Python34\\lib\\traceback.py file and insert a print('Loading {} from the linecache'.format(filename)) statement just before the linecache.checkcache(filename) line in the _extract_tb_or_stack_iter function. 否则,请编辑您的C:\\Python34\\lib\\traceback.py文件,并在_extract_tb_or_stack_iter函数的linecache.checkcache(filename)行之前插入print('Loading {} from the linecache'.format(filename))语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM