PEP-484 type hints bindings for the Django web framework

Related tags

Djangomypy-django
Overview

mypy-django

Type stubs to use the mypy static type-checker with your Django projects

This project includes the PEP-484 compatible "type stubs" for Django APIs. Using a compliant checking tool (typically, mypy), it allows you to document and verify more of your code. Your annotated code will look like:

def vote(request: HttpRequest, question_id: str) -> HttpResponse:
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {'question': question})
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

If you use incorrect annotations, like in the following example

class ResultsView(generic.DetailView):
    model = Question

    def get_template_names(self) -> str:
        if some_condition():
            return "template_a.html"
        else:
            return "template_b.html"

Running mypy will report the problem:

$ mypy --strict-optional -p polls
...
polls/views.py: note: In class "ResultsView":
polls/views.py:41: error: Return type of "get_template_names" incompatible with supertype "SingleObjectTemplateResponseMixin"
polls/views.py:41: error: Return type of "get_template_names" incompatible with supertype "TemplateResponseMixin"

Mypy Pony

Installation and usage

You'll need to install mypy (other PEP-484 checkers might work, but I haven't tested them). pip install mypy should do the trick. There are no other requirements.

This is not a python package (no actual executable code), so this is not installed with pip or available in PyPI. You can just git clone the latest version from https://github.com/machinalis/mypy-django.git or download and unzip https://github.com/machinalis/mypy-django/archive/master.zip

Once you have your copy, set your MYPYPATH environment variable to point to the files. For example (in Linux/bash):

$ export MYPYPATH=/home/dmoisset/mypy-django/
$ ls $MYPYPATH
django
$ ls $MYPYPATH/django
conf  core  http  __init__.pyi  urls  utils  views

If you don't see the above (the second line might have a few more items in your computer), check that the path exists, and that it points to the correct level in the directory tree.

Motivation

We are building this as a tool at Machinalis to improve the quality of the Django projects we build for our clients. Feel free to contact me if you want to hear more about how we use it or how it can be applied. I can be found at [email protected] or at @dmoisset via Twitter.

In a more general perspective, it makes sense to use static typing for Django given the following:

  1. Much of the user application code for Django projects consists in operating on objects defined by the framework. Unlike other APIs where you mostly pass around standard python data structures, this means that you don't get much benefit from PEP-484 static typing because everything gets annotated as Any (i.e. unchecked)
  2. A large part of the framework follows a very structured, almost declarative approach where you just fill-out a structure (for example, defining models, admin options, generic views, url routers, forms, settings)
  3. Django already has a policy of checking types before starting serving. Many of the system checks performed by manage.py check are actually type checks. So this fits very well with the framework philosophy

Full example

I reimplemented most of the standard Django tutorial with annotations, so you can see how it looks. The code (and a README with some details of problems and solutions found when annotating) are available at https://github.com/machinalis/mypy-django-example

Known issues

  • The current version is mainly focused on supporting Django 1.10 under python 3.x. Given that the APIs I cover are the core components and haven't changed much, you probably can work with older versions of Django and it might work. Python 2.x will not be supported (The code uses str to describe arguments/return values that can be text strings, i.e. unicode).
  • Many django modules that you might import are not supported yet. So you might need to silence with # type: ignore some messages like:
polls/views.py:1: error: No library stub file for module 'django.db.models.query'
  • It's recommended that you run mypy with the --strict-optional option; many of the stubs assume that you do, and you might get some warnings inside the stub files if you don't use it.

Roadmap

v0.1 - Initial release - October 2016

  • Request and Response objects
    • Including supporting classes like QueryDict and file objects
  • Generic views
  • URL resolver
  • Other miscellaneous components required by the above (timezones, cookies, ...)

v0.2 - In development

  • Admin support
  • django.shortcuts
  • Paginators

Probably never

  • Querysets may have some partial support, but complex arguments (like the ones for filter and get queries) or Q and F objects are beyond the expressive possibilities of mypy as it is now.
  • The template language is a separate language and can not be covered by mypy, so any type errors inside the template can not be detected by it.

License

BSD. See LICENSE file for details

Owner
Machinalis
Machinalis
Simple tagging for django

django-taggit This is a Jazzband project. By contributing you agree to abide by the Contributor Code of Conduct and follow the guidelines. django-tagg

Jazzband 3k Jan 02, 2023
Plug and play continuous integration with django and jenkins

django-jenkins Plug and play continuous integration with Django and Jenkins Installation From PyPI: $ pip install django-jenkins Or by downloading th

Mikhail Podgurskiy 941 Oct 22, 2022
Comprehensive Markdown plugin built for Django

Django MarkdownX Django MarkdownX is a comprehensive Markdown plugin built for Django, the renowned high-level Python web framework, with flexibility,

neutronX 738 Dec 21, 2022
A clone of https://virgool.io written in django

Virgool clone A clone of virgool blog written in django Installation first rename the .env.sample to .env and fill it. with docker docker-compose up -

Danial Selmipoor 7 Dec 23, 2022
Strict separation of config from code.

Python Decouple: Strict separation of settings from code Decouple helps you to organize your settings so that you can change parameters without having

Henrique Bastos 2.3k Jan 04, 2023
wagtail_tenants is a Django/Wagtail app to provide multitenancy to your wagtail project.

wagtail-tenants wagtail_tenants is a Django/Wagtail app to provide multitenancy to your wagtail project. You are able to run a main Wagtail Site and f

<bbr> 11 Nov 20, 2022
Service request portal on top of Ansible Tower

Squest - A service request portal based on Ansible Tower Squest is a Web portal that allow to expose Tower based automation as a service. If you want

Hewlett Packard Enterprise 183 Jan 04, 2023
Forgot password functionality build in Python / Django Rest Framework

Password Recover Recover password functionality with e-mail sender usign Django Email Backend How to start project. Create a folder in your machine Cr

alexandre Lopes 1 Nov 03, 2021
Django datatables with htmx.

Django datatables with htmx.

Regis Santos 7 Oct 23, 2022
Py-instant-search-redis - Source code example for how to build an instant search with redis in python

py-instant-search-redis Source code example for how to build an instant search (

Giap Le 4 Feb 17, 2022
Add Chart.js visualizations to your Django admin using a mixin class

django-admincharts Add Chart.js visualizations to your Django admin using a mixin class. Example from django.contrib import admin from .models import

Dropseed 22 Nov 22, 2022
A django model and form field for normalised phone numbers using python-phonenumbers

django-phonenumber-field A Django library which interfaces with python-phonenumbers to validate, pretty print and convert phone numbers. python-phonen

Stefan Foulis 1.3k Dec 31, 2022
Full control of form rendering in the templates.

django-floppyforms Full control of form rendering in the templates. Authors: Gregor Müllegger and many many contributors Original creator: Bruno Renié

Jazzband 811 Dec 01, 2022
A simple page with paypal payment and confiramtion in django

django-paypal a simple page with paypal payment and confiramtion in django Youtube Video : Paypal Smart Button : https://developer.paypal.com/demo/che

Mahmoud Ahmed 5 Feb 19, 2022
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

8 Jun 27, 2022
An orgizational tool to keep track of tasks/projects and the time spent on them.

Django-Task-Manager Task Tracker using Python Django About The Project This project is an orgizational tool to keep track of tasks/projects and the ti

Nick Newton 1 Dec 21, 2021
User Authentication In Django/Ajax/Jquery

User Authentication In Django/Ajax/Jquery Demo: Authentication System Using Django/Ajax/Jquery Demo: Authentication System Using Django Overview The D

Suman Raj Khanal 10 Mar 26, 2022
Let AngularJS play well with Django

django-angular Let Django play well with AngularJS What does it offer? Add AngularJS directives to Django Forms. This allows to handle client side for

Jacob Rief 1.2k Dec 27, 2022
Full-text multi-table search application for Django. Easy to install and use, with good performance.

django-watson django-watson is a fast multi-model full-text search plugin for Django. It is easy to install and use, and provides high quality search

Dave Hall 1.1k Dec 22, 2022
Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes

Bleach Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes. Bleach can also linkify text safely, appl

Mozilla 2.5k Dec 29, 2022