Używanie Pylint z Django

140

Bardzo chciałbym zintegrować pylint z procesem kompilacji moich projektów w Pythonie, ale natknąłem się na jeden show-stopper: jeden z typów błędów, który uważam za niezwykle przydatny -: - E1101: *%s %r has no %r member*stale zgłasza błędy podczas korzystania z typowych pól django , na przykład:

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

co jest spowodowane tym kodem:

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

Jak mogę tak dostroić Pylint, aby odpowiednio uwzględniał takie pola, jak obiekty? (Zajrzałem również do źródła Django i nie mogłem znaleźć implementacji objects, więc podejrzewam, że nie jest to „tylko” pole klasy. Z drugiej strony, jestem całkiem nowy w Pythonie, więc mogli coś przeoczyć).

Edycja: Jedynym sposobem, w jaki udało mi się powiedzieć pylintowi, aby nie ostrzegał o tych ostrzeżeniach, jest blokowanie wszystkich błędów typu (E1101), co nie jest akceptowalnym rozwiązaniem, ponieważ jest to (moim zdaniem) niezwykle przydatny błąd. Jeśli jest inny sposób, bez rozszerzania źródła pylinta, proszę o wskazanie szczegółów :)

Zobacz tutaj podsumowanie problemów, z którymi miałem pycheckeri pyflakes- okazały się one zbyt niestabilne do ogólnego użytku. (W przypadku pychecker, awarie pochodzą z kodu pychecker - a nie źródła, które ładował / wywoływał).

rcreswick
źródło
4
Zobacz post @ talweiss, aby uzyskać aktualną odpowiedź!
Brendan
Znalazłem dobre rozwiązanie na stackoverflow.com/a/31000713/78234
shahjapan
1
Czy możesz zaakceptować odpowiedź @talweiss? To najbardziej aktualne i poprawne rozwiązanie.
Vijay Varadan

Odpowiedzi:

155

Nie wyłączaj ani nie osłabiaj funkcjonalności Pylint, dodając ignoreslub generated-members.
Użyj aktywnie rozwijanej wtyczki Pylint, która rozumie Django.
Ta wtyczka Pylint dla Django działa całkiem dobrze:

pip install pylint-django

i podczas uruchamiania pylint dodaj następującą flagę do polecenia:

--load-plugins pylint_django

Szczegółowy wpis na blogu tutaj .

Tal Weiss
źródło
2
Link do posta na blogu jest martwy (tak szybko). Oto kilka zarchiwizowanych linków z Internet Archive oraz z archive.is
Christian Long
3
Aby działało z wtyczką SublimeLinter Sublime Text, musiałem dodać --load-plugins=pylint_djangoustawienie linters / pylint / args. Zwróć uwagę na znak „=”, bez niego to nie zadziałało.
Dennis Golomazov
to nie działa. Otrzymuję ten błąd: E: 8, 0: No name 'models' w module 'django.db' (no-name-in-module)
max
6
Możesz również dodać to w swoim pylintrc:[MASTER] load-plugins=pylint_django
azmeuk
3
W kodzie vs nie działa to dla mnie, dopóki nie {"python.linting.pylintArgs": [ "--load-plugins=pylint_django" ],} wstawię w
ali-myousefi
63

Używam następujących: pylint --generated-members=objects

Shai
źródło
man pylint (1) w TYPECHECK --generated-members=<members names>Lista elementów, które są ustawiane dynamicznie i pomijane przez system wnioskowania pylint, a więc nie powinny uruchamiać E0201 i E1101 podczas dostępu. [current: REQUEST, acl_users, aq_parent]
Mark Mikofski
Dodam to w PyDev w eclipse w preferencjach w sekcji PyDev / PyLint .
Mark Mikofski
2
Korzystanie z wygenerowanych elementów po prostu ukrywa te błędy przed tobą, nadal mogą wystąpić błędy podczas próby dostępu do pola obiektów na niewłaściwym obiekcie. Zamiast tego użyj wtyczki pylint-django.
Vajk Hermecz
5
To jest zły sposób na naprawienie Pylinta - poprzez wyłączenie części jego funkcjonalności. Wszystko, co musisz zrobić, to zainstalować wtyczkę pylint że rozumie Django. Zobacz stackoverflow.com/a/31000713/78234
Tal Weiss
31

Mój ~ / .pylintrc zawiera

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

ostatnie dwa są przeznaczone specjalnie dla Django.

Zauważ, że w PyLint 0.21.1 jest błąd, który wymaga łatania, aby to działało.

Edycja: Po tym, jak trochę się z tym pogubiłem, zdecydowałem się trochę zhakować PyLint, aby umożliwić mi rozwinięcie powyższego do:

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

Po prostu dodałem:

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

po poprawce wymienionej w zgłoszeniu błędu (tj. w linii 129).

Szczęśliwe dni!

Szymon
źródło
Powinieneś przesłać poprawkę do pylinta z powrotem do opiekunów.
slacy
właściwie umieścili tę poprawkę w 0.24, ale zaczęli używać tego shlexpakietu i teraz zepsuli coś innego. Musiałem dodać gen.wordchars += "[]-+"w linii 135, żeby to zadziałało ...
simon
4
Używanie wygenerowanych elementów tylko ukrywa te błędy przed tobą, nadal mogą wystąpić błędy podczas próby uzyskania dostępu do pola „obiekty” na niewłaściwym obiekcie. Zamiast tego użyj wtyczki pylint-django.
Vajk Hermecz
4
To jest zły sposób na naprawienie Pylinta - poprzez wyłączenie części jego funkcjonalności. Wszystko, co musisz zrobić, to zainstalować wtyczkę pylint że rozumie Django. Zobacz stackoverflow.com/a/31000713/78234
Tal Weiss
3
@TalWeiss - uczciwie, ta odpowiedź jest o trzy lata starsza niż pylint-django, więc głos negatywny jest nieco ostry ...
simon
27

Jeśli używasz Visual Studio Code, zrób to:

pip install pylint-django

I dodaj do konfiguracji VSC:

"python.linting.pylintArgs": [
    "--load-plugins=pylint_django"
],
Thiago Falcao
źródło
2
Zdecydowanie najlepsza odpowiedź: D
serfer2
19

django-lint to fajne narzędzie, które otacza pylint z określonymi ustawieniami django: http://chris-lamb.co.uk/projects/django-lint/

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

gurney alex
źródło
1
Podoba mi się pomysł pylinta specyficznego dla Django, ale ostatnim razem, gdy go wypróbowałem, wydaje mi się, że to duży błąd.
Wernight,
3
Nie jest również dostępny przez PyPI, a strona nie zawiera wystarczających informacji, takich jak: Jaka jest aktualna wersja?
Wernight,
1
Podoba mi się ta koncepcja, ale ta implementacja jest tylko niedopracowana i psuje się w każdej bazie kodu o średniej wielkości. Ma wiele do zrobienia, zanim stanie się użyteczna.
Cerin,
1
@gurney alex, Link nie żyje.
transfer: 87
2
Wygląda na to, że pylint-django jest teraz bardziej aktywny, to powinno być zalecane rozwiązanie.
Vajk Hermecz
16

Ze względu na to, jak działa pylint (bada samo źródło, nie pozwalając Pythonowi na jego wykonanie), bardzo trudno pylintowi dowiedzieć się, jak metaklasy i złożone klasy bazowe wpływają na klasę i jej instancje. The „pychecker” narzędzie jest nieco lepiej w tym względzie, ponieważ nie faktycznie niech Python wykonać kod; importuje moduły i sprawdza wynikowe obiekty. Jednak takie podejście ma inne problemy, ponieważ w rzeczywistości pozwala Pythonowi wykonać kod :-)

Możesz rozszerzyć pylint, aby nauczyć go o magii, której używa Django, lub aby lepiej rozumiał metaklasy lub złożone klasy podstawowe, lub po prostu zignorować takie przypadki po wykryciu jednej lub więcej funkcji, których nie do końca rozumie. Nie sądzę, żeby to było szczególnie łatwe. Możesz także po prostu powiedzieć pylintowi, aby nie ostrzegał o tych rzeczach, poprzez specjalne komentarze w źródle, opcje wiersza poleceń lub plik .pylintrc.

Thomas Wouters
źródło
3
Nie jest łatwo nauczyć Pylint o Django, ale zostało zrobione: Wszystko, co musisz zrobić, to zainstalować wtyczkę Pylint, która rozumie Django. Zobacz stackoverflow.com/a/31000713/78234
Tal Weiss
Cóż, zainstalowałem go, ale nadal zawiera rzeczy, takie jak QuerySet nie ma usuwania ...
Eino Mäkitalo
7

Zrezygnowałem z używania pylint / pychecker na rzecz używania pyflakes z kodem Django - po prostu próbuje zaimportować moduł i zgłasza wszelkie znalezione problemy, takie jak nieużywane importy lub niezainicjowane nazwy lokalne.

zgoda
źródło
ciekawe - dam pyflakes jeszcze raz.
rcreswick
2
PyChecker łapie znacznie mniej niż pylint. doughellmann.com/articles/CompletelyDifferent-2008-03-linters/…
Justin Abrahms
1
Nie musisz rezygnować z Pylint - wszystko, co musisz zrobić, to zainstalować wtyczkę Pylint, która rozumie Django. Zobacz stackoverflow.com/a/31000713/78234
Tal Weiss
7

To nie jest rozwiązanie, ale możesz dodawać objects = models.Manager()do swoich modeli Django bez zmiany zachowania.

Ja sam używam tylko pyflakes, głównie ze względu na głupie domyślne ustawienia pylinta i lenistwo z mojej strony (nie chcąc sprawdzać, jak zmienić ustawienia domyślne).

AdamKG
źródło
Ach ... dzięki za wskazówkę. Mogę po prostu dodać to do Model.models w lokalnej kopii źródła django i zobaczyć, czy to wystarczy.
rcreswick
Myślę, że to świetne rozwiązanie, ponieważ nie idzie na kompromis w kwestii ostrzeżeń.
Tom Leys
1
To jest złe rozwiązanie. Powtarzanie się i zastępowanie czegoś, co jest możliwe, zmieni się później (w ten sposób wprowadzając problem z kontrolą jakości), tylko po to, aby naprawić niekompletne narzędzie do kontroli jakości?
Chris Morgan,
2
Nie nazwałbym tego złym rozwiązaniem: wyraźne jest lepsze niż niejawne. Być może i objectstak nie powinno się ich magicznie dodawać.
Will Hardy
1
Myślę, że to zły sposób na naprawienie Pylinta - w pewnym sensie łatanie Django. Wszystko, co musisz zrobić, to zainstalować wtyczkę pylint że rozumie Django. Zobacz stackoverflow.com/a/31000713/78234
Tal Weiss
5

Spróbuj uruchomić pylint z

pylint --ignored-classes=Tags

Jeśli to zadziała, dodaj wszystkie inne klasy Django - prawdopodobnie używając skryptu, na przykład python: P

Dokumentacja dla --ignore-classes:

--ignored-classes=<members names>
Lista nazw klas, dla których atrybuty składowe nie powinny być sprawdzane (przydatne dla klas z ustawionymi dynamicznie atrybutami). [current:% default]

Dodam, że moim zdaniem nie jest to szczególnie eleganckie rozwiązanie, ale powinno działać.

wolna przestrzeń
źródło
Działa tylko wtedy, gdy nigdy nie popełnię błędów na tych zajęciach;). Jeśli to możliwe, chcę uniknąć ignorowania kodu - myślę, że bardzo złym pomysłem jest analizowanie różnych części kodu w różnym stopniu szczegółowości.
Zapomnę,
1
To jest zły sposób na naprawienie Pylinta - poprzez wyłączenie części jego funkcjonalności. Wszystko, co musisz zrobić, to zainstalować wtyczkę pylint że rozumie Django. Zobacz stackoverflow.com/a/31000713/78234
Tal Weiss
3

Rozwiązanie zaproponowane w tym drugim pytaniu polega po prostu na dodaniu get_attr do Twojej klasy Tag. Brzydki, ale działa.

eric
źródło
1

Jak dotąd nie znalazłem prawdziwego rozwiązania tego problemu, ale obejdź:

  • W naszej firmie wymagamy wyniku pylint> 8. Pozwala to na kodowanie, którego pylint nie rozumie, jednocześnie zapewniając, że kod nie jest zbyt „niezwykły”. Jak dotąd nie widzieliśmy żadnego przypadku, w którym E1101 uniemożliwiłby nam osiągnięcie wyniku 8 lub wyższego.
  • Nasze cele „make check” odfiltrowują komunikaty „for nie mają żadnych komunikatów„ objects ”member”, aby usunąć większość zakłóceń spowodowanych przez pylint, który nie rozumie Django.
max
źródło
0

Do neovim & vim8użytku w0rp's aleplugin. Jeśli zainstalowałeś wszystko poprawnie w tym w0rp's ale, pylintze pylint-django. W swojej vimrcdodać następujący wiersz i baw tworzeniu aplikacji internetowych przy użyciu Django. Dzięki.

let g:ale_python_pylint_options = '--load-plugins pylint_django'
Ganesh
źródło