可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a Flask (v0.10.1) application using Flask-SQLAlchemy (v2.0) and I'm trying to configure Pylint to check it. Running with Python 3.4.2.
First error was:
Instance of 'SQLAlchemy' has no 'Table' member (no-member)
And I fixed this one ignoring the check for member attributes on SQLAlchemy:
ignored-classes=SQLAlchemy
But I'm having a problem with the query member on entities:
Class 'UserToken' has no 'query' member (no-member)
Is there any way to fix this issue without having to ignore no-member errors on every query call?
Flask bootstrap:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app = Flask(__name__)
db.init_app(app)
app.run()
UserToken entity:
from app import db
class UserToken(db.Model):
user_token_id = db.Column(db.Integer, primary_key=True, index=True)
token_auth = db.Column(db.String(64), unique=True, nullable=False, index=True)
The controller:
from entities import UserToken
token = UserToken.query.filter(
UserToken.token_auth == token_hash,
).first()
回答1:
Solution
pip install pylint-flask
Load the installed plugin.
For example, if you use VS code, please edit setting.json file as follows:
"python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]
Optional
If having other warnings, define remaining members in generated-members
in pylintrc
file.
回答2:
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:
pylintrc
in the current working directory
- 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
- The file named by environment variable
PYLINTRC
- if you have a home directory which isn’t
/root
:
.pylintrc
in your home directory
.config/pylintrc
in your home directory
/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.
回答3:
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.
回答4:
After trying a lot of these options, plugins and adding query and all. The only solution that erased those scoped_session errors was using:
pylint --generate-rcfile > pylintrc
- look for the ignored_classes and add scoped_session after the comma, leave no space
- Run
pylint
on your module again.
回答5:
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 "python.linting.pylintArgs": ["--load-plugins", "pylint-flask"])
.
回答6:
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
回答7:
The one that worked for me was switching to flake8
python linter. Below are the steps:
- Open VSCode and run
Ctrl+shift+P
(For Windows Users)
- In the VSCode Search prompt, type
Python:Select Linter
. You will see a list of all Linters and select flake8.
- If you do not have flake8 installed as a VScode extension for pylint, it will prompt you to install it. Proceed and install it.
回答8:
Use pylint plugin pylint-flask-sqlalchemy
pip install pylint_flask_sqlalchemy
And in your settings.json of VisualCode
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalcheny"]
回答9:
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
回答10:
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.
回答11:
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)
回答12:
The one that worked for me was switching to flake8 python linter. Below are the steps:
Open VSCode and run Ctrl+Shift+P (for Windows Users)
In the VSCode Search prompt, type Python:Select Linter
. You will see a list of all Linters and select flake8
.
If you do not have flake8
installed as a VScode extension for pylint, it will prompt you to install it. Proceed and install it.