add mypy setup to tox.ini

This commit is contained in:
Maxim Kurnikov 2019-10-11 20:39:39 +03:00
parent 0fd72f17ee
commit 371caaf538
12 changed files with 40 additions and 22 deletions

2
mypy.ini Normal file
View File

@ -0,0 +1,2 @@
[mypy]
ignore_missing_imports = True

View File

@ -0,0 +1 @@
mypy==0.730

View File

@ -117,14 +117,14 @@ except ImportError:
try:
import yaml
except ImportError:
yaml = None
yaml = None # type: ignore
# requests is optional
try:
import requests
except ImportError:
requests = None
requests = None # type: ignore
# PATCH method is not implemented by Django
@ -156,7 +156,7 @@ try:
md_filter_add_syntax_highlight(md)
return md.convert(text)
except ImportError:
apply_markdown = None
apply_markdown = None # type: ignore
markdown = None

View File

@ -7,6 +7,7 @@ import re
import uuid
from collections import OrderedDict
from collections.abc import Mapping
from typing import Callable, List, Any, Optional, Dict
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
@ -302,9 +303,9 @@ class Field:
'required': _('This field is required.'),
'null': _('This field may not be null.')
}
default_validators = []
default_empty_html = empty
initial = None
default_validators = [] # type: List[Callable[[Any], None]]
default_empty_html = empty # type: Optional[Any]
initial = None # type: Optional[Any]
def __init__(self, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None,
@ -1456,7 +1457,7 @@ class MultipleChoiceField(ChoiceField):
'not_a_list': _('Expected a list of items but got type "{input_type}".'),
'empty': _('This selection may not be empty.')
}
default_empty_html = []
default_empty_html = [] # type: List[Any]
def __init__(self, *args, **kwargs):
self.allow_empty = kwargs.pop('allow_empty', True)
@ -1597,7 +1598,7 @@ class _UnvalidatedField(Field):
class ListField(Field):
child = _UnvalidatedField()
initial = []
initial = [] # type: List[Any]
default_error_messages = {
'not_a_list': _('Expected a list of items but got type "{input_type}".'),
'empty': _('This list may not be empty.'),
@ -1675,8 +1676,8 @@ class ListField(Field):
class DictField(Field):
child = _UnvalidatedField()
initial = {}
child = _UnvalidatedField() # type: Field
initial = {} # type: Dict[str, Any]
default_error_messages = {
'not_a_dict': _('Expected a dictionary of items but got type "{input_type}".'),
'empty': _('This dictionary may not be empty.'),

View File

@ -5,6 +5,7 @@ They give us a generic way of being able to handle various media types
on the request, such as form content or json encoded data.
"""
import codecs
from typing import Optional
from urllib import parse
from django.conf import settings
@ -33,7 +34,7 @@ class BaseParser:
All parsers should extend `BaseParser`, specifying a `media_type`
attribute, and overriding the `.parse()` method.
"""
media_type = None
media_type = None # type: Optional[str]
def parse(self, stream, media_type=None, parser_context=None):
"""

View File

@ -1,5 +1,6 @@
import sys
from collections import OrderedDict
from typing import List, Any
from urllib import parse
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
@ -472,8 +473,8 @@ class ManyRelatedField(Field):
You shouldn't generally need to be using this class directly yourself,
and should instead simply set 'many=True' on the relationship.
"""
initial = []
default_empty_html = []
initial = [] # type: List[Any]
default_empty_html = [] # type: List[Any]
default_error_messages = {
'not_a_list': _('Expected a list of items but got type "{input_type}".'),
'empty': _('This list may not be empty.')

View File

@ -8,6 +8,7 @@ REST framework also provides an HTML renderer that renders the browsable API.
"""
import base64
from collections import OrderedDict
from typing import Optional
from urllib import parse
from django import forms
@ -42,9 +43,9 @@ class BaseRenderer:
All renderers should extend this class, setting the `media_type`
and `format` attributes, and override the `.render()` method.
"""
media_type = None
format = None
charset = 'utf-8'
media_type = None # type: Optional[str]
format = None # type: Optional[str]
charset = 'utf-8' # type: Optional[str]
render_style = 'text'
def render(self, data, accepted_media_type=None, renderer_context=None):

View File

@ -15,6 +15,7 @@ import inspect
import traceback
from collections import OrderedDict
from collections.abc import Mapping
from typing import Type
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
from django.core.exceptions import ValidationError as DjangoValidationError
@ -891,7 +892,7 @@ class ModelSerializer(Serializer):
}
if ModelDurationField is not None:
serializer_field_mapping[ModelDurationField] = DurationField
serializer_related_field = PrimaryKeyRelatedField
serializer_related_field = PrimaryKeyRelatedField # type: Type[RelatedField]
serializer_related_to_field = SlugRelatedField
serializer_url_field = HyperlinkedIdentityField
serializer_choice_field = ChoiceField

View File

@ -115,7 +115,7 @@ if requests is not None:
return super().request(method, url, *args, **kwargs)
else:
def RequestsClient(*args, **kwargs):
def RequestsClient(*args, **kwargs): # type: ignore
raise ImproperlyConfigured('requests must be installed in order to use RequestsClient.')
@ -131,7 +131,7 @@ if coreapi is not None:
return self._session
else:
def CoreAPIClient(*args, **kwargs):
def CoreAPIClient(*args, **kwargs): # type: ignore
raise ImproperlyConfigured('coreapi must be installed in order to use CoreAPIClient.')

View File

@ -2,6 +2,7 @@
Provides various throttling policies.
"""
import time
from typing import Optional
from django.core.cache import cache as default_cache
from django.core.exceptions import ImproperlyConfigured
@ -62,7 +63,7 @@ class SimpleRateThrottle(BaseThrottle):
cache = default_cache
timer = time.time
cache_format = 'throttle_%(scope)s_%(ident)s'
scope = None
scope = None # type: Optional[str]
THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES
def __init__(self):

View File

@ -1,6 +1,8 @@
"""
Provides an APIView class that is the base of all views in REST framework.
"""
from typing import Optional
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.db import connection, models, transaction
@ -15,6 +17,7 @@ from rest_framework import exceptions, status
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.schemas import DefaultSchema
from rest_framework.schemas.inspectors import ViewInspector
from rest_framework.settings import api_settings
from rest_framework.utils import formatting
@ -116,7 +119,7 @@ class APIView(View):
# Allow dependency injection of other settings to make testing easier.
settings = api_settings
schema = DefaultSchema()
schema = DefaultSchema() # type: Optional[ViewInspector]
@classmethod
def as_view(cls, **initkwargs):

View File

@ -5,7 +5,7 @@ envlist =
{py35,py36,py37}-django21
{py35,py36,py37}-django22
{py36,py37}-djangomaster,
base,dist,lint,docs,
base,dist,lint,docs,mypy,
[travis:env]
DJANGO =
@ -57,3 +57,9 @@ commands = mkdocs build
deps =
-rrequirements/requirements-testing.txt
-rrequirements/requirements-documentation.txt
[testenv:mypy]
basepython = python3.7
commands = mypy ./rest_framework
deps =
-rrequirements/requirements-mypy.txt