• Stars
    star
    223
  • Rank 178,458 (Top 4 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created over 8 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

PEP-484 type hints bindings for the Django web framework

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

More Repositories

1

quepy

A python framework to transform natural language questions to queries in a database query language.
Python
1,254
star
2

iepy

Information Extraction in Python
Python
905
star
3

featureforge

A set of tools for creating and testing machine learning features, with a scikit-learn compatible API
Python
381
star
4

telegraphy

Telegraphy provides real time events for WSGI Python applications
JavaScript
202
star
5

refo

Regular expressions for objects
Python
143
star
6

yalign

A sentence aligner for comparable corpora
Python
127
star
7

satimg

Satellite data processing experiments
Jupyter Notebook
117
star
8

mypy-data

mypy typesheds for the Python data stack
Python
86
star
9

bidderd

RTBKIT Agent using Go and the HTTPInterface
Go
45
star
10

django-i18n-helper

Python
35
star
11

django-fasttest

A variant on django.test.TestCase optimized for postgres
Python
21
star
12

slides

Public talks by Machinalis
TeX
18
star
13

django-template-previewer

A Django app to allow developers preview templates
Python
17
star
14

mypy-django-example

A usage example for mypy-django
Python
15
star
15

django-test-autocomplete

Python
12
star
16

eff

Time tracking and report generation
Python
9
star
17

ninja-django-plugin

Django plugin for Ninja-IDE
Python
4
star
18

inventor

Inventor a very simple django based inventory system.
HTML
3
star
19

protobuf-python3

Google protobuf port to python3
C++
2
star
20

jquery_simple_progressbar

2
star
21

django-migration-tools

Scripts for helping with routine tasks while migration from 0.96 django versions to 1.x
Python
2
star
22

code_time_tracker

Python
1
star
23

ninja_ipython_console

An IPython console plugin for Ninja
Python
1
star
24

machinalis-movie-reviews

Python
1
star
25

alfajor

A site to collect shopping orders for packages of items, designed for an alfajor seller
Python
1
star