mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-06 12:14:28 +08:00
add tests for the django test suite
This commit is contained in:
26
.travis.yml
26
.travis.yml
@@ -7,21 +7,21 @@ sudo: required
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- name: "Run plugin test suite with python 3.7"
|
||||
python: 3.7
|
||||
script: |
|
||||
set -e
|
||||
pytest
|
||||
- name: "Typecheck Django test suite"
|
||||
python: 3.7
|
||||
script: |
|
||||
xonsh ./scripts/typecheck_django_tests.xsh
|
||||
|
||||
- name: "Lint with black"
|
||||
python: 3.7
|
||||
script: |
|
||||
black --check --line-length=120 django-stubs/
|
||||
- name: "Run plugin test suite with python 3.7"
|
||||
python: 3.7
|
||||
script: |
|
||||
set -e
|
||||
pytest
|
||||
|
||||
# - name: "Typecheck Django test suite"
|
||||
# python: 3.7
|
||||
# script: |
|
||||
# xonsh ./scripts/typecheck_django_tests.xsh
|
||||
- name: "Lint with black"
|
||||
python: 3.7
|
||||
script: |
|
||||
black --check --line-length=120 django-stubs/
|
||||
|
||||
before_install: |
|
||||
# Upgrade pip, setuptools, and wheel
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Any
|
||||
from django.utils.version import get_version as get_version
|
||||
|
||||
VERSION: Any
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Stubs for django.conf.urls (Python 3.5)
|
||||
from typing import Any, Callable, Dict, List, Optional, overload, Tuple, Union
|
||||
|
||||
from django.http.response import HttpResponse
|
||||
from django.http.response import HttpResponse, HttpResponseBase
|
||||
|
||||
from django.urls import URLResolver, URLPattern
|
||||
|
||||
@@ -14,7 +14,9 @@ IncludedURLConf = Tuple[List[URLResolver], Optional[str], Optional[str]]
|
||||
|
||||
def include(arg: Any, namespace: str = ..., app_name: str = ...) -> IncludedURLConf: ...
|
||||
@overload
|
||||
def url(regex: str, view: Callable[..., HttpResponse], kwargs: Dict[str, Any] = ..., name: str = ...) -> URLPattern: ...
|
||||
def url(
|
||||
regex: str, view: Callable[..., HttpResponseBase], kwargs: Dict[str, Any] = ..., name: str = ...
|
||||
) -> URLPattern: ...
|
||||
@overload
|
||||
def url(regex: str, view: IncludedURLConf, kwargs: Dict[str, Any] = ..., name: str = ...) -> URLResolver: ...
|
||||
@overload
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from .messages import Warning as Warning, Info as Info, Debug as Debug, Error as Error, Critical as Critical
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Any, Optional, Union
|
||||
from typing import Any, Optional
|
||||
|
||||
DEBUG: int
|
||||
INFO: int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Any, List, Optional
|
||||
from typing import Any, List
|
||||
|
||||
from django.core.checks.messages import Warning
|
||||
|
||||
|
||||
@@ -31,10 +31,15 @@ class FileSystemStorage(Storage):
|
||||
file_permissions_mode: Optional[int] = ...,
|
||||
directory_permissions_mode: Optional[int] = ...,
|
||||
) -> None: ...
|
||||
@property
|
||||
def base_location(self) -> str: ...
|
||||
@property
|
||||
def location(self) -> str: ...
|
||||
@property
|
||||
def base_url(self) -> str: ...
|
||||
@property
|
||||
def file_permissions_mode(self) -> Optional[int]: ...
|
||||
@property
|
||||
def directory_permissions_mode(self) -> Optional[int]: ...
|
||||
|
||||
class DefaultStorage(LazyObject): ...
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from django.core.management.base import BaseCommand as BaseCommand
|
||||
from django.core.management.base import BaseCommand as BaseCommand, CommandError as CommandError
|
||||
|
||||
def find_commands(management_dir: str) -> List[str]: ...
|
||||
def load_command_class(app_name: str, name: str) -> BaseCommand: ...
|
||||
|
||||
@@ -60,7 +60,7 @@ class BaseCommand:
|
||||
def add_arguments(self, parser: CommandParser) -> None: ...
|
||||
def print_help(self, prog_name: str, subcommand: str) -> None: ...
|
||||
def run_from_argv(self, argv: List[str]) -> None: ...
|
||||
def execute(self, *args: Any, **options: Any) -> Optional[Union[Tuple, str]]: ...
|
||||
def execute(self, *args: Any, **options: Any) -> Any: ...
|
||||
def check(
|
||||
self,
|
||||
app_configs: Optional[List[AppConfig]] = ...,
|
||||
|
||||
@@ -11,6 +11,7 @@ from .utils import (
|
||||
NotSupportedError as NotSupportedError,
|
||||
InternalError as InternalError,
|
||||
InterfaceError as InterfaceError,
|
||||
ConnectionHandler as ConnectionHandler,
|
||||
)
|
||||
|
||||
from . import migrations
|
||||
|
||||
@@ -1,9 +1,35 @@
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Optional, Tuple, Iterable, Callable, Dict, Union
|
||||
|
||||
from django.db.models.query_utils import RegisterLookupMixin
|
||||
|
||||
_Choice = Tuple[Any, str]
|
||||
_ChoiceNamedGroup = Tuple[str, Iterable[_Choice]]
|
||||
_FieldChoices = Iterable[Union[_Choice, _ChoiceNamedGroup]]
|
||||
|
||||
_ValidatorCallable = Callable[[...], None]
|
||||
_ErrorMessagesToOverride = Dict[str, Any]
|
||||
|
||||
class Field(RegisterLookupMixin):
|
||||
def __init__(self, **kwargs: Any): ...
|
||||
def __init__(
|
||||
self,
|
||||
verbose_name: Optional[str] = ...,
|
||||
name: Optional[str] = ...,
|
||||
primary_key: bool = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
def __get__(self, instance, owner) -> Any: ...
|
||||
|
||||
class IntegerField(Field):
|
||||
@@ -19,24 +45,83 @@ class BigIntegerField(IntegerField): ...
|
||||
class FloatField(Field): ...
|
||||
|
||||
class DecimalField(IntegerField):
|
||||
def __init__(self, *, max_digits: Optional[int] = ..., decimal_places: Optional[int] = ..., **kwargs): ...
|
||||
def __init__(
|
||||
self,
|
||||
verbose_name: Optional[str] = ...,
|
||||
name: Optional[str] = ...,
|
||||
max_digits: Optional[int] = ...,
|
||||
decimal_places: Optional[int] = ...,
|
||||
primary_key: bool = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
|
||||
class AutoField(Field):
|
||||
def __get__(self, instance, owner) -> int: ...
|
||||
|
||||
class CharField(Field):
|
||||
def __init__(self, max_length: int = ..., **kwargs: Any): ...
|
||||
def __init__(
|
||||
self,
|
||||
verbose_name: Optional[str] = ...,
|
||||
name: Optional[str] = ...,
|
||||
primary_key: bool = ...,
|
||||
max_length: Optional[int] = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
def __set__(self, instance, value: str) -> None: ...
|
||||
def __get__(self, instance, owner) -> str: ...
|
||||
|
||||
class SlugField(CharField):
|
||||
def __init__(self, max_length: int = ..., **kwargs: Any): ...
|
||||
def __init__(
|
||||
self,
|
||||
verbose_name: Optional[str] = ...,
|
||||
name: Optional[str] = ...,
|
||||
primary_key: bool = ...,
|
||||
max_length: Optional[int] = ...,
|
||||
allow_unicode: bool = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
|
||||
class EmailField(CharField):
|
||||
def __init__(self, max_length: int = ..., **kwargs: Any): ...
|
||||
|
||||
class URLField(CharField):
|
||||
def __init__(self, max_length: int = ..., **kwargs: Any): ...
|
||||
class EmailField(CharField): ...
|
||||
class URLField(CharField): ...
|
||||
|
||||
class TextField(Field):
|
||||
def __set__(self, instance, value: str) -> None: ...
|
||||
@@ -63,7 +148,21 @@ class GenericIPAddressField(Field):
|
||||
name: Optional[Any] = ...,
|
||||
protocol: str = ...,
|
||||
unpack_ipv4: bool = ...,
|
||||
**kwargs: Any
|
||||
primary_key: bool = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
) -> None: ...
|
||||
|
||||
class DateTimeCheckMixin: ...
|
||||
@@ -75,7 +174,21 @@ class DateField(DateTimeCheckMixin, Field):
|
||||
name: Optional[str] = ...,
|
||||
auto_now: bool = ...,
|
||||
auto_now_add: bool = ...,
|
||||
**kwargs
|
||||
primary_key: bool = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
|
||||
class TimeField(DateTimeCheckMixin, Field): ...
|
||||
@@ -92,10 +205,22 @@ class FilePathField(Field):
|
||||
recursive: bool = ...,
|
||||
allow_files: bool = ...,
|
||||
allow_folders: bool = ...,
|
||||
**kwargs
|
||||
primary_key: bool = ...,
|
||||
unique: bool = ...,
|
||||
blank: bool = ...,
|
||||
null: bool = ...,
|
||||
db_index: bool = ...,
|
||||
default: Any = ...,
|
||||
editable: bool = ...,
|
||||
auto_created: bool = ...,
|
||||
serialize: bool = ...,
|
||||
choices: Optional[_FieldChoices] = ...,
|
||||
help_text: str = ...,
|
||||
db_column: Optional[str] = ...,
|
||||
db_tablespace: Optional[str] = ...,
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
|
||||
class BinaryField(Field):
|
||||
def __init__(self, editable: bool = ..., **kwargs: Any): ...
|
||||
|
||||
class BinaryField(Field): ...
|
||||
class DurationField(Field): ...
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from django.core.exceptions import ValidationError as ValidationError
|
||||
|
||||
from .forms import Form as Form, BaseForm as BaseForm
|
||||
|
||||
from .models import ModelForm as ModelForm
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Any, Dict, Iterator, Optional, List
|
||||
|
||||
from django.template.base import Template
|
||||
from django.template.base import Template as Template
|
||||
from django.template.exceptions import TemplateDoesNotExist
|
||||
|
||||
from django.template.engine import Engine
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Callable, Dict, List, Optional, Tuple, Any
|
||||
|
||||
from django.template.base import Template
|
||||
from django.template.base import Template as Template
|
||||
from django.template.exceptions import TemplateSyntaxError
|
||||
|
||||
from .base import BaseEngine
|
||||
|
||||
@@ -51,5 +51,5 @@ class Engine:
|
||||
) -> Tuple[Template, Origin]: ...
|
||||
def from_string(self, template_code: str) -> Template: ...
|
||||
def get_template(self, template_name: str) -> Template: ...
|
||||
def render_to_string(self, template_name: str, context: Any = ...) -> SafeText: ...
|
||||
def render_to_string(self, template_name: str, context: Optional[Dict[str, Any]] = ...) -> SafeText: ...
|
||||
def select_template(self, template_name_list: List[str]) -> Template: ...
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
from typing import Dict, List, Optional, Union
|
||||
from typing import Dict, List, Optional, Union, Any
|
||||
|
||||
from django.core.handlers.wsgi import WSGIRequest
|
||||
from django.template.backends.django import Template as DjangoTemplate
|
||||
from django.template.backends.dummy import Template as DummyTemplate
|
||||
from django.template.backends.jinja2 import Template as Jinja2Template
|
||||
|
||||
def get_template(
|
||||
template_name: str, using: Optional[str] = ...
|
||||
) -> Union[DjangoTemplate, DummyTemplate, Jinja2Template]: ...
|
||||
def select_template(
|
||||
template_name_list: Union[List[str], str], using: Optional[str] = ...
|
||||
) -> Union[DjangoTemplate, DummyTemplate, Jinja2Template]: ...
|
||||
def get_template(template_name: str, using: Optional[str] = ...) -> Any: ...
|
||||
def select_template(template_name_list: Union[List[str], str], using: Optional[str] = ...) -> Any: ...
|
||||
def render_to_string(
|
||||
template_name: Union[List[str], str],
|
||||
context: Optional[Union[Dict[str, bool], Dict[str, str]]] = ...,
|
||||
context: Optional[Dict[str, Any]] = ...,
|
||||
request: Optional[WSGIRequest] = ...,
|
||||
using: Optional[str] = ...,
|
||||
) -> str: ...
|
||||
|
||||
@@ -5,6 +5,6 @@ from .testcases import (
|
||||
LiveServerTestCase as LiveServerTestCase,
|
||||
)
|
||||
|
||||
from .utils import override_settings as override_settings
|
||||
from .utils import override_settings as override_settings, modify_settings as modify_settings
|
||||
|
||||
from .client import Client as Client
|
||||
|
||||
@@ -2,10 +2,55 @@ import os
|
||||
if not os.path.exists('./django-sources'):
|
||||
git clone -b stable/2.1.x https://github.com/django/django.git django-sources
|
||||
|
||||
ignored_error_patterns = ["Need type annotation for", "already defined on", "Cannot assign to a"]
|
||||
for line in $(mypy --config-file ./scripts/mypy.ini ./django-sources/tests).split('\n'):
|
||||
for pattern in ignored_error_patterns:
|
||||
if pattern in line:
|
||||
break
|
||||
else:
|
||||
print(line)
|
||||
IGNORED_ERROR_PATTERNS = [
|
||||
'Need type annotation for',
|
||||
'already defined on',
|
||||
'Cannot assign to a',
|
||||
'cannot perform relative import',
|
||||
'broken_app',
|
||||
'LazySettings',
|
||||
'Cannot infer type of lambda',
|
||||
'Incompatible types in assignment (expression has type "Callable[',
|
||||
'"Callable[[Any], Any]" has no attribute',
|
||||
'Invalid value for a to= parameter'
|
||||
]
|
||||
TESTS_DIRS = [
|
||||
'absolute_url_overrides',
|
||||
'admin_*',
|
||||
'aggregation*',
|
||||
'annotations'
|
||||
]
|
||||
|
||||
def check_file_in_the_current_directory(directory, fname):
|
||||
cd @(directory)
|
||||
with ${...}.swap(FNAME=fname):
|
||||
for line in $(mypy --config-file ../../../scripts/mypy.ini $FNAME).split('\n'):
|
||||
for pattern in IGNORED_ERROR_PATTERNS:
|
||||
if pattern in line:
|
||||
break
|
||||
else:
|
||||
if line:
|
||||
print(line)
|
||||
cd -
|
||||
|
||||
def parse_ls_output_into_fnames(output):
|
||||
fnames = []
|
||||
for line in output.splitlines()[1:]:
|
||||
fnames.append(line.split()[-1])
|
||||
return fnames
|
||||
|
||||
all_tests_dirs = []
|
||||
for test_dir in TESTS_DIRS:
|
||||
with ${...}.swap(TEST_DIR=test_dir):
|
||||
dirs = g`django-sources/tests/$TEST_DIR`
|
||||
all_tests_dirs.extend(dirs)
|
||||
|
||||
for tests_dir in all_tests_dirs:
|
||||
print('Checking ' + tests_dir)
|
||||
abs_dir = os.path.join(os.getcwd(), tests_dir)
|
||||
|
||||
with ${...}.swap(ABS_DIR=abs_dir):
|
||||
ls_output = $(ls $ABS_DIR)
|
||||
for fname in parse_ls_output_into_fnames(ls_output):
|
||||
path_to_check = os.path.join(abs_dir, fname)
|
||||
check_file_in_the_current_directory(abs_dir, fname)
|
||||
Reference in New Issue
Block a user