如何调试 `ast.literal_eval` 中的错误?
How do I debug an error in `ast.literal_eval`?
我使用 pprint.PrettyPrinter
and I am trying to read it using ast.literal_eval
将数据写入文件。
这已经为我工作了很长一段时间,我对生成的文本表示相当满意。
但是,今天我在反序列化时遇到了这个错误:
File "/...mypath.../store.py", line 82, in <lambda>
reader=(lambda fd: ast.literal_eval(fd.read())),
File "/usr/lib64/python2.7/ast.py", line 80, in literal_eval
return _convert(node_or_string)
File "/usr/lib64/python2.7/ast.py", line 60, in _convert
return list(map(_convert, node.elts))
File "/usr/lib64/python2.7/ast.py", line 63, in _convert
in zip(node.keys, node.values))
File "/usr/lib64/python2.7/ast.py", line 62, in <genexpr>
return dict((_convert(k), _convert(v)) for k, v
File "/usr/lib64/python2.7/ast.py", line 63, in _convert
in zip(node.keys, node.values))
File "/usr/lib64/python2.7/ast.py", line 62, in <genexpr>
return dict((_convert(k), _convert(v)) for k, v
File "/usr/lib64/python2.7/ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string
如何修复这个特定文件?
有问题的文件是 17k lines/700kb。
我将它加载到 Emacs 中——括号是平衡的。
文件中没有非 ASCII 字符。
我可以 "divide and conquer"(将文件分成两半,并尝试将每一半都真实化)——但这相当乏味。
还有更好的吗?
我修改了 ast.literal_eval:_convert
以打印有问题的节点 - 结果是 <_ast.UnaryOp object at 0x110696510>
。帮助不大。
如何确保以后不会发生这种情况?
我希望 JSON
不是答案。 ;-)
我没有使用 JSON
因为
- JSON inserts either too many newlines or none at all
快速而肮脏
应用此补丁:
--- /...../2.7/lib/python2.7/ast.py.old 2018-03-25 12:17:11.000000000 -0400
+++ /...../2.7/lib/python2.7/ast.py 2018-03-25 12:17:18.000000000 -0400
@@ -76,7 +76,7 @@ def literal_eval(node_or_string):
return left + right
else:
return left - right
- raise ValueError('malformed string')
+ raise ValueError('malformed string', node.lineno, node.col_offset)
return _convert(node_or_string)
重新加载ast
:
>>> reload(ast)
重试加载有问题的文件
得到
ValueError: ('malformed string', 21161, 10)
然后第21161行,第10列是错误所在。
老练
将代码包装在 try/except
, catch the error and use inspect
/traceback
中以访问有问题的 node
:
try:
ast.literal_eval(...)
except ValueError as ex:
_exc_type, exc_value, exc_traceback = sys.exc_info()
print("ERROR: %r" % (exc_value))
# traceback.print_tb(exc_traceback)
last_tb = exc_traceback
while last_tb.tb_next:
last_tb = last_tb.tb_next
print("Error location: line=%d, col=%d" % (
last_tb.tb_frame.f_locals["node"].lineno,
last_tb.tb_frame.f_locals["node"].col_offset))
打印
ERROR: ValueError('malformed string')
Error location: line=21933, col=15
我使用 pprint.PrettyPrinter
and I am trying to read it using ast.literal_eval
将数据写入文件。
这已经为我工作了很长一段时间,我对生成的文本表示相当满意。
但是,今天我在反序列化时遇到了这个错误:
File "/...mypath.../store.py", line 82, in <lambda>
reader=(lambda fd: ast.literal_eval(fd.read())),
File "/usr/lib64/python2.7/ast.py", line 80, in literal_eval
return _convert(node_or_string)
File "/usr/lib64/python2.7/ast.py", line 60, in _convert
return list(map(_convert, node.elts))
File "/usr/lib64/python2.7/ast.py", line 63, in _convert
in zip(node.keys, node.values))
File "/usr/lib64/python2.7/ast.py", line 62, in <genexpr>
return dict((_convert(k), _convert(v)) for k, v
File "/usr/lib64/python2.7/ast.py", line 63, in _convert
in zip(node.keys, node.values))
File "/usr/lib64/python2.7/ast.py", line 62, in <genexpr>
return dict((_convert(k), _convert(v)) for k, v
File "/usr/lib64/python2.7/ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string
如何修复这个特定文件?
有问题的文件是 17k lines/700kb。 我将它加载到 Emacs 中——括号是平衡的。 文件中没有非 ASCII 字符。 我可以 "divide and conquer"(将文件分成两半,并尝试将每一半都真实化)——但这相当乏味。 还有更好的吗?
我修改了 ast.literal_eval:_convert
以打印有问题的节点 - 结果是 <_ast.UnaryOp object at 0x110696510>
。帮助不大。
如何确保以后不会发生这种情况?
我希望 JSON
不是答案。 ;-)
我没有使用 JSON
因为
- JSON inserts either too many newlines or none at all
快速而肮脏
应用此补丁:
--- /...../2.7/lib/python2.7/ast.py.old 2018-03-25 12:17:11.000000000 -0400
+++ /...../2.7/lib/python2.7/ast.py 2018-03-25 12:17:18.000000000 -0400
@@ -76,7 +76,7 @@ def literal_eval(node_or_string):
return left + right
else:
return left - right
- raise ValueError('malformed string')
+ raise ValueError('malformed string', node.lineno, node.col_offset)
return _convert(node_or_string)
重新加载ast
:
>>> reload(ast)
重试加载有问题的文件
得到
ValueError: ('malformed string', 21161, 10)
然后第21161行,第10列是错误所在。
老练
将代码包装在 try/except
, catch the error and use inspect
/traceback
中以访问有问题的 node
:
try:
ast.literal_eval(...)
except ValueError as ex:
_exc_type, exc_value, exc_traceback = sys.exc_info()
print("ERROR: %r" % (exc_value))
# traceback.print_tb(exc_traceback)
last_tb = exc_traceback
while last_tb.tb_next:
last_tb = last_tb.tb_next
print("Error location: line=%d, col=%d" % (
last_tb.tb_frame.f_locals["node"].lineno,
last_tb.tb_frame.f_locals["node"].col_offset))
打印
ERROR: ValueError('malformed string')
Error location: line=21933, col=15