Flask "app.logger"的 Pylint 误报:E1101:方法"记录器"没有"调试"成员(无成员)



使用flask的app.logger成员函数(如app.logger.error(会导致pylint报告E1101(no-member(错误,即使app.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'

需求.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)

有没有一个好的方法来避免这些误报?

请改用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'

另一个对我有效且不包括编写额外插件的解决方案是在我的.pylintrc:中设置generated-members

...
[TYPECHECK]
generated-members=app.logger
...

通过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.errorapp.logger.addHandler上出现linting错误。

要使用pylintplugins.py文件,需要使用--load-plugins命令行选项加载:

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

或者通过在pylintrc配置文件中包括以下行:

load-plugins=pylintplugins

还要注意,如果您通过另一个python文件(如使用Blueprint时的视图文件(导入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代理,它指向处理当前活动的应用程序。

我不知道为什么,但在python3.6.6上使用pylint==2.2.2对我来说很有效。和往常一样,你的夫人可能会有所不同。

对严启东答案的扩展:

您也可以自己创建记录器:

from flask import Flask
from flask.logging import create_logger
app = Flask(__name__)
app.logger = create_logger(app)

这样,您就可以像往常一样使用app.logger.warning("Starting the HTTP server...")pylint,不会有任何抱怨。

否则,您可以像pylint --disable=E1101 src/一样调用它,但这意味着您很乐意忽略ALL那些E1101错误。

相关内容

  • 没有找到相关文章

最新更新