web-dev-qa-db-fra.com

Pylint ne trouve pas de membre de requête SQLAlchemy

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()
41
Pedro Teixeira

Solution

  1. pip install pylint-flask
  2. 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

28
Jun

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:

  1. pylintrc dans le répertoire de travail actuel
  2. 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
  3. Le fichier nommé par la variable d'environnement PYLINTRC
  4. si vous avez un répertoire personnel qui n'est pas /root:
    1. .pylintrc dans votre répertoire personnel
    2. .config/pylintrc dans votre répertoire personnel
  5. /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.
17
0rkan

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.
15
axis

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:

  1. pylint --generate-rcfile > pylintrc
  2. recherchez les classes ignorées et ajoutez scoped_session après la virgule, ne laissez aucun espace
  3. Exécutez à nouveau pylint sur votre module.
6
Sibo Donald

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
6
Kurtiss Hare

Celui qui travaillait pour moi passait à flake8 python linter. Voici les étapes:

  1. Ouvrez VSCode et exécutez Ctrl+shift+P (Pour les utilisateurs de Windows)
  2. Dans l'invite de recherche VSCode, tapez Python:Select Linter. Vous verrez une liste de tous les Linters et sélectionnez flake8.
  3. Si vous n'avez pas installé flake8 en tant qu'extension VScode pour pylint, il vous demandera de l'installer. Continuez et installez-le.
3
Emz Amechu

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
1
jojonas

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".

1
Saravana Kumar

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.

0
Pedro Teixeira

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)

0
joeforker