【问题标题】:Pylint false positive for Flask's "app.logger": E1101: Method 'logger' has no 'debug' member (no-member)Flask 的“app.logger”的 Pylint 误报:E1101:方法“记录器”没有“调试”成员(无成员)
【发布时间】:2019-01-11 16:46:31
【问题描述】:

使用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

返回这些错误:

************* 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)

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

【问题讨论】:

标签: python logging flask pylint


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    通过 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
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        另请注意,如果您通过另一个 python 文件(例如使用蓝图时的视图文件)导入 app

        1. 如果您像这样导入应用程序,您将在app.logger.info 上收到 lint 错误:

          from myapp import app

        2. 如果你像这样导入应用程序,app.logger.info 上不会出现 lint 错误:

          from flask import current_app as app

        来自documentation

        Flask 通过应用程序上下文解决了这个问题。与其直接引用应用程序,不如使用 current_app 代理,它指向处理当前活动的应用程序。

        我对原因没有很好的答案,但它适用于我在 python3.6.6 上使用 pylint==2.2.2。与往常一样,您的里程可能会有所不同。

        【讨论】:

          【解决方案5】:

          扩展严启东的答案:

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

          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/ 一样调用它,但这意味着您很乐意忽略所有那些E1101 错误。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-05-30
            • 2017-09-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-24
            相关资源
            最近更新 更多