Pylint can't find SQLAlchemy query member

吃可爱长大的小学妹 提交于 2019-12-02 16:09:33
Jun

Solution

  1. pip install pylint-flask
  2. Load the installed plugin.

    For example, if you use VS code, please edit setting.json file as follows: (opened with the File > Preferences > Settings command ⌘, search for settings.json and one of the options will let you edit it)

    "python.linting.pylintArgs": ["--load-plugins", "pylint_flask"]

Optional

If having other warnings, define remaining members in generated-members in pylintrc file

Any class you declare as inheriting from db.Model won't have query member until the code runs so Pylint can't detect it.

The workaround for this besides ignoring no-member errors on every query call is to add query on the generated-members list in a Pylint config file since it is a member that will only be created at runtime.

When you run Pylint, it will search for a configuration file as stated in its documentation:

You can specify a configuration file on the command line using the --rcfile option. Otherwise, Pylint searches for a configuration file in the following order and uses the first one it finds:

  1. pylintrc in the current working directory
  2. If the current working directory is in a Python module, Pylint searches up the hierarchy of Python modules until it finds a pylintrc file. This allows you to specify coding standards on a module-by-module basis. Of course, a directory is judged to be a Python module if it contains an __init__.py file
  3. The file named by environment variable PYLINTRC
  4. if you have a home directory which isn’t /root:
    1. .pylintrc in your home directory
    2. .config/pylintrc in your home directory
  5. /etc/pylintrc

So if you don't have a config and you want a system wide default config for pylint you can use pylint --generate-rcfile > /etc/pylintrc. This will generate a commented configuration file according to the current configuration (or the default if you don't have one) that you can edit to your preferences.

p.s.: generated-members on a config file is the right way to deal with this warning, as it's said by the commented config

  # List of members which are set dynamically and missed by pylint inference
  # system, and so shouldn't trigger E0201 when accessed. Python regular
  # expressions are accepted.
axis

I meet the same issue when using flask_sqlalchemy. my solution is:

pylint --generate-rcfile>~/.config/pylintrc

and then find the

ignored-modules

line, rewrite it to:

ignored-modules=flask_sqlalchemy

all E1101 errors are gone.

Remeber to read the comment:

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.

Here's a version of joeforker's answer that dynamically adds all public methods from the Session object back into a scoped_session's locals at lint-time, instead of hardcoding a few well-known method names.

Define {path}/{to}/pylintplugins.py:

import sys

from astroid import MANAGER, scoped_nodes
from astroid.builder import AstroidBuilder
from sqlalchemy.orm import Session


def register(_linter):
    pass

def transform(cls):
    if cls.name == 'scoped_session':
        builder = AstroidBuilder(MANAGER)
        module_node = builder.module_build(sys.modules[Session.__module__])
        session_cls_node = [
            c for c in module_node.get_children()
            if getattr(c, "type", None) == "class" and c.name == Session.__name__
        ][0]

        for prop in Session.public_methods:
            cls.locals[prop] = [
                c for c in session_cls_node.get_children() 
                if getattr(c, "type", None) == "method" and c.name == prop
            ]

MANAGER.register_transform(scoped_nodes.Class, transform)

And in your .pylintrc file:

load-plugins={path}.{to}.pylintplugins
Sibo Donald

After trying a lot of these options, plugins and adding query and all. The only solution that erased those scoped_session errors was using:

  1. pylint --generate-rcfile > pylintrc
  2. look for the ignored_classes and add scoped_session after the comma, leave no space
  3. Run pylint on your module again.
Saravana Kumar

In the first solution in this page, following needs to be updated. Its a typo issue,

Instead of "pylint_flask" in this settings.json parameter(in this line: "python.linting.pylintArgs": ["--load-plugins", "pylint_flask"]) it should be "pylint-flask".

Emz Amechu

The one that worked for me was switching to flake8 python linter. Below are the steps:

  1. Open VSCode and run Ctrl+shift+P(For Windows Users)
  2. In the VSCode Search prompt, type Python:Select Linter. You will see a list of all Linters and select flake8.
  3. If you do not have flake8 installed as a VScode extension for pylint, it will prompt you to install it. Proceed and install it.

Another alternative is to add scoped_session to the list of ignored classes:

# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=scoped_session

After a lot of investigation I was not able to make Pylint to understand this member, so I just added query to the generated-members list and the check is ignored.

It's not a perfect solution but it works.

This is how I'm dealing with the issue for scoped_session. Trivial to extend to check for more cls names with SQLAlchemy attributes.

from astroid import MANAGER
from astroid import scoped_nodes

def register(_linter):
    pass

def transform(cls):
    if cls.name == 'scoped_session':
        for prop in ['add', 'delete', 'query', 'commit', 'rollback']:
            cls.locals[prop] = [scoped_nodes.Function(prop, None)]

MANAGER.register_transform(scoped_nodes.Class, transform)

Adapted from https://docs.pylint.org/en/1.6.0/plugins.html . Then make sure pylint loads your plugin.

pylint -E --load-plugins warning_plugin Lib/warnings.py

(or load it in pylintrc)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!