web-dev-qa-db-ja.com

Flaskの "app.logger"のPylint誤検知:E1101:メソッド 'logger'に 'debug'メンバーがありません(メンバーなし)

フラスコのapp.loggerメンバー関数(app.logger.errorなど)を使用すると、E1101のメンバーであってもpylintno-memberapp.logger)エラーを報告します。 _は実行時に定義されます。

これは、次のファイルを使用して再現できます。

app.py

import flask
app = flask.Flask(__name__)

@app.route('/')
def say_hello():
    app.logger.debug('A debug message')
    app.logger.error('An error message')
    return 'hello'

requirements.txt

pylint==2.1.0
Flask==1.0.2

virtualenv:を使用して問題を再現するためのサンプルコマンド

(ここではPython 3.5を使用していますが、問題はそのバージョンに固有ではありません)

virtualenv --python=python3.5 env
source env/bin/activate
pip install pip==18.0
pip install -r requirements.txt

そして最後に、pylintを実行します。

pylint -E app

次のエラーを返します:

************* Module app
app.py:9:4: E1101: Method 'logger' has no 'debug' member (no-member)
app.py:10:4: E1101: Method 'logger' has no 'error' member (no-member)

これらの誤検知を回避する良い方法はありますか?

9
Odysseas

Pylintプラグインを介してこれらの誤検知を防止するソリューション:

pylintplugins.py

import sys

from astroid import MANAGER, scoped_nodes, extract_node
from astroid.builder import AstroidBuilder


def register(_linter):
    pass


def transform(f):
    if f.name == 'logger':
        for prop in ['debug', 'info', 'warning', 'error', 'addHandler']:
            f.instance_attrs[prop] = extract_node('def {name}(arg): return'.format(name=prop))


MANAGER.register_transform(scoped_nodes.FunctionDef, transform)

この回避策は、app.logger.debugapp.logger.infoapp.logger.warningapp.logger.errorおよびapp.logger.addHandlerのlintingエラーを防ぎます。

pylintplugins.pyファイルを使用するには、--load-pluginsコマンドラインオプションを使用してロードする必要があります。

PYTHONPATH="." pylint -E app --load-plugins pylintplugins

または、pylintrc構成ファイルに次の行を含めることによって:

load-plugins=pylintplugins
3
Odysseas

使用する create_logger代わりに。

from flask import Flask
from flask.logging import create_logger

APP = Flask(__name__)
LOG = create_logger(APP)


@APP.route('/')
def say_hello():
    LOG.debug('A debug message')
    LOG.error('An error message')
    return 'hello'
10
Yan QiDong

また、別のpythonファイル(ブループリントを使用する場合のビューファイルなど))を介してappをインポートする場合も注意してください。

  1. このようなアプリをインポートすると、app.logger.infoでlintエラーが発生します。

    from myapp import app

  2. このようなアプリをインポートすると、app.logger.infoでlintエラーが発生しなくなります。

    from flask import current_app as app

ドキュメント から:

Flaskはアプリケーションコンテキストでこの問題を解決します。アプリを直接参照するのではなく、現在のアクティビティを処理するアプリケーションを指すcurrent_appプロキシを使用します。

理由はわかりませんが、pylint==2.2.2python3.6.6を使用するとうまくいきます。いつものように、あなたの距離は変わるかもしれません。

1
Niklas B