Verwenden von Pylint mit Django

140

Ich würde sehr gerne pylint in den Erstellungsprozess für meine Python-Projekte integrieren, aber ich bin auf einen Show-Stopper gestoßen: Einer der Fehlertypen, die ich äußerst nützlich finde:E1101: *%s %r has no %r member* - - meldet ständig Fehler, wenn allgemeine Django-Felder verwendet werden , zum Beispiel:

E1101:125:get_user_tags: Class 'Tag' has no 'objects' member

was durch diesen Code verursacht wird:

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

Wie kann ich Pylint so einstellen, dass Felder wie Objekte richtig berücksichtigt werden? (Ich habe mir auch die Django-Quelle angesehen und konnte die Implementierung von nicht finden objects. Daher vermute ich, dass es sich nicht "nur" um ein Klassenfeld handelt. Andererseits bin ich ziemlich neu in Python, also ich kann sehr gut etwas übersehen haben.)

Bearbeiten: Die einzige Möglichkeit, Pylint anzuweisen, nicht vor diesen Warnungen zu warnen, besteht darin, alle Fehler des Typs (E1101) zu blockieren, was keine akzeptable Lösung darstellt, da dies (meiner Meinung nach) ein äußerst nützlicher Fehler ist. Wenn es einen anderen Weg gibt, ohne die Pylint-Quelle zu erweitern, weisen Sie mich bitte auf Einzelheiten hin :)

Sehen Sie hier eine Übersicht über die Probleme , die ich habe mit pycheckerund pyflakes- sie weit zu instabil für den allgemeinen Gebrauch erwiesen haben. (Im Fall von Pychecker stammten die Abstürze aus dem Pychecker-Code - nicht aus der Quelle, die geladen / aufgerufen wurde.)

rcreswick
quelle
4
Eine aktuelle Antwort finden Sie im Beitrag von @ talweiss!
Brendan
Gute Lösung gefunden bei stackoverflow.com/a/31000713/78234
shahjapan
1
Können Sie bitte die Antwort von @talweiss akzeptieren? Es ist die aktuellste und korrekteste Lösung.
Vijay Varadan

Antworten:

155

Deaktivieren oder schwächen Sie die Pylint-Funktionalität nicht durch Hinzufügen von ignoresoder generated-members.
Verwenden Sie ein aktiv entwickeltes Pylint-Plugin, das Django versteht .
Dieses Pylint-Plugin für Django funktioniert ganz gut:

pip install pylint-django

und wenn Sie pylint ausführen, fügen Sie dem Befehl das folgende Flag hinzu:

--load-plugins pylint_django

Ausführlicher Blogbeitrag hier .

Tal Weiss
quelle
2
Der Link zum Blog-Beitrag ist tot (so bald). Hier sind einige archivierte Links aus dem Internetarchiv und von archive.is
Christian Long
3
Damit es mit dem SublimeLinter-Plugin von Sublime Text funktioniert, musste ich die --load-plugins=pylint_djangoEinstellung linters / pylint / args hinzufügen . Beachten Sie das Zeichen '=', ohne das es nicht funktioniert hat.
Dennis Golomazov
es funktioniert nicht. Ich erhalte folgende Fehlermeldung: E: 8, 0: Kein Name 'Modelle' im Modul 'django.db' (kein Name im Modul)
max
6
Sie können dies auch in Ihrem Pylintrc hinzufügen:[MASTER] load-plugins=pylint_django
Azmeuk
3
In vs Code funktioniert es nicht für mich, bis ich Folgendes in die Benutzereinstellungen {"python.linting.pylintArgs": [ "--load-plugins=pylint_django" ],} eingebe
ali-myousefi
63

Ich benutze folgendes: pylint --generated-members=objects

Shai
quelle
man pylint (1) unter TYPECHECK --generated-members=<members names>Liste der Mitglieder, die dynamisch festgelegt werden und vom Pylint-Inferenzsystem übersehen werden und daher beim Zugriff nicht E0201 und E1101 auslösen sollten . [aktuell: REQUEST, acl_users, aq_parent]
Mark Mikofski
Ich füge dies in PyDev in Eclipse unter Einstellungen im Abschnitt PyDev / PyLint hinzu .
Mark Mikofski
2
Wenn Sie generierte Mitglieder verwenden, werden diese Fehler nur vor Ihnen ausgeblendet. Es kann dennoch zu Fehlern kommen, wenn Sie versuchen, auf das Objektfeld des falschen Objekts zuzugreifen. Verwenden Sie stattdessen das Pylint-Django-Plugin.
Vajk Hermecz
5
Dies ist der falsche Weg, um Pylint zu reparieren - indem Sie einige seiner Funktionen deaktivieren. Sie müssen lediglich ein Pylint-Plugin installieren, das Django versteht . Siehe stackoverflow.com/a/31000713/78234
Tal Weiss
31

Mein ~ / .pylintrc enthält

[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id

Die letzten beiden sind speziell für Django.

Beachten Sie, dass in PyLint 0.21.1 ein Fehler vorliegt muss, damit dies funktioniert.

Bearbeiten: Nachdem ich ein bisschen mehr damit herumgespielt hatte, entschied ich mich, PyLint nur ein kleines bisschen zu hacken, damit ich das Obige erweitern kann in:

[TYPECHECK]
generated-members=REQUEST,acl_users,aq_parent,objects,_meta,id,[a-zA-Z]+_set

Ich habe einfach hinzugefügt:

    import re
    for pattern in self.config.generated_members:
        if re.match(pattern, node.attrname):
            return

nach dem im Fehlerbericht genannten Fix (dh in Zeile 129).

Glückliche Tage!

Simon
quelle
Sie sollten Ihren Patch an pylint zurück an die Betreuer senden.
Slacy
Eigentlich haben sie diesen Patch in 0.24 aufgenommen, aber sie haben begonnen, das shlexPaket zu verwenden, und jetzt etwas anderes kaputt gemacht. Ich musste in gen.wordchars += "[]-+"Zeile 135 hinzufügen , damit es funktioniert ...
Simon
4
Wenn Sie generierte Mitglieder verwenden, werden diese Fehler nur vor Ihnen ausgeblendet. Es kann dennoch zu Fehlern kommen, wenn Sie versuchen, auf das Feld "Objekte" des falschen Objekts zuzugreifen. Verwenden Sie stattdessen das Pylint-Django-Plugin.
Vajk Hermecz
4
Dies ist der falsche Weg, um Pylint zu reparieren - indem Sie einige seiner Funktionen deaktivieren. Sie müssen lediglich ein Pylint-Plugin installieren, das Django versteht . Siehe stackoverflow.com/a/31000713/78234
Tal Weiss
3
@ TalWeiss - fairerweise ist diese Antwort drei Jahre älter als pylint-django, daher ist die Abwertung etwas hart ...
Simon
27

Wenn Sie Visual Studio Code verwenden, gehen Sie wie folgt vor:

pip install pylint-django

Und zur VSC-Konfiguration hinzufügen:

"python.linting.pylintArgs": [
    "--load-plugins=pylint_django"
],
Thiago Falcao
quelle
2
Beste Antwort bei weitem: D
serfer2
19

django-lint ist ein nettes Tool, das Pylint mit django-spezifischen Einstellungen umschließt: http://chris-lamb.co.uk/projects/django-lint/

Github-Projekt: https://github.com/lamby/django-lint

Bahre Alex
quelle
1
Ich mag die Idee eines Django-spezifischen Pylint, aber es scheint ein großer Buggy zu sein, als ich es das letzte Mal ausprobiert habe.
Wernight
3
Außerdem ist es nicht über PyPI verfügbar und die Website scheint nicht genügend Informationen zu bieten wie: Was ist die aktuelle Version?
Wernight
1
Ich mag das Konzept, aber diese Implementierung ist nur halbherzig und bricht auf jeder mittelgroßen Codebasis. Es ist noch ein langer Weg, bis es wirklich nützlich ist.
Cerin
1
@ Gurney Alex, Link ist tot.
Shuttle87
2
Es sieht so aus, als ob Pylint-Django jetzt aktiver ist, das sollte die empfohlene Lösung sein.
Vajk Hermecz
16

Aufgrund der Funktionsweise von Pylint (es untersucht die Quelle selbst, ohne dass Python sie tatsächlich ausführt) ist es für Pylint sehr schwierig herauszufinden, wie sich Metaklassen und komplexe Basisklassen tatsächlich auf eine Klasse und ihre Instanzen auswirken. Das 'Pychecker'-Tool ist in dieser Hinsicht etwas besser, weil es es tut wirklich läßt Python den Code auszuführen; Es importiert die Module und untersucht die resultierenden Objekte. Dieser Ansatz hat jedoch andere Probleme, da Python den Code tatsächlich ausführen kann :-)

Sie können pylint erweitern, um es über die Magie zu unterrichten, die Django verwendet, oder um Metaklassen oder komplexe Grundklassen besser zu verstehen, oder um solche Fälle einfach zu ignorieren, nachdem Sie eine oder mehrere Funktionen entdeckt haben, die es nicht ganz versteht. Ich denke nicht, dass es besonders einfach wäre. Sie können pylint auch einfach durch spezielle Kommentare in der Quelle, Befehlszeilenoptionen oder eine .pylintrc-Datei anweisen, nicht vor diesen Dingen zu warnen.

Thomas Wouters
quelle
3
Es ist nicht einfach, Pylint Django beizubringen, aber es wurde getan: Sie müssen lediglich ein Pylint-Plugin installieren, das Django versteht . Siehe stackoverflow.com/a/31000713/78234
Tal Weiss
Nun, ich habe es installiert, aber es enthält immer noch einige Informationen, wie QuerySet nicht entfernt werden kann ...
Eino Mäkitalo
7

Ich habe mich von der Verwendung von pylint / pychecker zurückgezogen, um Pyflakes mit Django-Code zu verwenden. Es wird lediglich versucht, ein Modul zu importieren, und es werden alle gefundenen Probleme gemeldet, z. B. nicht verwendete Importe oder nicht initialisierte lokale Namen.

zgoda
quelle
interessant - ich werde Pyflakes noch einmal ansehen.
Rcreswick
2
PyChecker fängt viel weniger als Pylint. teigmannmann.com/articles/CompletelyDifferent-2008-03-linters/…
Justin Abrahms
1
Sie müssen Pylint nicht aufgeben - Sie müssen lediglich ein Pylint-Plugin installieren, das Django versteht . Siehe stackoverflow.com/a/31000713/78234
Tal Weiss
7

Dies ist keine Lösung, aber Sie können objects = models.Manager()Ihre Django-Modelle erweitern, ohne das Verhalten zu ändern.

Ich selbst verwende nur Pyflakes, hauptsächlich aufgrund einiger dummer Standardeinstellungen in Bezug auf Pylint und Faulheit meinerseits (ich möchte nicht nachschlagen, wie die Standardeinstellungen geändert werden können).

AdamKG
quelle
Ah ... danke für den Tipp. Ich kann versuchen, dies einfach zu Model.models in der lokalen Kopie der Django-Quelle hinzuzufügen, und prüfen, ob dies der Fall ist.
Rcreswick
Ich halte dies für eine großartige Lösung, da bei Warnungen keine Kompromisse eingegangen werden.
Tom Leys
1
Dies ist eine schlechte Lösung. Wenn Sie sich wiederholen und etwas ersetzen, das machbar ist, wird sich dies später ändern (wodurch ein QS-Problem entsteht), nur um ein unvollständiges QS-Tool zu beheben?
Chris Morgan
2
Ich würde das nicht als schlechte Lösung bezeichnen: explizit ist besser als implizit. Vielleicht objectssollte es sowieso nicht magisch hinzugefügt werden.
Will Hardy
1
Ich denke, dass dies der falsche Weg ist, um Pylint zu reparieren - indem man Django in gewissem Sinne patcht. Sie müssen lediglich ein Pylint-Plugin installieren, das Django versteht . Siehe stackoverflow.com/a/31000713/78234
Tal Weiss
5

Versuchen Sie, Pylint mit auszuführen

pylint --ignored-classes=Tags

Wenn dies funktioniert, fügen Sie alle anderen Django-Klassen hinzu - möglicherweise mithilfe eines Skripts, z. B. Python: P.

Die Dokumentation für --ignore-classesist:

--ignored-classes=<members names>
Liste der Klassennamen, für die Mitgliedsattribute nicht überprüft werden sollen (nützlich für Klassen mit dynamisch festgelegten Attributen). [aktuell:% default]

Ich sollte hinzufügen, dass dies aus meiner Sicht keine besonders elegante Lösung ist, aber es sollte funktionieren.

Freiraum
quelle
Es funktioniert nur, wenn ich in diesen Klassen nie Fehler mache;). Ich möchte vermeiden, Code zu ignorieren, wenn dies überhaupt möglich ist. Ich halte es für eine sehr schlechte Idee, verschiedene Teile der Codebasis unterschiedlich genau untersuchen zu lassen. Ich werde vergessen, was was ist, und beim Debuggen falsche Annahmen treffen
rcreswick
1
Dies ist der falsche Weg, um Pylint zu reparieren - indem Sie einige seiner Funktionen deaktivieren. Sie müssen lediglich ein Pylint-Plugin installieren, das Django versteht . Siehe stackoverflow.com/a/31000713/78234
Tal Weiss
3

Die in dieser anderen Frage vorgeschlagene Lösung besteht darin , Ihrer Tag-Klasse einfach get_attr hinzuzufügen . Hässlich, funktioniert aber.

Eric
quelle
1

Bisher habe ich keine wirkliche Lösung dafür gefunden, sondern arbeite daran:

  • In unserem Unternehmen benötigen wir einen Pylint-Score> 8. Dies ermöglicht Codierungspraktiken, die Pylint nicht versteht, und stellt gleichzeitig sicher, dass der Code nicht zu "ungewöhnlich" ist. Bisher haben wir keinen Fall gesehen, in dem E1101 uns davon abgehalten hat, eine Punktzahl von 8 oder höher zu erreichen.
  • Unsere "Make Check" -Ziele filtern "für hat keine" Objekt "-Mitgliedsnachrichten heraus, um den größten Teil der Ablenkung zu beseitigen, die durch Pylint verursacht wird, der Django nicht versteht.
max
quelle
0

Zur neovim & vim8Verwendung w0rp's alePlugin. Wenn Sie alles richtig installiert haben , einschließlich w0rp's ale, pylint& pylint-django. vimrcFügen Sie die folgende Zeile hinzu und haben Sie Spaß beim Entwickeln von Web-Apps mit Django. Vielen Dank.

let g:ale_python_pylint_options = '--load-plugins pylint_django'
Ganesh
quelle