52268


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

[code]

    try:
        ...
    except Exception:
        pass
    
[/code]

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


CC BY-SA 4.0
2019-01-23T03:45:22.737
52233
2019-01-23T19:14:19.607
2019-01-23T03:51:48.750
5246
5246
question
python python3 exception
pythonでpass文でつぶしてあるエラーを取得する


この記事が参考になりそうです。

[pythonですべての例外をキャッチし、詳細を表示させたい。](https://ja.stackoverflow.com/q/6972/26370)  
[pythonのtry,exceptを用いる際にエラーごとに処理を分ける方法](https://ja.stackoverflow.com/q/23714/26370)

変更は、複数行・複数ファイルの grep,置換 が行えるエディタで一気にやってしまうとか。  
私は秀丸エディタでやってます。

* * *

参照先をまとめると以下になります。

> `traceback`モジュールの`print_exc()`を使えば、スタック情報も表示します。
[code]

    except:
        traceback.print_exc()
    
[/code]

> sysモジュールの`exc_info()`で現在処理中の例外を参照できます。
[code]

    except:
        print(sys.exc_info())
    
[/code]

> `traceback`の情報じゃなくて、ただ、メッセージが知りたいなら、Exceptionの`args`が使えます（tupleが返される)：  
>  プラスして詳細なException種別を指定して対処を振り分ける
[code]

    except ZeroDivisionError as e:
        print("ゼロ除算例外args:", e.args)
    except Exception as e:
        print("その他例外args:", e.args)
    
[/code]

> もっとキチンと対応する際の考え方  
>  [Pythonでtry exceptの書き方と、エラー内容の取得方法](https://symfoware.blog.fc2.com/blog-
> entry-873.html)


CC BY-SA 4.0
2019-01-23T06:09:44.197
52240
2019-01-23T08:01:32.807
2019-01-23T08:01:32.807
26370
26370
52233
answer


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

**pass2tb.py**

[code]

    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))
    
[/code]

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

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

**src.py**

[code]

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

以下を実行します。

[code]

    $ 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()
    
[/code]

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

[code]

    $ 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'
    
[/code]

なお、AST オブジェクトをソースコードに戻すために [An AST unparser for
Python](https://github.com/simonpercivall/astunparse) を利用しています。pip
コマンドなどを使って、事前にインストールしておいて下さい。


CC BY-SA 4.0
2019-01-23T19:05:34.007
52268
2019-01-23T19:14:19.607
2019-01-23T19:14:19.607
52233
answer