add more test folders

This commit is contained in:
Maxim Kurnikov
2019-02-13 19:44:25 +03:00
parent 587c2c484b
commit 79ebe20f2e
19 changed files with 148 additions and 104 deletions

View File

@@ -1,4 +1,4 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Iterator
from django.contrib.admin.options import ModelAdmin
from django.core.handlers.wsgi import WSGIRequest
@@ -16,7 +16,7 @@ class ListFilter:
self, request: WSGIRequest, params: Dict[str, str], model: Type[Model], model_admin: ModelAdmin
) -> None: ...
def has_output(self) -> bool: ...
def choices(self, changelist: Any) -> None: ...
def choices(self, changelist: Any) -> Optional[Iterator[Dict[str, Any]]]: ...
def queryset(self, request: Any, queryset: QuerySet) -> Optional[QuerySet]: ...
def expected_parameters(self) -> Optional[List[str]]: ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Optional, Tuple, List
from typing import Any, Optional, Tuple, List, overload
from django.db import models
@@ -30,4 +30,8 @@ class AbstractBaseUser(models.Model):
@classmethod
def get_email_field_name(cls) -> str: ...
@classmethod
@overload
def normalize_username(cls, username: str) -> str: ...
@classmethod
@overload
def normalize_username(cls, username: Any) -> Any: ...

View File

@@ -4,12 +4,7 @@ from django.db import models
from django.db.models.base import Model
from django.db.models.query import QuerySet
class ContentTypeManager(models.Manager):
creation_counter: int
model: None
name: None
use_in_migrations: bool = ...
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
class ContentTypeManager(models.Manager['ContentType']):
def get_by_natural_key(self, app_label: str, model: str) -> ContentType: ...
def get_for_model(self, model: Union[Type[Model], Model], for_concrete_model: bool = ...) -> ContentType: ...
def get_for_models(self, *models: Any, for_concrete_models: bool = ...) -> Dict[Type[Model], ContentType]: ...
@@ -18,9 +13,9 @@ class ContentTypeManager(models.Manager):
class ContentType(models.Model):
id: int
app_label: str = ...
model: str = ...
objects: Any = ...
app_label: models.CharField = ...
model: models.CharField = ...
objects: ContentTypeManager = ...
@property
def name(self) -> str: ...
def model_class(self) -> Optional[Type[Model]]: ...

View File

@@ -1,14 +1,13 @@
from typing import Any, Optional
from django.contrib.sites.models import Site
from django.db import models
class FlatPage(models.Model):
id: None
url: str = ...
title: str = ...
content: str = ...
enable_comments: bool = ...
template_name: str = ...
registration_required: bool = ...
sites: Any = ...
url: models.CharField = ...
title: models.CharField = ...
content: models.TextField = ...
enable_comments: models.BooleanField = ...
template_name: models.CharField = ...
registration_required: models.BooleanField = ...
sites: models.ManyToManyField[Site] = ...
def get_absolute_url(self) -> str: ...

View File

@@ -1,40 +1,43 @@
# Stubs for django.core.files.uploadedfile (Python 3.5)
from typing import Any, Dict, IO, Iterator, Optional, Union
from django.core.files import temp as tempfile
from django.core.files.base import File
class UploadedFile(File):
content_type = ... # type: Optional[str]
charset = ... # type: Optional[str]
content_type_extra = ... # type: Optional[Dict[str, str]]
content_type: Optional[str] = ...
charset: Optional[str] = ...
content_type_extra: Optional[Dict[str, str]] = ...
def __init__(
self,
file: IO,
name: str = None,
content_type: str = None,
size: int = None,
charset: str = None,
content_type_extra: Dict[str, str] = None,
file: Optional[IO] = ...,
name: Optional[str] = ...,
content_type: Optional[str] = ...,
size: Optional[int] = ...,
charset: Optional[str] = ...,
content_type_extra: Optional[Dict[str, str]] = ...,
) -> None: ...
class TemporaryUploadedFile(UploadedFile):
def __init__(
self, name: str, content_type: str, size: int, charset: str, content_type_extra: Dict[str, str] = None
self,
name: Optional[str],
content_type: Optional[str],
size: Optional[int],
charset: Optional[str],
content_type_extra: Optional[Dict[str, str]] = ...,
) -> None: ...
def temporary_file_path(self) -> str: ...
class InMemoryUploadedFile(UploadedFile):
field_name = ... # type: Optional[str]
field_name: Optional[str] = ...
def __init__(
self,
file: IO,
field_name: Optional[str],
name: str,
name: Optional[str],
content_type: Optional[str],
size: int,
size: Optional[int],
charset: Optional[str],
content_type_extra: Dict[str, str] = None,
content_type_extra: Dict[str, str] = ...,
) -> None: ...
def chunks(self, chunk_size: int = None) -> Iterator[bytes]: ...
def multiple_chunks(self, chunk_size: int = None) -> bool: ...

View File

@@ -168,12 +168,12 @@ class RawSQL(Expression):
def __init__(self, sql: str, params: Sequence[Any], output_field: Optional[_OutputField] = ...) -> None: ...
class Func(SQLiteNumericMixin, Expression):
function: Any = ...
function: str = ...
template: str = ...
arg_joiner: str = ...
arity: Any = ...
arity: int = ...
source_expressions: List[Expression] = ...
extra: Any = ...
extra: Dict[Any, Any] = ...
def __init__(self, *expressions: Any, output_field: Optional[_OutputField] = ..., **extra: Any) -> None: ...
def get_source_expressions(self) -> List[Combinable]: ...
def set_source_expressions(self, exprs: List[Expression]) -> None: ...

View File

@@ -207,6 +207,7 @@ class GenericIPAddressField(Field):
validators: Iterable[_ValidatorCallable] = ...,
error_messages: Optional[_ErrorMessagesToOverride] = ...,
) -> None: ...
def __set__(self, instance, value: Union[str, int, Callable[..., Any], Combinable]): ...
def __get__(self, instance, owner) -> str: ...
class DateTimeCheckMixin: ...
@@ -269,7 +270,7 @@ class DateTimeField(DateField):
def __get__(self, instance, owner) -> datetime: ...
class UUIDField(Field):
def __set__(self, instance, value: Any) -> None: ...
def __set__(self, instance, value: Union[str, uuid.UUID]) -> None: ...
def __get__(self, instance, owner) -> uuid.UUID: ...
class FilePathField(Field):

View File

@@ -9,22 +9,19 @@ class CumeDist(Func):
window_compatible: bool = ...
class DenseRank(Func):
extra: Dict[Any, Any]
source_expressions: List[Any]
function: str = ...
name: str = ...
output_field: Any = ...
window_compatible: bool = ...
class FirstValue(Func):
arity: int = ...
function: str = ...
name: str = ...
window_compatible: bool = ...
class LagLeadFunction(Func):
window_compatible: bool = ...
def __init__(self, expression: Optional[str], offset: int = ..., default: None = ..., **extra: Any) -> Any: ...
def __init__(
self, expression: Optional[str], offset: int = ..., default: Optional[int] = ..., **extra: Any
) -> None: ...
class Lag(LagLeadFunction):
function: str = ...

View File

@@ -1,4 +1,4 @@
from io import BytesIO
from io import BytesIO, StringIO
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
from django.http.request import QueryDict
@@ -11,7 +11,7 @@ class MultiPartParser:
def __init__(
self,
META: Dict[str, Any],
input_data: BytesIO,
input_data: Union[StringIO, BytesIO],
upload_handlers: Union[List[Any], ImmutableList],
encoding: Optional[str] = ...,
) -> None: ...

View File

@@ -27,7 +27,7 @@ class HttpResponseBase(Iterable[AnyStr]):
charset: Optional[str] = ...,
) -> None: ...
def serialize_headers(self) -> bytes: ...
def __setitem__(self, header: Union[str, bytes], value: Union[str, bytes]) -> None: ...
def __setitem__(self, header: Union[str, bytes], value: Union[str, bytes, int]) -> None: ...
def __delitem__(self, header: Union[str, bytes]) -> None: ...
def __getitem__(self, header: Union[str, bytes]) -> str: ...
def has_header(self, header: str) -> bool: ...

View File

@@ -1,7 +1,7 @@
from typing import Any, Optional
from django.http.request import HttpRequest
from django.http.response import HttpResponse, HttpResponseNotFound, HttpResponsePermanentRedirect
from django.http.response import HttpResponseBase, HttpResponsePermanentRedirect
from django.utils.deprecation import MiddlewareMixin
class CommonMiddleware(MiddlewareMixin):
@@ -9,9 +9,9 @@ class CommonMiddleware(MiddlewareMixin):
def process_request(self, request: HttpRequest) -> Optional[HttpResponsePermanentRedirect]: ...
def should_redirect_with_slash(self, request: HttpRequest) -> bool: ...
def get_full_path_with_slash(self, request: HttpRequest) -> str: ...
def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse: ...
def process_response(self, request: HttpRequest, response: HttpResponseBase) -> HttpResponseBase: ...
class BrokenLinkEmailsMiddleware(MiddlewareMixin):
def process_response(self, request: HttpRequest, response: HttpResponseNotFound) -> HttpResponseNotFound: ...
def process_response(self, request: HttpRequest, response: HttpResponseBase) -> HttpResponseBase: ...
def is_internal_request(self, domain: str, referer: str) -> bool: ...
def is_ignorable_request(self, request: HttpRequest, uri: str, domain: str, referer: str) -> bool: ...

View File

@@ -45,6 +45,7 @@ class Origin:
@property
def loader_name(self) -> Optional[str]: ...
class Template:
name: Optional[str] = ...
origin: Origin = ...
@@ -53,7 +54,7 @@ class Template:
nodelist: NodeList = ...
def __init__(
self,
template_string: str,
template_string: Union[Template, str],
origin: Optional[Origin] = ...,
name: Optional[str] = ...,
engine: Optional[Engine] = ...,

View File

@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, date, time
from decimal import Decimal
from typing import Any, Iterator, List, Optional, Union
@@ -8,14 +8,16 @@ FORMAT_SETTINGS: Any
def reset_format_cache() -> None: ...
def iter_format_modules(lang: str, format_module_path: Optional[Union[List[str], str]] = ...) -> Iterator[Any]: ...
def get_format_modules(lang: Optional[str] = ..., reverse: bool = ...) -> List[Any]: ...
def get_format(
format_type: str, lang: Optional[str] = ..., use_l10n: Optional[bool] = ...
) -> Union[List[str], int, str]: ...
def get_format(format_type: str, lang: Optional[str] = ..., use_l10n: Optional[bool] = ...) -> str: ...
get_format_lazy: Any
def date_format(value: Union[datetime, str], format: Optional[str] = ..., use_l10n: Optional[bool] = ...) -> str: ...
def time_format(value: Union[datetime, str], format: Optional[str] = ..., use_l10n: None = ...) -> str: ...
def date_format(
value: Union[date, datetime, str], format: Optional[str] = ..., use_l10n: Optional[bool] = ...
) -> str: ...
def time_format(
value: Union[time, datetime, str], format: Optional[str] = ..., use_l10n: Optional[bool] = ...
) -> str: ...
def number_format(
value: Union[Decimal, float, str],
decimal_pos: Optional[int] = ...,

View File

@@ -1,5 +1,6 @@
import logging.config
from typing import Any, Callable, Dict, Optional
from logging import LogRecord
from typing import Any, Callable, Dict, Optional, Union
from django.core.mail.backends.locmem import EmailBackend
from django.core.management.color import Style
@@ -20,9 +21,13 @@ class AdminEmailHandler(logging.Handler):
class CallbackFilter(logging.Filter):
callback: Callable = ...
def __init__(self, callback: Callable) -> None: ...
def filter(self, record: Union[str, LogRecord]) -> bool: ...
class RequireDebugFalse(logging.Filter): ...
class RequireDebugTrue(logging.Filter): ...
class RequireDebugFalse(logging.Filter):
def filter(self, record: Union[str, LogRecord]) -> bool: ...
class RequireDebugTrue(logging.Filter):
def filter(self, record: Union[str, LogRecord]) -> bool: ...
class ServerFormatter(logging.Formatter):
datefmt: None

View File

@@ -1,11 +1,11 @@
from decimal import Decimal
from typing import Any, Optional, Tuple, Union
from typing import Optional, Sequence, Union
def format(
number: Union[Decimal, float, str],
decimal_sep: str,
decimal_pos: Optional[int] = ...,
grouping: Union[Tuple[int, int, int], int] = ...,
grouping: Union[int, Sequence[int]] = ...,
thousand_sep: str = ...,
force_grouping: bool = ...,
use_l10n: Optional[bool] = ...,

View File

@@ -1,19 +1,21 @@
from typing import Any, Dict, List, Optional, Type
from typing import Any, Callable, Dict, Optional, Sequence, Type, Union
from django.db import models
from django.forms import models as model_forms, Form # type: ignore # This will be solved when adding forms module
from django.http import HttpResponse, HttpRequest
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin
from typing_extensions import Literal
from django.db import models
from django.forms import Form
from django.http import HttpRequest, HttpResponse
class FormMixin(ContextMixin):
initial = ... # type: Dict[str, object]
form_class = ... # type: Optional[Type[Form]]
success_url = ... # type: Optional[str]
prefix = ... # type: Optional[str]
request = ... # type: HttpRequest
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
def get_initial(self) -> Dict[str, object]: ...
initial: Dict[str, Any] = ...
form_class: Optional[Type[Form]] = ...
success_url: Optional[Union[str, Callable[..., Any]]] = ...
prefix: Optional[str] = ...
request: HttpRequest = ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: object) -> HttpResponse: ...
def get_initial(self) -> Dict[str, Any]: ...
def get_prefix(self) -> Optional[str]: ...
def get_form_class(self) -> Type[Form]: ...
def get_form(self, form_class: Type[Form] = None) -> Form: ...
@@ -24,8 +26,8 @@ class FormMixin(ContextMixin):
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
class ModelFormMixin(FormMixin, SingleObjectMixin):
fields = ... # type: Optional[List[str]]
object = ... # type: models.Model
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...
object: models.Model = ...
def get_form_class(self) -> Type[Form]: ...
def get_form_kwargs(self) -> Dict[str, object]: ...
def get_success_url(self) -> str: ...

View File

@@ -62,7 +62,11 @@ def return_user_model_hook(ctx: FunctionContext) -> Type:
if setting_expr is None:
return ctx.default_return_type
app_label, _, model_class_name = get_string_value_from_expr(setting_expr).rpartition('.')
model_path = get_string_value_from_expr(setting_expr)
if model_path is None:
return ctx.default_return_type
app_label, _, model_class_name = model_path.rpartition('.')
if app_label is None:
return ctx.default_return_type

View File

@@ -69,11 +69,14 @@ def redefine_and_typecheck_model_init(ctx: FunctionContext) -> Type:
def redefine_and_typecheck_model_create(ctx: MethodContext) -> Type:
api = cast(TypeChecker, ctx.api)
if isinstance(ctx.type, Instance) and len(ctx.type.args) > 0:
model: TypeInfo = ctx.type.args[0].type
model_generic_arg = ctx.type.args[0]
else:
if isinstance(ctx.default_return_type, AnyType):
return ctx.default_return_type
model: TypeInfo = ctx.default_return_type.type
model_generic_arg = ctx.default_return_type
if isinstance(model_generic_arg, AnyType):
return ctx.default_return_type
model: TypeInfo = model_generic_arg.type
# extract name of base models for _ptr
base_pointer_args = extract_base_pointer_args(model)

View File

@@ -19,7 +19,7 @@ DJANGO_COMMIT_SHA = '03219b5f709dcd5b0bfacd963508625557ec1ef0'
# Some errors occur for the test suite itself, and cannot be addressed via django-stubs. They should be ignored
# using this constant.
MOCK_OBJECTS = ['MockRequest', 'MockCompiler', 'modelz', 'call_count', 'call_args_list', 'call_args']
MOCK_OBJECTS = ['MockRequest', 'MockCompiler', 'modelz', 'call_count', 'call_args_list', 'call_args', 'MockUser']
IGNORED_ERRORS = {
'__common__': [
*MOCK_OBJECTS,
@@ -28,6 +28,7 @@ IGNORED_ERRORS = {
'Need type annotation for',
'Invalid value for a to= parameter',
'already defined (possibly by an import)',
'gets multiple values for keyword argument',
'Cannot assign to a type',
re.compile(r'Cannot assign to class variable "[a-z_]+" via instance'),
# forms <-> models plugin support
@@ -135,6 +136,9 @@ IGNORED_ERRORS = {
'dispatch': [
'Argument 1 to "connect" of "Signal" has incompatible type "object"; expected "Callable[..., Any]"'
],
'deprecation': [
re.compile('"(old|new)" undefined in superclass')
],
'db_typecasts': [
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)'
],
@@ -147,6 +151,12 @@ IGNORED_ERRORS = {
'field_deconstruction': [
'Incompatible types in assignment (expression has type "ForeignKey[Any]", variable has type "CharField")'
],
'file_uploads': [
'"handle_uncaught_exception" undefined in superclass'
],
'fixtures': [
'Incompatible types in assignment (expression has type "int", target has type "Iterable[str]")'
],
'get_object_or_404': [
'Argument 1 to "get_object_or_404" has incompatible type "str"; '
+ 'expected "Union[Type[<nothing>], Manager[<nothing>], QuerySet[<nothing>]]"',
@@ -164,6 +174,9 @@ IGNORED_ERRORS = {
'Argument "max_length" to "CharField" has incompatible type "str"; expected "Optional[int]"',
'Argument "choices" to "CharField" has incompatible type "str"'
],
'logging_tests': [
re.compile('"(setUpClass|tearDownClass)" undefined in superclass')
],
'model_inheritance_regress': [
'Incompatible types in assignment (expression has type "List[Supplier]", variable has type "QuerySet[Supplier]")'
],
@@ -175,6 +188,8 @@ IGNORED_ERRORS = {
'Incompatible types in assignment (expression has type "Type[Person]", variable has type',
'Unexpected keyword argument "name" for "Person"',
'Cannot assign multiple types to name "PersonTwoImages" without an explicit "Type[...]" annotation',
'Incompatible types in assignment (expression has type "Type[Person]", '
+ 'base class "ImageFieldTestMixin" defined the type as "Type[PersonWithHeightAndWidth]")'
],
'model_regress': [
'Too many arguments for "Worker"',
@@ -200,6 +215,13 @@ IGNORED_ERRORS = {
'FakeLoader',
'Argument 1 to "append" of "list" has incompatible type "AddIndex"; expected "CreateModel"'
],
'middleware_exceptions': [
'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any]"; expected "str"'
],
'multiple_database': [
'Unexpected attribute "extra_arg" for model "Book"',
'Too many arguments for "create" of "QuerySet"'
],
'queryset_pickle': [
'"None" has no attribute "somefield"'
],
@@ -294,6 +316,13 @@ IGNORED_ERRORS = {
'select_related_onetoone': [
'"None" has no attribute'
],
'servers': [
re.compile('Argument [0-9] to "WSGIRequestHandler"')
],
'sitemaps_tests': [
'Incompatible types in assignment (expression has type "str", '
+ 'base class "Sitemap" defined the type as "Callable[[Sitemap, Model], str]")'
],
'view_tests': [
'"Handler" has no attribute "include_html"',
'"EmailMessage" has no attribute "alternatives"'
@@ -328,10 +357,10 @@ TESTS_DIRS = [
'builtin_server',
'bulk_create',
# TODO: 'cache',
# TODO: 'check_framework',
'check_framework',
'choices',
'conditional_processing',
# TODO: 'contenttypes_tests',
'contenttypes_tests',
'context_processors',
'csrf_tests',
'custom_columns',
@@ -347,36 +376,36 @@ TESTS_DIRS = [
'db_typecasts',
'db_utils',
'dbshell',
# TODO: 'decorators',
'decorators',
'defer',
# TODO: 'defer_regress',
'defer_regress',
'delete',
'delete_regress',
# TODO: 'deprecation',
'deprecation',
'dispatch',
'distinct_on_fields',
'empty',
'expressions',
'expressions_case',
# TODO: 'expressions_window',
'expressions_window',
# TODO: 'extra_regress',
'field_deconstruction',
'field_defaults',
'field_subclassing',
# TODO: 'file_storage',
# TODO: 'file_uploads',
'file_uploads',
# TODO: 'files',
'filtered_relation',
# TODO: 'fixtures',
'fixtures',
'fixtures_model_package',
# TODO: 'fixtures_regress',
# TODO: 'flatpages_tests',
'fixtures_regress',
'flatpages_tests',
'force_insert_update',
'foreign_object',
# TODO: 'forms_tests',
'from_db_value',
# TODO: 'generic_inline_admin',
# TODO: 'generic_relations',
'generic_inline_admin',
'generic_relations',
'generic_relations_regress',
# TODO: 'generic_views',
'get_earliest_or_latest',
@@ -397,7 +426,7 @@ TESTS_DIRS = [
# 'invalid_models_tests',
'known_related_objects',
# TODO: 'logging_tests',
'logging_tests',
'lookup',
'm2m_and_m2o',
'm2m_intermediary',
@@ -415,13 +444,13 @@ TESTS_DIRS = [
'many_to_one_null',
'max_lengths',
# TODO: 'messages_tests',
# TODO: 'middleware',
# TODO: 'middleware_exceptions',
'middleware',
'middleware_exceptions',
'migrate_signals',
'migration_test_data_persistence',
'migrations',
'migrations2',
# TODO: 'model_fields',
'model_fields',
# TODO: 'model_forms',
'model_formsets',
'model_formsets_regress',
@@ -433,7 +462,7 @@ TESTS_DIRS = [
'model_package',
'model_regress',
'modeladmin',
# TODO: 'multiple_database',
'multiple_database',
'mutually_referential',
'nested_foreign_keys',
'no_models',
@@ -451,7 +480,7 @@ TESTS_DIRS = [
'properties',
'proxy_model_inheritance',
# TODO: 'proxy_models',
# TODO: 'queries',
'queries',
'queryset_pickle',
'raw_query',
'redirects_tests',
@@ -467,7 +496,7 @@ TESTS_DIRS = [
'select_related_onetoone',
'select_related_regress',
# TODO: 'serializers',
# TODO: 'servers',
'servers',
'sessions_tests',
'settings_tests',
'shell',
@@ -503,7 +532,6 @@ TESTS_DIRS = [
# TODO: 'urlpatterns_reverse',
'user_commands',
# TODO: 'utils_tests',
# not annotatable without annotation in test
# TODO: 'validation',
'validators',
'version',