2017-08-08 2 views
5

のために私は私のログにこのような警告を参照してください。スタックトレースはUserWarning

py.warnings.__init__: WARNING .../bs4/__init__.py:219: UserWarning: "foo" 
    looks like a filename, not markup. You should probably open this file 
    and pass the filehandle into Beautiful Soup 

このメッセージはあまり役に立ちません。

この場合、スタックトレースが表示されます。

この警告の内容を検討しないでください。この質問は

簡単な解決策は、サードパーティのコード(ライン219でbs4/__init__.py)を変更し、このような何かを追加することです:-)美しいスープに関するものではありません。

import traceback 
logger.warn('Exc at ...\n%s' % ''.join(traceback.format_stack())) 

しかし、私は避けたいですこの。理由:

  • これは運用システムからの警告です。私はソースを変更したくありません。
  • このような警告が発生する次の時間は、私はすぐに

フラグがあるのか​​、私がいないだけで1行を見て、変更することができるのpythonの設定が、しばらくのスタックトレーススタックトレースを見たいのですが?私はこれをデバッグするために上部フレームが必要です。

この環境では、Python 2.7が使用されます。

答えて

2

あなたは次の操作を実行する必要があります:

  1. USER_SITEが存在しない場合は作成します。

    :問題python -c "import site; site._script()"をUSER_SITE変数の内容を次のコードでそのディレクトリ内のファイルusercustomize.py
  2. 場所を参照してください、

    import traceback 
    import warnings 
    
    
    _old_warn = warnings.warn 
    def warn(*args, **kwargs): 
        tb = traceback.extract_stack() 
        _old_warn(*args, **kwargs) 
        print("".join(traceback.format_list(tb)[:-1])) 
    warnings.warn = warn 
    

    クレジット番号this答えます。

通常通りコードを実行します。私のテストコード:手順の前に

import warnings 

def f(): 
    warnings.warn("foz") 

f() 

$ python test_warn.py 
test_warn.py:4: UserWarning: foz 
    warnings.warn("foz") 

後:

$ python test_warn.py 
<USER_SITE_REDACTED>/usercustomize.py:6: UserWarning: foz 
    _old_warn(*args, **kwargs) 
    File "test_warn.py", line 6, in <module> 
    f() 
    File "test_warn.py", line 4, in f 
    warnings.warn("foz") 
+0

わかりました。 AFAIKこれは猿のパッチと呼ばれます。はい、私はusercustomize.pyがこのような猿のパッチを当てるのに良い場所だと思います。ありがとうございました。 – guettli

+1

@guettli、それは、monkeypatchingです。ソースが変更されず、侵入によってロジックが変更されないので、これを使用すると正当なケースかもしれませんが、ロギングを効果的に追加するだけです。 – RebelWithoutAPulse

1

私は、一般的にちょうどExceptionsWarningsを促進警告のルートを検索する場合。

あなたの場合は、単にwarnings.simplefilterまたはwarnings.filterwarningsを使用することができます。例えば

import warnings 

def func(): 
    warnings.warn('abc', UserWarning) 

def func2(): 
    func() 

# Here I promote all UserWarnings to exceptions, but you could also use "warnings.filterwarnings" 
# to only promote warnings from a specified module or matching a specified message. 
# You may need to check which is most useful/appropriate for you. 
warnings.simplefilter("error", UserWarning) # you might need to reset this later :) 
func2() 

完全なトレースバック与える:

--------------------------------------------------------------------------- 
UserWarning        Traceback (most recent call last) 
<ipython-input-11-be791e1071e7> in <module>() 
     8 
     9 warnings.simplefilter("error", UserWarning) 
---> 10 func2() 

<ipython-input-11-be791e1071e7> in func2() 
     5 
     6 def func2(): 
----> 7  func() 
     8 
     9 warnings.simplefilter("error", UserWarning) 

<ipython-input-11-be791e1071e7> in func() 
     2 
     3 def func(): 
----> 4  warnings.warn('abc', UserWarning) 
     5 
     6 def func2(): 

UserWarning: abc 

をそして、あなたはこれをデバッグしたい場合は、簡単にニシキヘビに最後に発生した例外のpdb Sフックできます

import pdb 

pdb.pm() 

結果:

> <ipython-input-11-be791e1071e7>(4)func() 
-> warnings.warn('abc', UserWarning) 
(Pdb) _________________ 

これにより、最後に発生した例外の死後解析が開始されます。どのフレームを通じて掘ることができますし、変数を検査しなければならない、など


またフラグについて尋ね、そして実際に「警告処理」、-W flagを可能フラグがあります。これは、warnings.filterwarningsと非常によく似ています。便宜上、-Wフラグのドキュメントをここにコピーしました。

Warning control. Python’s warning machinery by default prints warning messages to sys.stderr. A typical warning message has the following form:

file:line: category: message 

By default, each warning is printed once for each source line where it occurs. This option controls how often warnings are printed.

Multiple -W options may be given; when a warning matches more than one option, the action for the last matching option is performed. Invalid -W options are ignored (though, a warning message is printed about invalid options when the first warning is issued).

Starting from Python 2.7, DeprecationWarning and its descendants are ignored by default. The -Wd option can be used to re-enable them.

Warnings can also be controlled from within a Python program using the warnings module.

The simplest form of argument is one of the following action strings (or a unique abbreviation) by themselves:

  • ignore

    Ignore all warnings.

  • default

    Explicitly request the default behavior (printing each warning once per source line).

  • all

    Print a warning each time it occurs (this may generate many messages if a warning is triggered repeatedly for the same source line, such as inside a loop).

  • module

    Print each warning only the first time it occurs in each module.

  • once

    Print each warning only the first time it occurs in the program.

  • error:

    Raise an exception instead of printing a warning message.

The full form of argument is:

action:message:category:module:line 

Here, action is as explained above but only applies to messages that match the remaining fields. Empty fields match all values; trailing empty fields may be omitted. The message field matches the start of the warning message printed; this match is case-insensitive. The category field matches the warning category. This must be a class name; the match tests whether the actual warning category of the message is a subclass of the specified warning category. The full class name must be given. The module field matches the (fully-qualified) module name; this match is case-sensitive. The line field matches the line number, where zero matches all line numbers and is thus equivalent to an omitted line number.

+0

私はこれがあなたのお手伝いで対処されていないと思います。次回このような警告が出たら、すぐにスタックトレースを見たいと思います – guettli

+0

あなたはそれらを例外に昇格させるとすぐにトレースバックを見ます。または、私はあなたの質問を誤解しましたか? – MSeifert

+0

私は昨日あなたのソリューションを誤解しました。今私はそれを理解していると思う。警告メッセージを出力する代わりに例外を発生させます。私はこれを避けたいと思っています。警告は本番環境で発生し、これまでは開発環境では再現できません。この場合、警告から例外への切り替えは避けてください。 – guettli

関連する問題