Flask 的 "app.logger" 的 Pylint 误报:E1101:方法 'logger' 没有 'debug' 成员(无成员)
Pylint false positive for Flask's "app.logger": E1101: Method 'logger' has no 'debug' member (no-member)
使用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'
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
Returns 这些错误:
************* 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)
是否有避免这些误报的好方法?
通过 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.debug
、app.logger.info
、app.logger.warning
、app.logger.error
和 app.logger.addHandler
.
上的 linting 错误
为了使用,需要使用--load-plugins
命令行选项加载pylintplugins.py文件:
PYTHONPATH="." pylint -E app --load-plugins pylintplugins
或者通过在 pylintrc
配置文件中包含以下行:
load-plugins=pylintplugins
另请注意,如果您通过另一个 python 文件(例如使用蓝图时的视图文件)导入 app
:
如果您像这样导入应用程序,您将在 app.logger.info
:
上收到 lint 错误
from myapp import app
如果您像这样导入应用程序,您将不会在 app.logger.info
:
上出现 lint 错误
from flask import current_app as app
Flask solves this issue with the application context. Rather than referring to an app directly, you use the the current_app proxy, which points to the application handling the current activity.
关于原因我没有一个很好的答案,但它对我在 python3.6.6
上使用 pylint==2.2.2
有效。一如既往,您的里程数可能会有所不同。
改用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
...
延启东的回答:
您也可以自己创建记录器:
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
错误。
使用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'
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
Returns 这些错误:
************* 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)
是否有避免这些误报的好方法?
通过 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.debug
、app.logger.info
、app.logger.warning
、app.logger.error
和 app.logger.addHandler
.
为了使用,需要使用--load-plugins
命令行选项加载pylintplugins.py文件:
PYTHONPATH="." pylint -E app --load-plugins pylintplugins
或者通过在 pylintrc
配置文件中包含以下行:
load-plugins=pylintplugins
另请注意,如果您通过另一个 python 文件(例如使用蓝图时的视图文件)导入 app
:
如果您像这样导入应用程序,您将在
上收到 lint 错误app.logger.info
:from myapp import app
如果您像这样导入应用程序,您将不会在
上出现 lint 错误app.logger.info
:from flask import current_app as app
Flask solves this issue with the application context. Rather than referring to an app directly, you use the the current_app proxy, which points to the application handling the current activity.
关于原因我没有一个很好的答案,但它对我在 python3.6.6
上使用 pylint==2.2.2
有效。一如既往,您的里程数可能会有所不同。
改用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
...
延启东的回答:
您也可以自己创建记录器:
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
错误。