Tôi đoán một giải pháp chỉ có thể không chính xác vì thiếu các quy tắc nhập tĩnh.
Tôi không biết một số công cụ kiểm tra ngoại lệ, nhưng bạn có thể nghĩ ra công cụ của riêng mình phù hợp với nhu cầu của bạn (một cơ hội tốt để chơi một chút với phân tích tĩnh).
Lần thử đầu tiên, bạn có thể viết một hàm tạo AST, tìm tất cả Raise
các nút và sau đó cố gắng tìm ra các mẫu phổ biến của việc nâng cao các ngoại lệ (ví dụ: gọi trực tiếp một hàm tạo)
Hãy x
là chương trình sau:
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
Xây dựng AST bằng cách sử dụng compiler
gói:
tree = compiler.parse(x)
Sau đó, xác định một Raise
lớp khách truy cập:
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
Và đi bộ qua Raise
các nút thu thập 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),
]
Bạn có thể tiếp tục bằng cách giải quyết các ký hiệu bằng cách sử dụng bảng ký hiệu của trình biên dịch, phân tích sự phụ thuộc dữ liệu, v.v. Hoặc bạn có thể chỉ suy luận rằng CallFunc(Name('IOError'), ...)
"chắc chắn có nghĩa là nâng cao IOError
", điều này khá tốt cho kết quả thực tế nhanh chóng :)
raise
xâu chuỗi chứ không chỉ cácBaseException
lớp con. Vì vậy, nếu bạn đang gọi vào mã thư viện nằm ngoài tầm kiểm soát của bạn, thậm chíexcept Exception
là không đủ, vì nó sẽ không bắt các ngoại lệ chuỗi. Như những người khác đã chỉ ra, bạn đang trồng sai cây ở đây.