Pylint false positive for Flask's "app.logger": E1101: Method 'logger' has no 'debug' member (no-member)
Use create_logger
instead.
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'
A solution to prevent these false positives, via pylint plugins:
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)
This workaround prevents linting errors on app.logger.debug
, app.logger.info
, app.logger.warning
, app.logger.error
and app.logger.addHandler
.
In order to be used, the pylintplugins.py file needs to be loaded using the --load-plugins
command line option:
PYTHONPATH="." pylint -E app --load-plugins pylintplugins
or by including the following line in the pylintrc
configuration file:
load-plugins=pylintplugins
Also note that if you are importing app
via another python file (such as a view file when using Blueprints):
If you import app like this, you will get lint errors on
app.logger.info
:from myapp import app
If you import app like this, you won't get lint errors on
app.logger.info
:from flask import current_app as app
From the documentation:
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.
I don't have a good answer as to why, but it works for me using pylint==2.2.2
on python3.6.6
. As always, your milage may vary.