Использование Pylint с Django
Я бы очень хотел интегрировать 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, а не в источнике, который он загружал/вызывал.)
Ответы
Ответ 1
Не отключайте и не ослабляйте функциональность Pylint, добавляя ignores
или generated-members
.
Используйте активно разработанный плагин Pylint, который понимает Django.
Этот плагин Pylint для Django работает достаточно хорошо:
pip install pylint-django
и при запуске pylint добавьте в команду следующий флаг:
--load-plugins pylint_django
Подробное сообщение в блоге здесь.
Ответ 2
Я использую следующее: pylint --generated-members=objects
Ответ 3
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).
Счастливые дни!
Ответ 4
django-lint - отличный инструмент, который обертывает pylint с помощью специальных настроек django: http://chris-lamb.co.uk/projects/django-lint/
Проект github: https://github.com/lamby/django-lint
Ответ 5
Из-за того, как работает pylint (он исследует сам источник, не позволяя Python фактически выполнять его), очень сложно для pylint выяснить, как метаклассы и сложные базовые очки действительно влияют на класс и его экземпляры. Инструмент "pychecker" немного лучше в этом отношении, потому что он действительно позволяет Python выполнять код; он импортирует модули и анализирует результирующие объекты. Однако этот подход имеет другие проблемы, поскольку он действительно позволяет Python выполнять код: -)
Вы можете расширить pylint, чтобы научить его использованию волшебного Django, или лучше понять метаклассы или сложные базовые классы, или просто игнорировать такие случаи после обнаружения одной или нескольких функций, которые она не совсем понимает. Я не думаю, что это было бы очень легко. Вы также можете просто сказать pylint, чтобы не предупреждать об этих вещах, посредством специальных комментариев в исходном коде, параметрах командной строки или файле .pylintrc.
Ответ 6
Это не решение, но вы можете добавить objects = models.Manager()
к вашим моделям Django, не изменяя никакого поведения.
Я сам использую только pyflakes, прежде всего из-за некоторых немых значений по умолчанию в pylint и лень с моей стороны (не желая искать способ изменения значений по умолчанию).
Ответ 7
Я отказался от использования pylint/pychecker в пользу использования pyflakes с кодом Django - он просто пытается импортировать модуль и сообщает о любой проблеме, которую он находит, например, неиспользуемый импорт или неинициализированные локальные имена.
Ответ 8
Попробуйте запустить pylint с помощью
pylint --ignored-classes=Tags
Если это работает, добавьте все остальные классы Django - возможно, используя script, скажем, python: P
Документация для --ignore-classes
:
--ignored-classes=<members names>
Список имен классов, для которых член атрибуты не должны проверяться (полезно для классов с атрибутами динамический набор). [текущий:% по умолчанию]
Я должен добавить, что это не особое элегантное решение на мой взгляд, но оно должно работать.
Ответ 9
До сих пор я не нашел реального решения для этого, но работал:
- В нашей компании нам нужна пилинга
оценкa > 8. Это позволяет кодировать
практики pylint не понимает
гарантируя, что код не
слишком "необычный". До сих пор мы не видели
любой случай, когда E1101 держал нас
от достижения 8 баллов или
выше.
- Наши цели "проверить"
отфильтровать "для не имеет" объектов "члена", чтобы удалить большую часть
отвлечение, вызванное pylint not
понимая Django.
Ответ 10
Решение, предложенное в этом другом вопросе, просто добавит get_attr в ваш класс Tag. Уродливо, но работает.
Ответ 11
Если вы используете код Visual Studio, сделайте следующее:
pip install pylint-django
И добавьте в конфигурацию VSC:
"python.linting.pylintArgs": [
"--load-plugins=pylint_django"
],