Nous sommes des fans de longue date de pylint
. Son analyse statique est devenue un élément essentiel de tous nos projets python et a permis d'économiser des tonnes de temps à chasser les bugs obscurs. Mais après la mise à niveau de 1.3 -> 1.4, presque toutes les extensions c compilées aboutissent à E1101 ( no-member) erreurs.
Les projets qui fonctionnaient auparavant parfaitement avec pylint
1.3 se plaignent désormais de presque tous les membres de l'extension C avec E1101. Nous avons été obligés de désactiver les erreurs E1101, mais cela nuit considérablement à l'utilité de pylint
.
Par exemple, cette utilisation parfaitement valide du package lxml
r"""valid.py: demonstrate pylint 1.4 error"""
from lxml import etree
print etree.Element('mydoc')
Exécutez ceci via pylint
, et il signale:
$ pylint -rn valid.py
No config file found, using default configuration
************* Module valid
E: 3, 6: Module 'lxml.etree' has no 'Element' member (no-member)
Mais c'est parfaitement valable:
$ python valid.py
<Element mydoc at 7fddf67b1ba8>
Voici où ça devient vraiment bizarre. Une très petite poignée d'extensions C semble fonctionner très bien via pylint
, par exemple:
r"""valid2.py: this one works fine"""
import sqlite3
print sqlite3.version
$ pylint -rn valid2.py
No config file found, using default configuration
Ma question est la suivante: quelqu'un d'autre en a-t-il été témoin? Et si oui, seriez-vous prêt à partager votre solution/contournement?
Nous avons essayé de créer des plugins pour supprimer ces avertissements ( http://docs.pylint.org/plugins.html#enter-plugin ), mais nous avons du mal à créer des têtes ou des queues de la documentation - et la classe de base astroid
est uber-complexe et a défié nos tentatives de le faire.
Pour de vrais points bonus (et notre gratitude éternelle), nous aimerions comprendre ce qui a changé dans pylint
. Nous serions heureux de corriger le code (ou au moins de publier un document de bonnes pratiques pour les auteurs d'extensions C) qui satisferait pylint
.
Détails de la plateforme
$ pylint --version
No config file found, using default configuration
pylint 1.4.0,
astroid 1.3.2, common 0.63.2
Python 2.7.5 (default, Jul 1 2013, 18:09:11)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)]
Peu de temps après avoir posté ma question, j'ai trouvé la réponse. Le changement a en fait été fait exprès comme mesure de sécurité. Pylint importe des modules pour identifier efficacement les méthodes et les attributs valides. Il a été décidé que l'importation d'extensions c qui ne font pas partie du python stdlib est un risque pour la sécurité et pourrait introduire du code malveillant.
Cela a été fait dans la version d'Astroid 1.3.1 https://mail.python.org/pipermail/code-quality/2014-November/000394.html
Seules les extensions C de sources fiables (la bibliothèque standard) sont chargées dans le processus d'examen Python pour construire un AST à partir du module en direct).
Il existe quatre solutions si vous souhaitez utiliser pylint sur des projets qui importent des extensions c non stdlib.
1) Désactivez la sécurité à l'aide de --unsafe-load-any-extension=y
option de ligne de commande. Cette fonctionnalité est non documentée et classée comme une option cachée ( https://mail.python.org/pipermail/code-quality/2014-November/000439.html ).
2) Désactivez la sécurité à l'aide de pylint.rc
réglage unsafe-load-any-extensions=yes
. Ceci est recommandé par rapport à l'option 1 et inclut une documentation complète dans le fichier pylint.rc par défaut (créé avec --generate-rcfile
).
3) Répertoriez spécifiquement les noms de packages ou de modules que vous pensez pouvoir charger par pylint dans le pylint.rc
fichier à l'aide du extension-pkg-whitelist=
option.
4) Créez un plugin pour manipuler le AST (je ne sais pas comment effectuer cela - mais il est régulièrement discuté sur la liste de diffusion pylint).
Nous avons opté pour l'option 3. Nous avons ajouté la ligne suivante à notre projet pylint.rc
fichier:
extension-pkg-whitelist=lxml
@ user590028, merci beaucoup pour votre réponse! Je viens de rencontrer ce même problème avec les bibliothèques win32api, win32evtlog, win32file, win32gui et win32process, et votre solution a fonctionné.
J'ai utilisé une autre méthode qui, selon moi, vaut la peine d'être publiée ici, qui consiste à appeler pylint et à passer les packages sur liste blanche en tant que paramètre:
pylint --extension-pkg-whitelist=win32api,win32evtlog,win32file,win32gui,win32process myfile.py
Pour ceux d'entre vous qui utilisent VS Code, il est un peu difficile de trouver où placer la commande car je n'ai pas pu trouver mon exécutable.
Dans VS Code;
J'ai dû faire tout cela parce que PyLint n'est pas exécutable à partir de ma ligne de commande Windows ...
Si vous utilisez VS Code pour Mac, voici ce que vous devez faire pour modifier le fichier settings.json:
Edit in settings.json
liens. Cela ouvre settings.json
pour l'édition."python.linting.pylintArgs": ["----extension-pkg-whitelist=1xml"]
.