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