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

114

Я бы очень хотел интегрировать pylint в процесс сборки для мои проекты python, но я столкнулся с одним шоу-пробкой: один из типы ошибок, которые я считаю чрезвычайно полезными -: E1101: *%s %r has no %r member* - постоянно сообщает об ошибках при использовании общих полей 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, а не в источнике, который он загружал/вызывал.)

  • 4
    см. сообщение @ talweiss для получения актуального ответа!
  • 0
    Нашел хорошее решение на stackoverflow.com/a/31000713/78234
Показать ещё 1 комментарий
Теги:
pylint
static-analysis

11 ответов

87

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

pip install pylint-django

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

--load-plugins pylint_django

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

  • 8
    Это должен быть принятый ответ как можно скорее
  • 1
    Ссылка на пост в блоге мертва (так скоро). Вот несколько архивных ссылок из интернет-архива и из archive.is
Показать ещё 7 комментариев
65

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

  • 1
    Еще? Это сделало трюк для объектов оповещения.
  • 0
    man pylint (1) в TYPECHECK --generated-members=<members names> Список членов, которые устанавливаются динамически и пропускаются системой вывода pylint, и поэтому не должны вызывать E0201 и E1101 при доступе. [current: REQUEST, acl_users, aq_parent]
Показать ещё 3 комментария
30

My ~/.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).

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

  • 0
    Вы должны отправить свой патч в Pylint обратно сопровождающим.
  • 0
    на самом деле они включили этот патч в 0.24, но они начали использовать пакет shlex и теперь сломали что-то еще. Мне пришлось добавить gen.wordchars += "[]-+" в строке 135, чтобы заставить его работать ...
Показать ещё 3 комментария
19

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

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

  • 1
    Мне нравится идея специфического для Django пиллинга, но в прошлый раз, когда я его пробовал, это кажется большой ошибкой.
  • 3
    Кроме того, он не доступен через PyPI, и веб-сайт не предоставляет достаточно информации, например: Какая текущая версия?
Показать ещё 5 комментариев
16

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

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

  • 3
    Научить Pylint Django непросто, но это было сделано: все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. Stackoverflow.com/a/31000713/78234
  • 0
    Ну, я установил его, но он все еще относится к тонким, как QuerySet не имеет удаления ...
7

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

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

  • 0
    Ах ... спасибо за совет. Я могу попробовать просто добавить это в Model.models в локальной копии исходного кода django и посмотреть, так ли это.
  • 0
    Я думаю, что это отличное решение, потому что оно не ставит под угрозу предупреждения.
Показать ещё 3 комментария
6

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

  • 0
    интересно - я еще раз посмотрю на хлопьев.
  • 2
    PyChecker ловит намного меньше чем pylint. doughellmann.com/articles/CompletelyDifferent-2008-03-linters/...
Показать ещё 1 комментарий
5

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

pylint --ignored-classes=Tags

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

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

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

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

  • 0
    Это работает, только если я никогда не делаю ошибок в этих классах;). Я хочу избежать игнорирования кода, если это вообще возможно - я думаю, что это очень плохая идея, чтобы разные части кодовой базы анализировали разные степени проверки. Я забуду что есть что и сделаю ложные предположения при отладке
  • 1
    Это неправильный способ исправить Pylint - отключив некоторые его функции. Все, что вам нужно сделать, это установить плагин Pylint, который понимает Django. См. Stackoverflow.com/a/31000713/78234
2

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

2

До сих пор я не нашел реального решения для этого, но работал:

  • В нашей компании нам нужна пилинга оценкa > 8. Это позволяет кодировать практики pylint не понимает гарантируя, что код не слишком "необычный". До сих пор мы не видели любой случай, когда E1101 держал нас от достижения 8 баллов или выше.
  • Наши цели "проверить" отфильтровать "для не имеет" объектов "члена", чтобы удалить большую часть отвлечение, вызванное pylint not понимая Django.
0

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

pip install pylint-django

И добавьте в конфигурацию VSC:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню