django-compat-lint

Overview

django_compat_lint -- check Django compatibility of your code

Django's API stability policy is nice, but there are still things that change from one version to the next. Figuring out all of those things when it's time to upgrade can be tediious and annoying as you flip back and forth between the release notes and your code, or start grepping for things in your code.

So why not automate it?

django_compat_lint, in the grand tradition of lint tools, is a simple and extensible engine for going through files of code line by line, applying some rules that look for potential problems, and then report those problems. As the name suggests, it is geared toward checking a Django codebase and finding potential issues you'd run into when upgrading to a more recent Django.

How to use it

Put simply:

python django_compat_lint.py [OPTIONS] [FILE1] [FILE2]...

OPTIONS is a set of command-line options. There is one universal command-line option, implemented as -l or --level, specifying the level of messages to report. See below for a definition of the message levels and what they mean.

Beyond that, different options (run -h or --help to see a list) can be specified depending on what code-checking rules you have available.

The output will be a series of messages, on stdout, each specifying its level, the file it came from, the line of code it came from, and the problem or suggestion that was noticed.

Two useful shortcuts are available for specifying files to check:

  • If no files are specified, all .py files in the current working directory are checked.
  • A path to a directory can be specified; all .py files in that directory will be checked.

Recursive checking involving os.walk() is left as an exercise for someone to send a pull request for.

How it works

django_compat_lint uses one or more sets of rules to check your code. A rule is simply a callable; it will be given the line of code to check, the name of the file that line came from, and an object representing the command-line options being used. It should return a 3-tuple of (warnings, errors, info), which are the supported levels of messages. Which levels are actually displayed is controlled by a command-line flag; these levels should be used for:

warning
Something that isn't going to immediately break the code, but may cause problems later. Deprecated APIs, for example, will issue warnings (since the APIs will still be usable for a couple Django versions).
error
Something that is going to immediately break your code if you try to run under a newer Django version. APIs and modules which have been removed are typical examples of this.
info
Something that doesn't and won't break your code, but is an outdated idiom or something which can be accomplished in a better way using more recent Django.

Registering rules

Rules live in the rules/ subdirectory, and a set of rules is simply a Python module which exports a variable named rules. This should be a list of dictionaries, one per rule. Each dictionary should have the following keys. The first five correspond exactly to the same-named arguments to parser.add_option() in Python's optparse module (which implements the parsing of command-line flags):

long_option
The (long) command-line flag for this rule. To avoid conflicts, rules cannot use short flags.
action
What action to take with the flag.
dest
Similarly, where to store the value of the command-line flag.
help
A brief description of the rule and what it checks, for help output.

The remaining keys are:

callback
The callback which implements the rule.
enabled
A callable which is passed the command-line options, and returns a boolean indicating, from those options, whether this rule is enabled.

A simple example

Suppose that a new version of Django introduces a model field type called SuperAwesomeTextField, which is just like TextField but better. So people who are upgrading may want to change from TextField to SuperAwesomeTextField. A simple rule for this might live in a file named superawesomefield.py. First, the callback for the rule:

def check_superawesomefield(line, filename, options):
    info = []
    if filename == 'models.py' and 'TextField' in line:
        info.append('Consider using SuperAwesomeField instead of TextField.')
    return []. [], info

This checks for the filename 'models.py' since a model field change is probably only applicable to models files. And it checks for use of the model TextField, by just seeing if that appears in the line of code. More complex things might use regular expressions or other tricks to check a line.

Since it's only ever going to give an "info"-level message, the "warnings" and "errors" lists are just always empty.

Then, at the bottom of the file, the rule gets registered:

rules = [
    {'option': '-a',
     'long_option': '--superawesomefield',
     'action': 'store_true',
     'dest': 'superawesomefield',
     'help': 'Check for places where SuperAwesomeField could be used.',
     'callback': check_superawesomefield,
     'enabled': lambda options: options.superawesomefield,}
]

And that's it -- the engine will pick up that rule, and enable it whenever the appropriate command-line flag is used.

You might also like...
Dockerizing Django with Postgres, Gunicorn, Nginx and Certbot. A fully Django starter project.

Dockerizing Django with Postgres, Gunicorn, Nginx and Certbot 🚀 Features A Django stater project with fully basic requirements for a production-ready

pytest-django allows you to test your Django project/applications with the pytest testing tool.

pytest-django allows you to test your Django project/applications with the pytest testing tool.

APIs for a Chat app. Written with Django Rest framework and Django channels.
APIs for a Chat app. Written with Django Rest framework and Django channels.

ChatAPI APIs for a Chat app. Written with Django Rest framework and Django channels. The documentation for the http end points can be found here This

django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project. Inspired in the dashboard framework Dashing
django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project. Inspired in the dashboard framework Dashing

django-dashing django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project.

Django-MySQL extends Django's built-in MySQL and MariaDB support their specific features not available on other databases.
Django-MySQL extends Django's built-in MySQL and MariaDB support their specific features not available on other databases.

Django-MySQL The dolphin-pony - proof that cute + cute = double cute. Django-MySQL extends Django's built-in MySQL and MariaDB support their specific

Django-Audiofield is a simple app that allows Audio files upload, management and conversion to different audio format (mp3, wav & ogg), which also makes it easy to play audio files into your Django application.
Django-Audiofield is a simple app that allows Audio files upload, management and conversion to different audio format (mp3, wav & ogg), which also makes it easy to play audio files into your Django application.

Django-Audiofield Description: Django Audio Management Tools Maintainer: Areski Contributors: list of contributors Django-Audiofield is a simple app t

django Filer is a file management application for django that makes handling of files and images a breeze.
django Filer is a file management application for django that makes handling of files and images a breeze.

django Filer is a file management application for django that makes handling of files and images a breeze.

Twitter Bootstrap for Django Form - A simple Django template tag to work with Bootstrap

Twitter Bootstrap for Django Form - A simple Django template tag to work with Bootstrap

Blog focused on skills enhancement and knowledge sharing. Tech Stack's: Vue.js, Django and Django-Ninja

Blog focused on skills enhancement and knowledge sharing. Tech Stack's: Vue.js, Django and Django-Ninja

Comments
  • setup.py, package, .gitignore and code fixes

    setup.py, package, .gitignore and code fixes

    • add setup.py so this is pip installable
    • move the script to bin/
    • create djangocompatlint module
    • move rules registration code from the script to djangocompatlint module
    • add --verbose flag to make it easier to figure out if it's checking the files you think it's checking
    • did some minor code cleanup

    Fixes #3

    Hope this helps!

    opened by willkg 0
Owner
James Bennett
James Bennett
Meta package to combine turbo-django and stimulus-django

Hotwire + Django This repository aims to help you integrate Hotwire with Django ?? Inspiration might be taken from @hotwired/hotwire-rails. We are sti

Hotwire for Django 31 Aug 9, 2022
django-reversion is an extension to the Django web framework that provides version control for model instances.

django-reversion django-reversion is an extension to the Django web framework that provides version control for model instances. Requirements Python 3

Dave Hall 2.8k Jan 2, 2023
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.

Django-environ django-environ allows you to use Twelve-factor methodology to configure your Django application with environment variables. import envi

Daniele Faraglia 2.7k Jan 7, 2023
Rosetta is a Django application that eases the translation process of your Django projects

Rosetta Rosetta is a Django application that facilitates the translation process of your Django projects. Because it doesn't export any models, Rosett

Marco Bonetti 909 Dec 26, 2022
Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.

Cookiecutter Django Powered by Cookiecutter, Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly. Documentati

Daniel Feldroy 10k Dec 31, 2022
Django project starter on steroids: quickly create a Django app AND generate source code for data models + REST/GraphQL APIs (the generated code is auto-linted and has 100% test coverage).

Create Django App ?? We're a Django project starter on steroids! One-line command to create a Django app with all the dependencies auto-installed AND

imagine.ai 68 Oct 19, 2022
django-quill-editor makes Quill.js easy to use on Django Forms and admin sites

django-quill-editor django-quill-editor makes Quill.js easy to use on Django Forms and admin sites No configuration required for static files! The ent

lhy 139 Dec 5, 2022
A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, celery and redis.

Django Channels Websocket Chatbot A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, c

Yunbo Shi 8 Oct 28, 2022
A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.

Django Sage Painless The django-sage-painless is a valuable package based on Django Web Framework & Django Rest Framework for high-level and rapid web

sageteam 51 Sep 15, 2022
A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a unique id.

Django-URL-Shortener A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a uni

Rohini Rao 3 Aug 8, 2021