Sanırım bir çözüm, statik yazım kurallarının olmaması nedeniyle kesin olmayabilir.
İstisnaları kontrol eden bir araçtan haberdar değilim, ancak ihtiyaçlarınıza uygun kendi aracınızı bulabilirsiniz (statik analizle biraz oynamak için iyi bir şans).
İlk girişim olarak, bir AST oluşturan, tüm Raise
düğümleri bulan ve ardından istisnaları artırmanın ortak modellerini bulmaya çalışan bir işlev yazabilirsiniz (örneğin, bir kurucuyu doğrudan çağırmak)
x
Aşağıdaki program olalım :
x = '''\
if f(x):
raise IOError(errno.ENOENT, 'not found')
else:
e = g(x)
raise e
'''
AST'yi aşağıdaki compiler
paketi kullanarak oluşturun :
tree = compiler.parse(x)
Ardından bir Raise
ziyaretçi sınıfı tanımlayın :
class RaiseVisitor(object):
def __init__(self):
self.nodes = []
def visitRaise(self, n):
self.nodes.append(n)
Ve AST toplama Raise
düğümlerinde yürüyün :
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),
]
Derleyici sembol tablolarını kullanarak sembolleri çözerek, veri bağımlılıklarını analiz ederek, vb. Devam edebilirsiniz. Ya da sadece CallFunc(Name('IOError'), ...)
"kesinlikle yükseltme anlamına gelmelidir" sonucuna varabilirsiniz, bu IOError
hızlı pratik sonuçlar için oldukça uygundur :)
raise
dizeler de yapabileceğinizi unutmayın, sadeceBaseException
alt sınıflar değil . Dolayısıyla, kontrolünüz dışındaki kitaplık kodunu çağırıyorsanızexcept Exception
, dize istisnalarını yakalayamayacağı için bile yeterli değildir. Başkalarının da belirttiği gibi, burada yanlış ağaca havlıyorsunuz.