Использование Pylint с Django

Я очень хотел бы интегрировать pylint в процесс сборки для моих проектов Python, но я столкнулся с одним show-stopper: один из типов ошибок, который я считаю чрезвычайно полезным -: _ 1 _-- постоянно сообщает об ошибках при использовании общих полей django, например:

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

что вызвано этим кодом:

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

Как настроить Pylint для правильного учета таких полей, как объекты? (Я также изучил исходный код Django, и мне не удалось найти реализацию objects, поэтому я подозреваю, что это не «просто» поле класса. С другой стороны, я новичок в python, поэтому Я вполне мог что-то пропустить.)

Изменить. Я нашел единственный способ указать pylint не предупреждать об этих предупреждениях - это заблокировать все ошибки типа (E1101), что не является приемлемым решением, поскольку это (на мой взгляд ) чрезвычайно полезная ошибка. Если есть другой способ, без дополнения источника pylint, укажите мне конкретику :)

См. здесь для обзора моих проблем с pychecker и pyflakes - они оказались очень нестабильными для общего использования. (В случае pychecker сбои возникли в коде pychecker, а не в источнике, который он загружал / вызывал.)


person rcreswick    schedule 22.09.2008    source источник
comment
см. сообщение @ talweiss для получения актуального ответа!   -  person Brendan    schedule 02.09.2015
comment
Нашел хорошее решение на stackoverflow.com/a/31000713/78234   -  person shahjapan    schedule 19.11.2015
comment
Не могли бы вы принять ответ @talweiss? Это самое актуальное и правильное решение.   -  person Vijay Varadan    schedule 19.02.2017


Ответы (12)


Не отключайте и не ослабляйте функциональность Pylint, добавляя ignores или generated-members.
Используйте активно разрабатываемый плагин Pylint, который понимает Django.
Этот плагин Pylint для Django работает достаточно хорошо:

pip install pylint-django

и при запуске pylint добавьте к команде следующий флаг:

--load-plugins pylint_django

Подробное сообщение в блоге здесь.

person Tal Weiss    schedule 23.06.2015
comment
Ссылка на сообщение в блоге мертва (так скоро). Вот несколько заархивированных ссылок из Интернет-архив и из archive.is - person Christian Long; 23.09.2015
comment
Чтобы заставить его работать с плагином SublimeLinter Sublime Text, мне пришлось добавить --load-plugins=pylint_django в настройку linters / pylint / args. Обратите внимание на знак «=», без него ничего не получилось. - person Dennis Golomazov; 19.11.2015
comment
это не работает. Я получаю эту ошибку: E: 8, 0: Нет имени 'models' в модуле 'django.db' (no-name-in-module) - person max; 07.12.2015
comment
@max Какая у вас полная командная строка? Версии Django и pylint? Полный вывод pylint run? - person Tal Weiss; 08.12.2015
comment
django 1.8 pylint == 1.4.3 pylint-django == 0.7.1 Я не думаю, что здесь уместно помещать stacktrace ... - person max; 09.12.2015
comment
При использовании django 1.9, pylint 1.5.2 и pylint-django 0.7.1 плагин pylint_django не отображал models.Manager.get как допустимый метод. - person kzh; 08.01.2016
comment
Можете ли вы привести пример того, как я бы использовал его в проекте Django? pylint --load-plugins pylint_django (как мне здесь обратиться к моему проекту Django?) - person caliph; 16.03.2016
comment
Вы также можете добавить это в свой pylintrc: [MASTER] load-plugins=pylint_django - person azmeuk; 14.06.2016
comment
В коде vs это не сработает для меня, пока я не введу следующее в пользовательские настройки: {"python.linting.pylintArgs": [ "--load-plugins=pylint_django" ],} ответ от tieuminh2510 - person ali-myousefi; 14.07.2019
comment
@azmeuk Спасибо! Заголовок раздела разобраться не смог! Почему МАСТЕР? Где это задокументировано? Как мне узнать в следующий раз, как должны выглядеть формат и разделы .pylintrc? - person cammil; 03.12.2020
comment
Честно говоря, не могу вспомнить, где это нашел :( - person azmeuk; 03.12.2020

Я использую следующее: pylint --generated-members=objects

person Community    schedule 12.09.2009
comment
man pylint (1) в TYPECHECK --generated-members=<members names> Список члены, которые устанавливаются динамически и пропускаются системой вывода pylint, поэтому не должны вызывать E0201 и E1101 при доступе. [текущий: ЗАПРОС, acl_users, aq_parent] - person Mark Mikofski; 02.05.2012
comment
Я добавляю это в PyDev в eclipse под настройками в разделе PyDev / PyLint. - person Mark Mikofski; 02.05.2012
comment
Использование сгенерированных членов просто скрывает эти ошибки от вас, все еще могут быть ошибки при попытке доступа к полю объектов на неправильном объекте. Вместо этого используйте плагин pylint-django. - person Vajk Hermecz; 12.02.2015
comment
Это неправильный способ исправить Pylint - отключив некоторые его функции. Все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. stackoverflow.com/a/31000713/78234 - person Tal Weiss; 23.06.2015

Если вы используете Visual Studio Code, сделайте следующее:

pip install pylint-django

И добавляем в конфиг VSC:

"python.linting.pylintArgs": [
    "--load-plugins=pylint_django"
],
person Thiago Falcao    schedule 12.12.2017
comment
Лучший ответ на сегодняшний день: D - person serfer2; 10.09.2019

Мой ~ / .pylintrc содержит

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

последние два предназначены специально для Django.

Обратите внимание, что в PyLint 0.21.1 есть ошибка, требующая исправления для работы.

Изменить: немного поработав с этим, я решил немного взломать PyLint, чтобы позволить мне расширить приведенное выше до:

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

Я просто добавил:

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

после исправления, упомянутого в отчете об ошибке (т. е. в строке 129).

Счастливые дни!

person simon    schedule 12.11.2010
comment
Вы должны отправить свой патч в pylint обратно разработчикам. - person slacy; 17.06.2011
comment
на самом деле они включили этот патч в 0.24, но они начали использовать пакет shlex и сломали кое-что еще. Мне пришлось добавить gen.wordchars += "[]-+" в строке 135, чтобы заставить его работать ... - person simon; 02.10.2011
comment
Использование сгенерированных членов просто скрывает эти ошибки от вас, все еще могут быть ошибки при попытке доступа к полю «объекты» на неправильном объекте. Вместо этого используйте плагин pylint-django. - person Vajk Hermecz; 12.02.2015
comment
@TalWeiss - честно говоря, этот ответ на три года старше, чем pylint-django, поэтому отрицательный голос немного резок ... - person simon; 24.06.2015

django-lint - хороший инструмент, который обертывает pylint специфическими настройками django: http://chris-lamb.co.uk/projects/django-lint/

проект github: https://github.com/lamby/django-lint

person gurney alex    schedule 16.03.2010
comment
Мне нравится идея pylint, специфичного для Django, но в прошлый раз, когда я ее пробовал, она показалась мне большой ошибкой. - person Wernight; 21.07.2010
comment
Кроме того, он недоступен через PyPI, и веб-сайт, похоже, не дает достаточно информации, например: Какая текущая версия? - person Wernight; 21.07.2010
comment
Мне нравится эта концепция, но эта реализация является лишь недоработанной и не работает на любой кодовой базе среднего размера. Ему предстоит пройти долгий путь, прежде чем он станет действительно полезным. - person Cerin; 17.08.2011
comment
django-lint? это довольно интересно. Я посмотрю на это - person juliomalegria; 07.12.2011
comment
@gurney alex, линк мертв. - person shuttle87; 19.01.2015
comment
Похоже, что pylint-django сейчас более активен, это должно быть рекомендуемым решением. - person Vajk Hermecz; 12.02.2015
comment
Ссылка не работает, и репо на Github не трогали уже 3 года. Для активного решения и плагина Pylint, который понимает Django. См. stackoverflow.com/a/31000713/78234 - person Tal Weiss; 23.06.2015

Из-за того, как работает pylint (он проверяет сам источник, не позволяя Python выполнять его), pylint очень сложно понять, как метаклассы и сложные базовые классы на самом деле влияют на класс и его экземпляры. Инструмент pychecker в этом отношении немного лучше, потому что он действительно позволяет Python выполнять код; он импортирует модули и проверяет полученные объекты. Однако у этого подхода есть другие проблемы, потому что он действительно позволяет Python выполнять код :-)

Вы можете расширить pylint, чтобы научить его магии, которую использует Django, или чтобы он лучше понимал метаклассы или сложные базовые классы, или просто игнорировал такие случаи после обнаружения одной или нескольких функций, которые он не совсем понимает. Не думаю, что это будет особенно легко. Вы также можете просто указать pylint не предупреждать об этих вещах с помощью специальных комментариев в исходном коде, параметров командной строки или файла .pylintrc.

person Thomas Wouters    schedule 22.09.2008
comment
Научить Pylint работе с Django непросто, но это было сделано: все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. stackoverflow.com/a/31000713/78234 - person Tal Weiss; 23.06.2015
comment
Ну, я установил его, но он по-прежнему жалуется, например, QuerySet не удаляется ... - person Eino Mäkitalo; 18.06.2018

Я отказался от использования pylint / pychecker в пользу использования pyflakes с кодом Django - он просто пытается импортировать модуль и сообщает о любых обнаруженных проблемах, таких как неиспользуемый импорт или неинициализированные локальные имена.

person zgoda    schedule 22.09.2008
comment
интересно - еще раз посмотрю на пифлейк. - person rcreswick; 23.09.2008
comment
PyChecker ловит гораздо меньше, чем pylint. doughellmann.com/articles/CompletelyDifferent-2008-03-linters/ - person Justin Abrahms; 07.11.2009
comment
Не нужно отказываться от Pylint - все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. stackoverflow.com/a/31000713/78234 - person Tal Weiss; 23.06.2015

Это не решение, но вы можете добавить objects = models.Manager() в свои модели Django, не меняя поведения.

Я сам использую только pyflakes, в первую очередь из-за некоторых глупых значений по умолчанию в pylint и моей лени (не желая искать, как изменить значения по умолчанию).

person AdamKG    schedule 23.09.2008
comment
Ах ... спасибо за подсказку. Я могу попробовать просто добавить это в Model.models в локальную копию источника django и посмотреть, поможет ли это. - person rcreswick; 23.09.2008
comment
Я думаю, что это отличное решение, потому что оно не снижает предупреждений. - person Tom Leys; 22.03.2009
comment
Это плохое решение. Повторение и замена того, что возможно, изменится позже (что приведет к возникновению проблемы контроля качества), просто чтобы исправить неполный инструмент контроля качества? - person Chris Morgan; 11.06.2012
comment
Я бы не назвал это плохим решением: явное лучше, чем неявное. Возможно, objects в любом случае не следует добавлять волшебным образом. - person Will Hardy; 30.04.2013
comment
Я думаю, что это неправильный способ исправить Pylint - в некотором смысле исправляя Django. Все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. stackoverflow.com/a/31000713/78234 - person Tal Weiss; 23.06.2015

Попробуйте запустить pylint с

pylint --ignored-classes=Tags

Если это сработает, добавьте все остальные классы Django - возможно, используя скрипт, скажем, python: P

Документация для --ignore-classes:

--ignored-classes=<members names>
Список имен классов, для которых не следует проверять атрибуты членов (полезно для классов с динамически установленными атрибутами). [текущий:% по умолчанию]

Я должен добавить, что это не особо элегантное решение, на мой взгляд, но оно должно работать.

person freespace    schedule 22.09.2008
comment
Это работает, только если я никогда не делаю ошибок в этих классах;). Я хочу избегать игнорирования кода, если это вообще возможно - я считаю, что проводить анализ разных частей кодовой базы с разной степенью тщательности - очень плохая идея. Я забуду, что есть что, и сделаю ложные предположения при отладке - person rcreswick; 22.09.2008
comment
Это неправильный способ исправить Pylint - отключив некоторые его функции. Все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. stackoverflow.com/a/31000713/78234 - person Tal Weiss; 23.06.2015

Решение, предложенное в этом другом вопросе просто добавьте get_attr в свой класс Tag. Некрасиво, но работает.

person eric    schedule 24.02.2011

Пока я не нашел реального решения для этого, но работаю:

  • В нашей компании нам требуется оценка pylint> 8. Это позволяет практикам кодирования, которые pylint не понимает, при этом гарантируя, что код не будет слишком «необычным». До сих пор мы не видели ни одного случая, когда E1101 не позволял нам набрать 8 или больше баллов.
  • Наши цели 'make check' отфильтровывают сообщения «for has no 'objects' member», чтобы убрать большую часть отвлекающих факторов, вызванных тем, что pylint не понимает Django.
person max    schedule 04.01.2009

Для neovim & vim8 используйте w0rp's ale плагин. Если вы установили все правильно, включая w0rp's ale, pylint & pylint-django. Добавьте в свой vimrc следующую строку и получайте удовольствие от разработки веб-приложений с помощью django. Спасибо.

let g:ale_python_pylint_options = '--load-plugins pylint_django'
person Ganesh    schedule 14.06.2018
comment
действительно работал идеально для меня, на купленных vim и neovim, спасибо. - person Flavio Oliveira; 19.08.2020