Using flask's app.logger
member functions (such as app.logger.error
) causes pylint
to report E1101
(no-member
) errors, even though these members of app.logger
are defined at runtime.
This can be reproduced by using the following files:
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
Sample commands for reproducing the issue, using virtualenv
:
(Python 3.5 is used here, but the issue is not specific to that version)
virtualenv --python=python3.5 env
source env/bin/activate
pip install pip==18.0
pip install -r requirements.txt
And finally, running pylint
:
pylint -E app
Returns these errors:
************* 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)
Is there a good way to avoid these false positives?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With