Utilizzo di Pylint con Django


140

Mi piacerebbe molto integrare Pylint nel processo di compilazione per i miei progetti Python, ma mi sono imbattuto in uno show-stopper: Uno dei tipi di errore che trovo estremamente utile--: E1101: *%s %r has no %r member*- Riporta costantemente errori quando si usano i campi django comuni , per esempio:

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

che è causato da questo codice:

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

Come posso sintonizzare Pylint per prendere correttamente in considerazione campi come gli oggetti? (Ho anche esaminato la fonte Django e non sono stato in grado di trovare l'implementazione di objects, quindi sospetto che non sia "solo" un campo di classe. D'altra parte, sono abbastanza nuovo in Python, quindi ho potrebbe benissimo aver trascurato qualcosa).

Modifica: L'unico modo che ho trovato per dire a Pylint di non avvisare di questi avvisi è bloccando tutti gli errori del tipo (E1101) che non è una soluzione accettabile, dal momento che (a mio avviso) è un errore estremamente utile. Se esiste un altro modo, senza aumentare la fonte del pylint, per favore indicami le specifiche :)

Vedi qui per un riepilogo dei problemi che ho avuto con pycheckere pyflakes- hanno dimostrato di essere molto instabili per un uso generale. (Nel caso di pychecker, gli arresti anomali hanno avuto origine nel codice pychecker - non la fonte stava caricando / invocando.)


4
vedi il post di @ talweiss per una risposta aggiornata!
Brendan,

Buona soluzione trovata a stackoverflow.com/a/31000713/78234
shahjapan

1
Potete per favore accettare la risposta di @talweiss? È la soluzione più aggiornata e corretta.
Vijay Varadan,

Risposte:


155

Non disabilitare o indebolire la funzionalità Pylint aggiungendo ignoreso generated-members.
Usa un plug-in Pylint sviluppato attivamente che capisca Django.
Questo plugin Pylint per Django funziona abbastanza bene:

pip install pylint-django

e quando si esegue pylint aggiungere il seguente flag al comando:

--load-plugins pylint_django

Post di blog dettagliato qui .


2
Il link al post del blog è morto (così presto). Ecco alcuni link archiviati da Internet Archive e da archive.is
Christian Long,

3
Per farlo funzionare con il plugin SublimeLinter di Sublime Text, ho dovuto aggiungere l' --load-plugins=pylint_djangoimpostazione linters / pylint / args. Nota il segno '=', non funzionava senza di essa.
Dennis Golomazov,

non funziona. Ottengo questo errore: E: 8, 0: nessun nome "modelli" nel modulo "django.db" (nessun nome nel modulo)
massimo

6
Puoi anche aggiungerlo nel tuo pilastro:[MASTER] load-plugins=pylint_django
azmeuk,

3
Nel codice vs la dose non funziona per me fino a quando non {"python.linting.pylintArgs": [ "--load-plugins=pylint_django" ],} inserisco
ali-myousefi

63

Io uso il seguente: pylint --generated-members=objects


man pylint (1) in TYPECHECK --generated-members=<members names>Elenco dei membri che sono impostati in modo dinamico e mancati dal sistema di inferenza del pylint, e quindi non dovrebbero attivare E0201 ed E1101 quando vi si accede. [corrente: RICHIESTA, acl_users, aq_parent]
Mark Mikofski

Aggiungo questo in PyDev in eclipse sotto le preferenze nella sezione PyDev / PyLint .
Mark Mikofski

2
L'uso dei membri generati ti nasconde questi errori, ci possono essere ancora errori quando si tenta di accedere al campo oggetti sull'oggetto sbagliato. Utilizzare invece il plug-in pylint-django.
Vajk Hermecz,

5
Questo è il modo sbagliato di riparare Pylint, disabilitando alcune delle sue funzionalità. Tutto quello che devi fare è installare un plugin Pylint che capisca Django. Vedi stackoverflow.com/a/31000713/78234
Tal Weiss il

31

Il mio ~ / .pylintrc contiene

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

gli ultimi due sono specifici per Django.

Si noti che esiste un bug in PyLint 0.21.1 che necessita di patch per farlo funzionare.

Modifica: dopo aver fatto un po 'di casino con questo, ho deciso di hackerare PyLint solo un po' per consentirmi di espandere quanto sopra in:

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

Ho semplicemente aggiunto:

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

dopo la correzione menzionata nella segnalazione di bug (cioè alla riga 129).

Giorni felici!


È necessario inviare la patch per il pylint ai manutentori.
slacy,

in realtà hanno incluso questa patch in 0.24, ma hanno iniziato a usare il shlexpacchetto e ora hanno rotto qualcos'altro. Ho dovuto aggiungere gen.wordchars += "[]-+"alla riga 135 per farlo funzionare ...
simon

4
L'uso dei membri generati ti nasconde questi errori, ci possono essere ancora errori quando si tenta di accedere al campo "oggetti" sull'oggetto sbagliato. Utilizzare invece il plug-in pylint-django.
Vajk Hermecz,

4
Questo è il modo sbagliato di riparare Pylint, disabilitando alcune delle sue funzionalità. Tutto quello che devi fare è installare un plugin Pylint che capisca Django. Vedi stackoverflow.com/a/31000713/78234
Tal Weiss il

3
@TalWeiss - in tutta onestà, questa risposta ha tre anni più di pylint-django, quindi il downvote è un po 'duro ...
simon

27

Se si utilizza Visual Studio Code, procedere come segue:

pip install pylint-django

E aggiungi alla configurazione VSC:

"python.linting.pylintArgs": [
    "--load-plugins=pylint_django"
],

2
Migliore risposta di gran lunga: D
serfer2

19

django-lint è uno strumento piacevole che avvolge il pylint con impostazioni specifiche di django: http://chris-lamb.co.uk/projects/django-lint/

progetto github: https://github.com/lamby/django-lint


1
Mi piace l'idea di un pilone specifico per Django, ma l'ultima volta che l'ho provato sembra un grosso problema.
Wernight,

3
Inoltre non è disponibile tramite PyPI e il sito Web non sembra fornire informazioni sufficienti come: Qual è la versione corrente?
Wernight,

1
Mi piace il concetto, ma questa implementazione è solo a metà e si interrompe su qualsiasi base di codice di dimensioni moderate. Ha una lunga strada da percorrere prima che sia effettivamente utile.
Cerin,

1
@gurney alex, Link è morto.
shuttle87,

2
Sembra che Pylint-Django sia più attivo ora, questa dovrebbe essere la soluzione consigliata.
Vajk Hermecz,

16

A causa di come funziona la pylint (esamina la fonte stessa, senza lasciare che Python la esegua effettivamente) è molto difficile per la pylint capire come le metaclasse e le basi complesse influenzino effettivamente una classe e le sue istanze. Lo strumento 'pychecker' è un po 'migliore in questo senso, perché lo fa in realtà lascia Python eseguire il codice; importa i moduli ed esamina gli oggetti risultanti. Tuttavia, questo approccio ha altri problemi, perché in realtà consente a Python di eseguire il codice :-)

Potresti estendere il pylint per insegnarlo sugli incantesimi che Django usa, o per fargli capire meglio metaclassi o basi complesse, o semplicemente ignorare questi casi dopo aver rilevato una o più caratteristiche che non comprende. Non penso che sarebbe particolarmente facile. Puoi anche dire a pylint di non avvisare di queste cose, attraverso commenti speciali nel sorgente, opzioni della riga di comando o un file .pylintrc.


3
Non è facile insegnare a Pylint di Django, ma è stato fatto: tutto ciò che devi fare è installare un plugin Pylint che capisca Django. Vedi stackoverflow.com/a/31000713/78234
Tal Weiss il

Beh, l'ho installato, ma si basa ancora su cose come QuerySet non può essere rimosso ...
Eino Mäkitalo,

7

Mi sono dimesso dall'uso di pylint / pychecker a favore dell'uso di pyflakes con codice Django: tenta solo di importare il modulo e segnala qualsiasi problema che riscontra, come importazioni inutilizzate o nomi locali non inizializzati.


interessante - darò un'altra occhiata ai pyflakes.
rcreswick,


1
Non c'è bisogno di rinunciare a Pylint - Tutto quello che devi fare è installare un plugin Pylint che capisca Django. Vedi stackoverflow.com/a/31000713/78234
Tal Weiss il

7

Questa non è una soluzione, ma puoi aggiungere objects = models.Manager()ai tuoi modelli Django senza cambiare alcun comportamento.

Io stesso uso solo i pyflakes, principalmente a causa di alcune stupide impostazioni predefinite di pylint e pigrizia da parte mia (non voglio cercare come cambiare le impostazioni predefinite).


Ah ... grazie per la punta. Potrei provare ad aggiungerlo a Model.models nella copia locale della fonte django e vedere se lo fa.
Rcreswick,

Penso che sia un'ottima soluzione perché non scende a compromessi sugli avvisi.
Tom Leys,

1
Questa è una cattiva soluzione. Ripetersi e sostituire qualcosa che è fattibile cambierà in seguito (introducendo così un problema di QA), solo per correggere uno strumento di QA incompleto?
Chris Morgan,

2
Non la definirei una cattiva soluzione: esplicito è meglio di implicito. Forse objectsnon dovrebbe essere aggiunto magicamente comunque.
Will Hardy,

1
Penso che questo sia il modo sbagliato di riparare Pylint, rattoppando Django in un certo senso. Tutto quello che devi fare è installare un plugin Pylint che capisca Django. Vedi stackoverflow.com/a/31000713/78234
Tal Weiss il

5

Prova a eseguire il pilastro con

pylint --ignored-classes=Tags

Se funziona, aggiungi tutte le altre classi Django - possibilmente usando uno script, per esempio python: P

La documentazione per --ignore-classesè:

--ignored-classes=<members names>
Elenco dei nomi delle classi per i quali gli attributi dei membri non devono essere controllati (utile per le classi con attributi impostati dinamicamente). [corrente:% predefinito]

A mio avviso, questa non è una soluzione particolarmente elegante, ma dovrebbe funzionare.


Funziona solo se non commetto mai errori in quelle classi;). Voglio evitare di ignorare il codice se possibile - penso che sia una pessima idea avere parti diverse della base di codice analizzate con diversi gradi di controllo. Dimenticherò quale è quale, e farò false assunzioni durante il debug
rcreswick il

1
Questo è il modo sbagliato di riparare Pylint, disabilitando alcune delle sue funzionalità. Tutto quello che devi fare è installare un plugin Pylint che capisca Django. Vedi stackoverflow.com/a/31000713/78234
Tal Weiss il

3

La soluzione proposta in quest'altra domanda è semplicemente quella di aggiungere get_attr alla tua classe Tag. Brutto, ma funziona.


1

Finora non ho trovato una soluzione reale a questo, ma aggirare:

  • Nella nostra azienda è richiesto un punteggio di pylint> 8. Ciò consente pratiche di codifica che il pylint non comprende garantendo al contempo che il codice non sia troppo "insolito". Finora non abbiamo visto casi in cui E1101 ci ha impedito di raggiungere un punteggio di 8 o superiore.
  • I nostri target "make check" filtrano "perché non ha messaggi di" oggetti "per rimuovere la maggior parte della distrazione causata dal fatto che il pylint non capisca Django.

0

Per neovim & vim8utilizzare il w0rp's aleplugin. Se hai installato tutto correttamente incluso w0rp's ale, pylint& pylint-django. Nel tuo vimrcaggiungi la seguente riga e divertiti a sviluppare app Web usando Django. Grazie.

let g:ale_python_pylint_options = '--load-plugins pylint_django'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.