在我正在运行的单元测试用例中,我在下面的json文本中的第4个json对象上得到了一个KeyError异常,因为负责解码的代码片段正在查找不存在的对象,但应该是。
我浏览了子对象,发现导致问题的是“cpuid”对象。当我删除它并运行测试时,它可以正常工作。
def _make_report_entry(记录):
response = self.app.post(
'/machinestats',
params=dict(record=self.json_encode([
{"type": "crash", "instance_id": "xxx",
"version": "0.2.0", "build_id": "unknown",
"crash_text": "Gah!"},
{"type": "machine_info", "machine_info": "I'm awesome.",
"version": "0.2.0", "build_id": "unknown",
"instance_id": "yyy"},
{"machine_info": "Soup", "crash_text": "boom!",
"version": "0.2.0", "build_id": "unknown",
"instance_id": "zzz", "type": "crash"},
{"build_id" : "unknown", "cpu_brand" : "intel",
"cpu_count" : 4,
"cpuid": {
"00000000":
{"eax" :123,"ebx" :456,
"ecx" :789,"edx" :321},
"00000001":
{"eax" :123,"ebx" :456,
"ecx" :789,"edx" :321}},
"driver_installed" : True,
"instance_id" : "yyy",
"version" : "0.2.0",
"machine_info" : "I'm awesome.",
"os_version" : "linux",
"physical_memory_mib" : 1024,
"product_loaded" : True,
"type" : "machine_info",
"virtualization_advertised" : True}
])))
在正在测试的代码片段中,我使用django.utils中的simplejson.JSONDecoder来解码JSON。当我记录上面传递给我的解码函数的JSON的解码输出时,我得到了这个:
root:INFO:{u'instance_id':u'xxx',u'type':u'crash',u'crash_text':u'Gah!',u'version':u'0.2.0' ,u'build_id':u'unknown'}
root:INFO:{u'build_id':u'unknown',u'instance_id':u'yyy',u'version':u'0.2.0',u'machine_info':u“我是太棒了。“,你''':'u'machine_info'}
root:INFO:{u'build_id':u'unknown',u'machine_info':u'Soup',u'version':u'0.2.0',u'instance_id':u'zzz', u'crash_text':u'boom!',u'type':u'crash'}
root:INFO:{u'eax':123,u'edx':321,u'ebx':456,u'ecx':789}
在最后一个JSON对象上,只有JSON cpuid对象中的对象被传递给我的解码函数。因为我的解码函数期望其他对象(例如,'type','instance_id'等),所以我得到了一个KeyError异常。
[对不起早先不必要的长篇文章,我希望这会缩小它的范围更多]
答案 0 :(得分:1)
复制并粘贴您传递给self.json_encode
的内容,并将其用作json.dumps
的参数(在Python 2.6中的import json
之后),可以正常工作。所以看起来这个bug可能在你没有向我们展示的json_encode
方法中:它除了只是调用json.dumps
之外还做了什么呢? (或simplejson.dumps
如果您使用的是Python< 2.6,当然。)
修改:使用json_encode = json.JSONEncoder().encode
(正如OP刚刚发布的那样,除了使用旧的simplejson
,因为我提到的可能性)也可以。不完整的堆栈跟踪也作为Q的大型编辑的一部分发布,表明错误来自解码部分,可能是通过滥用某些模型(不能说,因为我们没有看到模型) - 正如OP所提到的,他现在发布了更多信息,但仍然不足以调试问题。
这有力地表明,OP一次尝试简化问题是值得的,直到最后一次增量简化使错误消失 - 这通常会强烈暗示错误可能是什么,但即使它没有,发布最简单的方法来重现bug以及如果进一步删除代码的微小epsilon将消失的信息可能有助于像我们这样的“第三方观察者”协助调试。 SO并不是一个专为集体调试而设计的平台(更适合于问题和答案, 设计的用途),但我不认为它违反了SO的规则,试图将它用于这个不同的目的
答案 1 :(得分:0)
追溯中的最后2行:
File "...j_report/src/jreport/machinestats.py", line 77, in _make_report_entry
entry_type=record['type']
您现在有两个版本的def _make_report_entry(record):
请注意,追溯的前几行是关于解码的嘀咕,而不是编码。
第一个/原始版本有什么问题?
你现在说“因为我的解码功能正在等待其他对象(例如'type','instance_id'等),我得到了一个KeyError异常。”
所以也许你的解码函数是递归调用的,并且调用者希望能够处理任何结构,而不仅仅是'type'等。