J'ai une application Flask (v0.10.1) utilisant Flask-SQLAlchemy (v2.0) et j'essaie de configurer Pylint pour le vérifier. Exécution avec Python 3.4.2.
La première erreur était:
Instance of 'SQLAlchemy' has no 'Table' member (no-member)
Et j'ai corrigé celui-ci en ignorant la vérification des attributs des membres sur SQLAlchemy:
ignored-classes=SQLAlchemy
Mais j'ai un problème avec le membre de requête sur les entités:
Class 'UserToken' has no 'query' member (no-member)
Existe-t-il un moyen de résoudre ce problème sans avoir à ignorer les erreurs de non-membre à chaque appel de requête?
Bootstrap de flacon:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app = Flask(__name__)
db.init_app(app)
app.run()
Entité UserToken:
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)
Le controlle:
from entities import UserToken
token = UserToken.query.filter(
UserToken.token_auth == token_hash,
).first()
pip install pylint-flask
Chargez le plugin installé.
Par exemple, si vous utilisez du code VS, veuillez modifier le fichier setting.json comme suit: (ouvert avec la commande Fichier> Préférences> Paramètres ⌘, recherchez settings.json et l'une des options vous permettra de le modifier)
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask"]
Facultatif
Si vous avez d'autres avertissements, définissez les membres restants dans generated-members
dans pylintrc
fichier
Toute classe que vous déclarez hériter de db.Model
n'aura pas de membre query
tant que le code ne sera pas exécuté, donc Pylint ne pourra pas le détecter.
En plus d'ignorer les erreurs de non-membre à chaque appel query
, la solution consiste à ajouter query
sur le generated-members
liste dans un fichier de configuration Pylint car il s'agit d'un membre qui ne sera créé qu'au moment de l'exécution.
Lorsque vous exécutez Pylint, il recherchera un fichier de configuration comme indiqué dans son documentation :
Vous pouvez spécifier un fichier de configuration sur la ligne de commande à l'aide de l'option --rcfile. Sinon, Pylint recherche un fichier de configuration dans l'ordre suivant et utilise le premier qu'il trouve:
pylintrc
dans le répertoire de travail actuel- Si le répertoire de travail actuel se trouve dans un module Python, Pylint recherche la hiérarchie des modules Python jusqu'à ce qu'il trouve un fichier pylintrc. Cela vous permet de spécifier le codage normes par module. Bien entendu, un répertoire est considéré comme un module Python s'il contient un
__init__.py
fichier- Le fichier nommé par la variable d'environnement
PYLINTRC
- si vous avez un répertoire personnel qui n'est pas
/root
:
.pylintrc
dans votre répertoire personnel.config/pylintrc
dans votre répertoire personnel/etc/pylintrc
Donc, si vous n'avez pas de configuration et que vous voulez une configuration par défaut à l'échelle du système pour pylint, vous pouvez utiliser pylint --generate-rcfile > /etc/pylintrc
. Cela générera un fichier de configuration commenté selon la configuration actuelle (ou la valeur par défaut si vous n'en avez pas) que vous pouvez modifier selon vos préférences.
p.s .: generated-members
sur un fichier de configuration est la bonne façon de gérer cet avertissement, comme le dit la configuration commentée
# 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.
Je rencontre le même problème lors de l'utilisation de flask_sqlalchemy. ma solution est:
pylint --generate-rcfile>~/.config/pylintrc
puis trouvez le
ignored-modules
réécrire à:
ignored-modules=flask_sqlalchemy
toutes les erreurs E1101 ont disparu.
N'oubliez pas de lire le commentaire:
# 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.
Après avoir essayé beaucoup de ces options, plugins et ajout de requête et tout. La seule solution qui a effacé ces erreurs scoped_session était d'utiliser:
pylint --generate-rcfile > pylintrc
pylint
sur votre module.Voici une version de la réponse de joeforker qui ajoute dynamiquement toutes les méthodes publiques de l'objet Session
dans les sections locales de scoped_session
Au moment du peluchage, au lieu de coder en dur quelques noms de méthodes bien connus.
Définissez {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)
Et dans votre fichier .pylintrc
:
load-plugins={path}.{to}.pylintplugins
Celui qui travaillait pour moi passait à flake8
python linter. Voici les étapes:
Ctrl+shift+P
(Pour les utilisateurs de Windows)Python:Select Linter
. Vous verrez une liste de tous les Linters et sélectionnez flake8.Une autre alternative consiste à ajouter scoped_session
à la liste des classes ignorées:
# 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
Dans la première solution de cette page, les éléments suivants doivent être mis à jour. C'est un problème de faute de frappe,
Au lieu de "pylint_flask"
dans ce paramètre settings.json (sur cette ligne: "python.linting.pylintArgs": ["--load-plugins", "pylint_flask"])
CA devrait etre "pylint-flask"
.
Après de nombreuses recherches, je n'ai pas réussi à faire comprendre à Pylint ce membre, j'ai donc simplement ajouté query
au generated-members
liste et la vérification est ignorée.
Ce n'est pas une solution parfaite mais ça marche.
Voici comment je traite le problème pour scoped_session
. Trivial à étendre pour vérifier plus de noms cls
avec des attributs SQLAlchemy.
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)
Adapté de https://docs.pylint.org/en/1.6.0/plugins.html . Assurez-vous ensuite que pylint charge votre plugin.
pylint -E --load-plugins warning_plugin Lib/warnings.py
(ou chargez-le dans pylintrc)