ฉันเดาว่าวิธีแก้ปัญหาอาจไม่ชัดเจนเพียงเพราะไม่มีกฎการพิมพ์แบบคงที่
ฉันไม่ทราบว่ามีเครื่องมือบางอย่างที่ตรวจสอบข้อยกเว้น แต่คุณสามารถสร้างเครื่องมือของคุณเองที่ตรงกับความต้องการของคุณได้ (โอกาสที่ดีที่จะเล่นด้วยการวิเคราะห์แบบคงที่)
ในความพยายามครั้งแรกคุณสามารถเขียนฟังก์ชันที่สร้าง AST ค้นหาRaise
โหนดทั้งหมดจากนั้นพยายามหารูปแบบทั่วไปของการเพิ่มข้อยกเว้น (เช่นการเรียกตัวสร้างโดยตรง)
ให้x
เป็นโปรแกรมต่อไปนี้:
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
สร้าง AST โดยใช้compiler
แพ็คเกจ:
tree = compiler.parse(x)
จากนั้นกำหนดRaise
ระดับผู้เยี่ยมชม:
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
และเดินตามRaise
โหนดรวบรวม AST :
v = RaiseVisitor()
compiler.walk(tree, v)
>>> print v.nodes
[
Raise(
CallFunc(
Name('IOError'),
[Getattr(Name('errno'), 'ENOENT'), Const('not found')],
None, None),
None, None),
Raise(Name('e'), None, None),
]
คุณสามารถดำเนินการต่อได้โดยการแก้ไขสัญลักษณ์โดยใช้ตารางสัญลักษณ์ของคอมไพเลอร์วิเคราะห์การอ้างอิงข้อมูล ฯลฯ หรือคุณอาจสรุปได้ว่าCallFunc(Name('IOError'), ...)
"ควรหมายถึงการเพิ่มขึ้นอย่างแน่นอนIOError
" ซึ่งค่อนข้างใช้ได้สำหรับผลลัพธ์ในทางปฏิบัติที่รวดเร็ว :)
raise
สตริงได้เช่นกันไม่ใช่แค่BaseException
คลาสย่อย ดังนั้นหากคุณกำลังเรียกใช้รหัสไลบรารีที่อยู่นอกเหนือการควบคุมของคุณก็ยังexcept Exception
ไม่เพียงพอเนื่องจากจะไม่พบข้อยกเว้นสตริง ในขณะที่คนอื่น ๆ ชี้ให้เห็นว่าคุณกำลังเห่าต้นไม้ผิดที่นี่