mirror of
https://github.com/davidhalter/django-stubs.git
synced 2026-02-16 23:13:56 +08:00
Large update (#909)
* Make module declaration precise. * Make settings match real file. * Replace `include` with import. * Make types more specific. * Replace `WSGIRequest` with `HttpRequest` where possible. * Replace all `OrderedDict` occurrences with plain `Dict` (it is not used in Django 3.2 and later) * Add fake datastructures for convenience: _PropertyDescriptor and _ListOrTuple now can live here. Added _IndexableCollection (often useful as alias for 'sequence or queryset') * Actualize other datastructures. * Rework MultiValueDict to reflect the fact that some methods can return empty list instead of value. * Deprecate SafeText in favor of SafeString. * Minor improvements to utils * Disallow using str in TimeFormat and DateFormat, drop removed fmt `B` * Do not let classproperty expect classmethod, make return value covariant. * Sync with real file. * Improve types for timezone. * Sync deprecated, new and removed features in translation utils. * Drop removed files, sync huge deprecations. * Fix incompatible decorators (properties, contextmanagers) * Rework pagination. * Sync validators with real code. Add _ValidatorCallable for any external use (field validation etc.) * Add shared type definitions (for fields of both forms and models). Actualize model fields. Mark keyword-only args explicitly in stubs (where code uses **kwargs). Disallow bytes for verbose_name. * Make all checks return Sequence[CheckMessage] or subclass to be covariant. * Add bidirectional references between backend.base and other files. Replace some Any's with specific types. * Actualize db.migrations: remove removed methods, replace "None" annotations in wrong places, improve some wrong annotations. * Actualize db.utils to match real file. * Replace FileResponse and TemplateResponse with HttpResponse(Base) where needed: at least HttpResponseNotModified/HttpResponseRedirect can be returned instead of it, so annotation was wrong. * Replace Any in forms where possible. Actualize class bases and method arguments. * Improve typing of serializers. * Actualize views, rename variable bound to Model to _M for consistency. * Make types of file-related code consistent. Disallow using bytes as path, because many methods expect str-only paths. Make File inherit from IO[AnyStr] instead of IO[Any]: it makes impossible to instantiate file of union type, but allows precise types for some methods. * Minor improvements: stop using None as annotation in wrong places, replace obvious Any's with precise types, actualize methods (missing/renamed/signature changed). * Allow less specific containers, replace Any's with specific types. * Improve types for requests and responses. * Use AbstractBaseUser instead of User in auth. * Use broader type for permission_required * Use wider container types. Add 'type: ignore' to avoid issues with mypy.stubtest. * Disallow using backend class as argument (it is passed to import_string). * Add required methods to PasseordValidator. * Allow using Path instance as argument. * Actualize methods. * Add 'type: ignore' to avoid issues with mypy.stubtest. * Replace Any's with specific types and BaseForm with ModelForm. * Actualize contrib.postgres * Remove render_to_response, add 'get_absolute_url' to corresponding protocol. * Actualize signers. * Use precise types for handlers. Disallow str as stream type for LimitedStream. * Exact types for ValidationError * Replace wrong used Union with Sequence. * Actualize static handlers. * More specific types for admin. Fixes #874. * Improve types and replace 'Tags' with str (it isn't Enum, so annotation was wrong). * Replace Any with specific types, actualize signatures. * Add async variants of handlers and clients. Use fake class to distinguish between request types in RequestFactory and AsyncRequestFactory. * Fix signature, minor improvements. * Actualize signatures and class names, replace Any with more specific types. * Fix signature. * Add some missing methods to Collector * Combinable rarely returns Self type: almost always it's CombinedExpression. * No Random in source anymore. * Drop removed SimpleCol. * Replace _OutputField with Field: nothing in docs about strings. * Introduce reusable types, add missing methods. Remove strange types (probably created by stubgen). Remove RawQuery from Compiler: it obviously doesn't work with RawQuery. * Use literal constants. * Actualize base classes. * Callable is not accepted by get_field. * Add precise types. * Use property and broader containers where possible. Add missing methods. * Actualize indexes. * More specific types for signals. * Fix signatures, drop missing methods. * Actualize window functions to match source. * Actualize text functions, add missing methods, use type aliases for consistency. * Add missing property decorators, methods and attributes. Use type aliases. Remove absent YearComparisonLookup and any SafeText references (they aren't related to lookups at all). * Use bound TypeVar, mark all BuiltinLookup descendants as generic explicitly. Remove strange Union from Lookup.__init__ * Apply type alias, fix base class and argument name. * Actualize BaseExpression methods. * Fix imports. * Add missing class and fix incompatible bases. * Use same types in __init__ and attribute. * OrderBy accepts F or Expression. * Non-expressions are converted to Values. * Add missing attributes. * Add missing methods, fix 'None' argument type. * Define properties where possible, remove 'None' argument annotations, remove inadequate type in make_immutable_fields_list. * Remove absent QueryWrapper. Replace some Any with precise types. * Fix wrong types and actualize signatures. Deny ManagerDescriptor.__get__ on model instances. * Use more specific types. * Arity can be None in subclasses. * Reformat with black * Make DeletionMixin generic. * Fix wrong type variable in _RequestFactory. * Fix variable name in signature. * Disallow returning None from Form.clean() * Allow again returning None from Form.clean * Drop some unused imports. * Add tests for MultiValueDict. * Add tests for utils.timezone. * Fix #834. * Add more files to import_all test * Allow None for `context_object_name` * Fix CI * Fix test to work on python 3.8
This commit is contained in:
48
tests/typecheck/utils/test_datastructures.yml
Normal file
48
tests/typecheck/utils/test_datastructures.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
- case: multivaluedict
|
||||
main: |
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from typing import Dict, List, Tuple, Union
|
||||
|
||||
# check constructors
|
||||
var1 = MultiValueDict() # E: Need type annotation for "var1"
|
||||
d2: Dict[str, List[Union[str, int]]] = {'foo': ['Foo'], 'bar': [2, 3]}
|
||||
var2 = MultiValueDict(d2)
|
||||
d3: Tuple[Tuple[str, List[Union[str, int]]], ...] = (('foo', ['Foo']), ('bar', [2, 3]))
|
||||
var3 = MultiValueDict(d3)
|
||||
reveal_type(var1) # N: Revealed type is "django.utils.datastructures.MultiValueDict[Any, Any]"
|
||||
reveal_type(var2) # N: Revealed type is "django.utils.datastructures.MultiValueDict[builtins.str*, Union[builtins.str, builtins.int]]"
|
||||
reveal_type(var3) # N: Revealed type is "django.utils.datastructures.MultiValueDict[builtins.str*, Union[builtins.str, builtins.int]]"
|
||||
|
||||
# __getitem__, get, getlist (with proofs)
|
||||
d = MultiValueDict({'foo': ['Foo']})
|
||||
d.setlist('bar', [])
|
||||
# actually 'Foo'
|
||||
reveal_type(d['foo']) # N: Revealed type is "Union[builtins.str*, builtins.list[builtins.object]]"
|
||||
# actually []
|
||||
reveal_type(d['bar']) # N: Revealed type is "Union[builtins.str*, builtins.list[builtins.object]]"
|
||||
# actually None
|
||||
reveal_type(d.get('bar')) # N: Revealed type is "Union[builtins.str*, None]"
|
||||
# actually 1
|
||||
reveal_type(d.get('bar', 1)) # N: Revealed type is "Union[builtins.str, builtins.int*]"
|
||||
# actually []
|
||||
reveal_type(d.getlist('bar')) # N: Revealed type is "builtins.list[builtins.str]"
|
||||
# actually []
|
||||
reveal_type(d.getlist('bar', [1])) # N: Revealed type is "Union[builtins.list[builtins.str], builtins.list*[builtins.int*]]"
|
||||
# actually True (note that default can be not a list)
|
||||
reveal_type(d.getlist('baz', True)) # N: Revealed type is "Union[builtins.list[builtins.str], builtins.bool*]"
|
||||
|
||||
# setters
|
||||
reveal_type(d.setlistdefault('baz')) # N: Revealed type is "builtins.list[builtins.str*]"
|
||||
d.setlistdefault('baz', [1]) # E: List item 0 has incompatible type "int"; expected "str"
|
||||
reveal_type(d.setlistdefault('baz', [])) # N: Revealed type is "builtins.list[builtins.str*]"
|
||||
d.appendlist('baz', 'Baz')
|
||||
d.appendlist('baz', 1) # E: Argument 2 to "appendlist" of "MultiValueDict" has incompatible type "int"; expected "str"
|
||||
|
||||
# iterators
|
||||
# actually [('foo', 'Foo'), ('bar', [])]
|
||||
reveal_type(list(d.items())) # N: Revealed type is "builtins.list[Tuple[builtins.str*, Union[builtins.str*, builtins.list[builtins.object]]]]"
|
||||
reveal_type(list(d.keys())) # N: Revealed type is "builtins.list[builtins.str*]"
|
||||
# actually ['Foo', []]
|
||||
reveal_type(list(d.values())) # N: Revealed type is "builtins.list[Union[builtins.str*, builtins.list[builtins.object]]]"
|
||||
# actually {'foo': 'Foo', 'bar': []}
|
||||
reveal_type(d.dict()) # N: Revealed type is "builtins.dict[builtins.str*, Union[builtins.str*, builtins.list[builtins.object]]]"
|
||||
14
tests/typecheck/utils/test_encoding.yml
Normal file
14
tests/typecheck/utils/test_encoding.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- case: force_bytes_or_str
|
||||
main: |
|
||||
from django.utils.encoding import force_bytes, force_str
|
||||
class S(str):
|
||||
pass
|
||||
|
||||
reveal_type(force_bytes(123)) # N: Revealed type is "builtins.bytes"
|
||||
reveal_type(force_bytes(123, strings_only=True)) # N: Revealed type is "builtins.int*"
|
||||
|
||||
reveal_type(force_str(123)) # N: Revealed type is "builtins.str"
|
||||
reveal_type(force_str(123, strings_only=True)) # N: Revealed type is "builtins.int*"
|
||||
reveal_type(force_str('foo')) # N: Revealed type is "builtins.str*"
|
||||
reveal_type(force_str('foo', strings_only=True)) # N: Revealed type is "builtins.str*"
|
||||
reveal_type(force_str(S('foo'), strings_only=True)) # N: Revealed type is "main.S*"
|
||||
30
tests/typecheck/utils/test_timezone.yml
Normal file
30
tests/typecheck/utils/test_timezone.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
- case: is_naive_correct
|
||||
main: |
|
||||
from django.utils.timezone import is_naive
|
||||
from datetime import date, time, datetime
|
||||
reveal_type(is_naive(date(2020, 1, 1)))
|
||||
reveal_type(is_naive(datetime(2020, 1, 1)))
|
||||
reveal_type(is_naive(time()))
|
||||
out: |
|
||||
main:3: error: No overload variant of "is_naive" matches argument type "date"
|
||||
main:3: note: Possible overload variants:
|
||||
main:3: note: def is_naive(value: time) -> Literal[True]
|
||||
main:3: note: def is_naive(value: datetime) -> bool
|
||||
main:3: note: Revealed type is "Any"
|
||||
main:4: note: Revealed type is "builtins.bool"
|
||||
main:5: note: Revealed type is "Literal[True]"
|
||||
- case: is_aware_correct
|
||||
main: |
|
||||
from django.utils.timezone import is_aware
|
||||
from datetime import date, time, datetime
|
||||
reveal_type(is_aware(date(2020, 1, 1)))
|
||||
reveal_type(is_aware(datetime(2020, 1, 1)))
|
||||
reveal_type(is_aware(time()))
|
||||
out: |
|
||||
main:3: error: No overload variant of "is_aware" matches argument type "date"
|
||||
main:3: note: Possible overload variants:
|
||||
main:3: note: def is_aware(value: time) -> Literal[False]
|
||||
main:3: note: def is_aware(value: datetime) -> bool
|
||||
main:3: note: Revealed type is "Any"
|
||||
main:4: note: Revealed type is "builtins.bool"
|
||||
main:5: note: Revealed type is "Literal[False]"
|
||||
Reference in New Issue
Block a user