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
A Django app for working with BTCPayServer

btcpay-django A Django app for working with BTCPayServer Installation pip install btcpay-django Developers Release To cut a release, run bumpversion,

Crawford 3 Nov 20, 2022
Auto-detecting the n+1 queries problem in Python

nplusone nplusone is a library for detecting the n+1 queries problem in Python ORMs, including SQLAlchemy, Peewee, and the Django ORM. The Problem Man

Joshua Carp 837 Dec 29, 2022
The magical reactive component framework for Django ✨

Unicorn The magical full-stack framework for Django ✨ Unicorn is a reactive component framework that progressively enhances a normal Django view, make

Adam Hill 1.4k Jan 05, 2023
This is a simple Todo web application built Django (back-end) and React JS (front-end)

Django REST Todo app This is a simple Todo web application built with Django (back-end) and React JS (front-end). The project enables you to systemati

Maxim Mukhin 5 May 06, 2022
Django-gmailapi-json-backend - Email backend for Django which sends email via the Gmail API through a JSON credential

django-gmailapi-json-backend Email backend for Django which sends email via the

Innove 1 Sep 09, 2022
A Django Demo Project of Students Management System

Django_StudentMS A Django Demo Project of Students Management System. From NWPU Seddon for DB Class Pre. Seddon simplify the code in 2021/10/17. Hope

2 Dec 08, 2021
A BitField extension for Django Models

django-bitfield Provides a BitField like class (using a BigIntegerField) for your Django models. (If you're upgrading from a version before 1.2 the AP

DISQUS 361 Dec 22, 2022
django social media app with real time features

django-social-media django social media app with these features: signup, login and old registered users are saved by cookies posts, comments, replies,

8 Apr 30, 2022
Awesome Django Markdown Editor, supported for Bootstrap & Semantic-UI

martor Martor is a Markdown Editor plugin for Django, supported for Bootstrap & Semantic-UI. Features Live Preview Integrated with Ace Editor Supporte

659 Jan 04, 2023
Add infinite scroll to any django app.

django-infinite-scroll Add infinite scroll to any django app. Features - Allows to add infinite scroll to any page.

Gustavo Teixeira 1 Dec 26, 2021
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
Django admin CKEditor integration.

Django CKEditor NOTICE: django-ckeditor 5 has backward incompatible code moves against 4.5.1. File upload support has been moved to ckeditor_uploader.

2.2k Jan 02, 2023
Django server-side adapter for Inertia.js

django-inertia Django server-side new adapter for Inertia.js. Getting Started Install the package pip install django-inertia Configure your project A

Samuel Girardin 14 Sep 16, 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 API creation with signed requests utilizing forms for validation.

django-formapi Create JSON API:s with HMAC authentication and Django form-validation. Version compatibility See Travis-CI page for actual test results

5 Monkeys 34 Apr 04, 2022
Learn Python and the Django Framework by building a e-commerce website

The Django-Ecommerce is an open-source project initiative and tutorial series built with Python and the Django Framework.

Very Academy 275 Jan 08, 2023
Simple XML-RPC and JSON-RPC server for modern Django

django-modern-rpc Build an XML-RPC and/or JSON-RPC server as part of your Django project. Major Django and Python versions are supported Main features

Antoine Lorence 82 Dec 04, 2022
a little task queue for python

a lightweight alternative. huey is: a task queue (2019-04-01: version 2.0 released) written in python (2.7+, 3.4+) clean and simple API redis, sqlite,

Charles Leifer 4.3k Dec 29, 2022
Modular search for Django

Haystack author: Daniel Lindsley date: 2013/07/28 Haystack provides modular search for Django. It features a unified, familiar API that allows you to

Daniel Lindsley 4 Dec 23, 2022
A blog app powered by python-django

Django_BlogApp This is a blog app powered by python-django Features Add and delete blog post View someone else blog Can add comment to that blog And o

Manish Jalui 1 Sep 12, 2022