J'aimerais très bien intégrer pylint dans le processus de construction demy projets python, mais je me suis heurté à un problème: l'un des types d'erreur Que je trouve extrêmement utile--: E1101: *%s %r has no %r
member*
-- rapporte constamment des erreurs lors de l'utilisation de champs Django courants, par exemple
E1101:125:get_user_tags: Class 'Tag' has no 'objects' member
qui est causé par ce code:
def get_user_tags(username):
"""
Gets all the tags that username has used.
Returns a query set.
"""
return Tag.objects.filter( ## This line triggers the error.
tagownership__users__username__exact=username).distinct()
# Here is the Tag class, models.Model is provided by Django:
class Tag(models.Model):
"""
Model for user-defined strings that help categorize Events on
on a per-user basis.
"""
name = models.CharField(max_length=500, null=False, unique=True)
def __unicode__(self):
return self.name
Comment puis-je ajuster Pylint pour prendre correctement en compte des champs tels que des objets? (J'ai également consulté le code source Django et je suis incapable de trouver l'implémentation de objects
. Je suppose donc que ce n'est pas "juste" un champ de classe. Par contre, je suis assez nouveau en python, alors J'ai peut-être très bien oublié quelque chose.)
Edit: Le seul moyen que j’ai dit à pylint de ne pas avertir de ces avertissements est de bloquer toutes les erreurs de type (E1101), ce qui n’est pas une solution acceptable, car c’est (à mon avis) un erreur utile. S'il existe un autre moyen, sans augmenter la source de pylint, veuillez me diriger vers les détails :)
Voir ici pour un résumé des problèmes que j'ai rencontrés avec pychecker
et pyflakes
- ils se sont révélés bien trop instables pour une utilisation générale. (Dans le cas de pychecker, les blocages provenaient du code pychecker - pas de la source qu'il était en train de charger/appeler.)
Ne désactivez ni n’affaiblissez la fonctionnalité Pylint en ajoutant ignores
ou generated-members
.
Utilisez un plugin Pylint activement développé qui comprend Django.
Ce plugin Pylint pour Django fonctionne assez bien:
pip install pylint-Django
et lors de l'exécution de pylint, ajoutez l'indicateur suivant à la commande:
--load-plugins pylint_Django
Article de blog détaillé ici .
J'utilise les éléments suivants: pylint --generated-members=objects
Mon ~/.pylintrc contient
[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id
les deux derniers sont spécifiquement pour Django.
Notez qu'il existe un bogue dans PyLint 0.21.1 qui nécessite un correctif pour que cela fonctionne.
Edit: Après avoir déconné cela un peu plus, j’ai décidé de pirater PyLint un tout petit peu pour me permettre d’étendre ce qui précède à:
[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id,[a-zA-Z]+_set
J'ai simplement ajouté:
import re
for pattern in self.config.generated_members:
if re.match(pattern, node.attrname):
return
après le correctif mentionné dans le rapport de bogue (c’est-à-dire à la ligne 129).
Jours heureux!
Django-lint est un outil Nice qui enveloppe pylint avec des paramètres spécifiques à Django: http://chris-lamb.co.uk/projects/Django-lint/
projet github: https://github.com/lamby/Django-lint
En raison du fonctionnement de pylint (il examine la source elle-même, sans laisser Python l'exécuter réellement), il est très difficile pour pylint de comprendre comment les métaclasses et les classes de base complexes affectent réellement une classe et ses instances. L'outil 'pychecker' est un peu meilleur à cet égard, car fait laisse réellement Python exécuter le code; il importe les modules et examine les objets résultants. Cependant, cette approche a d’autres problèmes, car elle permet en fait à Python d’exécuter le code :-)
Vous pouvez étendre pylint pour lui expliquer la magie utilisée par Django, ou pour lui faire mieux comprendre les métaclasses ou les bascasses complexes, ou simplement pour ignorer de tels cas après avoir détecté une ou plusieurs caractéristiques qu'il ne comprend pas tout à fait. Je ne pense pas que ce serait particulièrement facile. Vous pouvez également simplement dire à pylint de ne pas avertir à propos de ces choses, par le biais de commentaires spéciaux dans les sources, d'options de ligne de commande ou d'un fichier .pylintrc.
Si vous utilisez le code Visual Studio, procédez comme suit:
pip install pylint-Django
Et ajoutez à la configuration VSC:
"python.linting.pylintArgs": [
"--load-plugins=pylint_Django"
],
J'ai renoncé à utiliser pylint/pychecker au lieu d'utiliser pyflakes avec du code Django - il essaie simplement d'importer le module et signale tout problème rencontré, comme les importations inutilisées ou les noms locaux non initialisés.
Ce n'est pas une solution, mais vous pouvez ajouter objects = models.Manager()
à vos modèles Django sans modifier aucun comportement.
Je n'utilise moi-même que des pyflakes, principalement en raison de quelques défauts stupides de pylint et de paresse de ma part (ne pas vouloir chercher comment changer les défauts).
Essayez de lancer pylint avec
pylint --ignored-classes=Tags
Si cela fonctionne, ajoutez toutes les autres classes Django - en utilisant éventuellement un script, par exemple, python: P
La documentation pour --ignore-classes
est:
--ignored-classes=<members names>
Liste des noms de classes pour quel membre les attributs ne doivent pas être vérifiés (utile pour les classes avec des attributs dynamicaly set). [current:% default]
J'ajouterais que ce n'est pas une solution particulièrement élégante à mon avis, mais que cela devrait fonctionner.
La solution proposée dans cette autre question c'est simplement d'ajouter get_attr à votre classe Tag. Moche, mais ça marche.
Jusqu'à présent, je n'ai trouvé aucune solution réelle à cela, mais contourner:
Pour neovim & vim8
, utilisez le plugin w0rp's ale
. Si vous avez tout installé correctement, y compris w0rp's ale
, pylint
& pylint-Django
. Dans votre vimrc
, ajoutez la ligne suivante et amusez-vous à développer des applications Web avec Django . Merci.
let g:ale_python_pylint_options = '--load-plugins pylint_Django'