pythonでpass文でつぶしてあるエラーを取得する

投稿者: Anonymous

Pythonでpassをフックすることはできますか?

try:
    ...
except Exception:
    pass

上のようなエラー処理をしている部分が多いコードがありエラーを握りつぶしてしまっています。
一つ一つ書き換えてもいいのですが、数が多く大変です。消してしまっているエラーを取得する、なにかいい方法はありますか?

解決

ast パッケージを利用する方法もあるかと思います。

pass2tb.py

import sys
import ast
import astunparse

class Pass2Traceback(ast.NodeTransformer):
  trace_stmt = 'import traceback;traceback.print_exc()'

  def visit_Try(self, node):
    for h in node.handlers:
      if len(h.body) == 1 and isinstance(h.body[0], ast.Pass):
        h.body = ast.parse(self.trace_stmt).body
    return node

t = ast.parse(open(sys.argv[1], 'r').read())
Pass2Traceback().visit(t)

print(astunparse.unparse(t))

try … except ノードの exception handler ブロックを書き替えています。変更されるのは pass のみが存在する handler だけです。

例えば、以下の様なソースコードがあるとして、

src.py

try:
  {'a': 1}['b']
  1/0
  open('not exist')
except ZeroDivisionError:
  print('Divided by zero.')
except FileNotFoundError:
  print('File not found.')
except Exception:
  pass

以下を実行します。

$ python3 pass2tb.py src.py

try:
    {
        'a': 1,
    }['b']
    (1 / 0)
    open('not exist')
except ZeroDivisionError:
    print('Divided by zero.')
except FileNotFoundError:
    print('File not found.')
except Exception:
    import traceback
    traceback.print_exc()

実際には別ファイルにリダイレクトして、そちらを使う方が良いかと思います。

$ python3 pass2tb.py src.py > modified.py
$ python3 modified.py
  Traceback (most recent call last):
    File "modified.py", line 5, in <module>
      }['b']
  KeyError: 'b'

なお、AST オブジェクトをソースコードに戻すために An AST unparser for Python を利用しています。pip コマンドなどを使って、事前にインストールしておいて下さい。

回答者: Anonymous

Leave a Reply

Your email address will not be published.