Using Pylint with Django
I would very much like to integrate pylint into the build process for my python projects, but I have run into one show-stopper: One of the error types that I find extremely useful--:E1101: *%s %r has no %r member*--constantly reports errors when using common django fields, for example: E1101:125:get_user_tags: Class 'Tag' has no 'objects' member which is caused by this code: 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 How can I tune Pylint to properly take fields such as objects into account? (I've also looked into the Django source, and I have been unable to find the implementation of objects, so I suspect it is not "just" a class field. On the other hand, I'm fairly new to python, so I may very well have overlooked something.) Edit: The only way I've found to tell pylint to not warn about these warnings is by blocking all errors of the type (E1101) which is not an acceptable solution, since that is (in my opinion) an extremely useful error. If there is another way, without augmenting the pylint source, please point me to specifics :) See here for a summary of the problems I've had with pychecker and pyflakes -- they've proven to be far to unstable for general use. (In pychecker's case, the crashes originated in the pychecker code -- not source it was loading/invoking.)
Do not disable or weaken Pylint functionality by adding
Use an actively developed Pylint plugin that understands Django.
This Pylint plugin for Django works quite well:
pip install pylint-django
and when running pylint add the following flag to the command:
Detailed blog post here.
I use the following:
My ~/.pylintrc contains
the last two are specifically for Django.
Note that there is a bug in PyLint 0.21.1 which needs patching to make this work.
Edit: After messing around with this a little more, I decided to hack PyLint just a tiny bit to allow me to expand the above into:
I simply added:
import re for pattern in self.config.generated_members: if re.match(pattern, node.attrname): return
after the fix mentioned in the bug report (i.e., at line 129).
If you use Visual Studio Code do this:
pip install pylint-django
And add to VSC config:
"python.linting.pylintArgs": [ "--load-plugins=pylint_django" ],
django-lint is a nice tool which wraps pylint with django specific settings : http://chris-lamb.co.uk/projects/django-lint/
github project: https://github.com/lamby/django-lint
Because of how pylint works (it examines the source itself, without letting Python actually execute it) it’s very hard for pylint to figure out how metaclasses and complex baseclasses actually affect a class and its instances. The ‘pychecker’ tool is a bit better in this regard, because it does actually let Python execute the code; it imports the modules and examines the resulting objects. However, that approach has other problems, because it does actually let Python execute the code 🙂
You could extend pylint to teach it about the magic Django uses, or to make it understand metaclasses or complex baseclasses better, or to just ignore such cases after detecting one or more features it doesn’t quite understand. I don’t think it would be particularly easy. You can also just tell pylint to not warn about these things, through special comments in the source, command-line options or a .pylintrc file.
I resigned from using pylint/pychecker in favor of using pyflakes with Django code – it just tries to import module and reports any problem it finds, like unused imports or uninitialized local names.
This is not a solution, but you can add
objects = models.Manager() to your Django models without changing any behavior.
I myself only use pyflakes, primarily due to some dumb defaults in pylint and laziness on my part (not wanting to look up how to change the defaults).
Try running pylint with
If that works, add all the other Django classes – possibly using a script, in say, python 😛
The documentation for
List of classes names for which member
attributes should not be checked
(useful for classes with attributes
dynamicaly set). [current: %default]
I should add this is not a particular elegant solution in my view, but it should work.
The solution proposed in this other question it to simply add get_attr to your Tag class. Ugly, but works.
So far I have found no real solution to that but work around:
- In our company we require a pylint
score > 8. This allows coding
practices pylint doesn’t understand
while ensuring that the code isn’t
too “unusual”. So far we havn’t seen
any instance where E1101 kept us
from reaching a score of 8 or
- Our ‘make check’ targets
filter out “for has no ‘objects’
member” messages to remove most of
the distraction caused by pylint not
neovim & vim8 use
w0rp's ale plugin. If you have installed everything correctly including
pylint-django. In your
vimrc add the following line & have fun developing web apps using django.
let g:ale_python_pylint_options = '--load-plugins pylint_django'
- Go to settings in VSC by pressing Ctrl + ,
- Press Ctrl + Shift + p , type Python: Select Linter
- Select mypy from dropdown
- Install mypy if prompted.
- Database Administration Tutorials
- Programming Tutorials & IT News
- Linux & DevOps World
- Entertainment & General News
- Games & eSport