Commit Graph

20 Commits

Author SHA1 Message Date
Sigurd Ljødal
02999f3e86 Fix unresolved placeholder error during serialization (#1161)
This fixes an error that occured during state serialization. Completely
unsure how to reproduce this in a test but it resolves a long-standing
prolem in our project at work at least.
2022-09-23 21:35:23 +03:00
Nikita Sobolev
0bb1182c42 Fix CI (#1108)
* Fix CI

* Fix CI

* Fix CI

* Fix CI

* APply black

* APply black

* Fix mypy

* Fix mypy errors in django-stubs

* Fix format

* Fix plugin

* Do not patch builtins by default

* Fix mypy

* Only run mypy on 3.10 for now

* Only run mypy on 3.10 for now

* WHAT THE HELL

* Enable strict mode in mypy

* Enable strict mode in mypy

* Fix tests

* Fix tests

* Debug

* Debug

* Fix tests

* Fix tests

* Add TYPE_CHECKING debug

* Caching maybe?

* Caching maybe?

* Try explicit `${{ matrix.python-version }}`

* Remove debug

* Fix typing

* Finally
2022-08-26 13:22:55 +03:00
Sigurd Ljødal
e7a89f73c4 Improve typing for unresolved managers (#1044)
* Improve typing for unresolved managers

This changes the logic when encountering an unresolvable manager class.
Instead of adding it as a `Manager` we create a subclass of `Manager`
that has `fallback_to_any=True` set. Similarly a `QuerySet` class is
created that also has fallbacks to `Any`. This allows calling custom
methods on the manager and querysets without getting type errors.

* Fix manager created and improve a test

* Fix row type of FallbackQuerySet

Because this inherits from _QuerySet, not QuerySet, it needs to have two
parameters
2022-07-18 09:13:46 +03:00
Sigurd Ljødal
830d74b493 Add support for inline from_queryset in model classes (#1045)
* Add support for inline from_queryset in model classes

This adds support for calling <Manager>.from_queryset(<QuerySet>)()
inline in models, for example like this:

    class MyModel(models.Model):
        objects = MyManager.from_queryset(MyQuerySet)()

This is done by inspecting the class body in the transform_class_hook

* Fix missing methods on copied manager

* Add test and other minor tweaks

* Always create manager at module level

When the manager is added at the class level, which happened when it was
created inline in the model body, it's not possible to retrieve the
manager again based on fullname. That lead to problems with inheritance
and the default manager.
2022-07-13 10:04:44 +03:00
Sigurd Ljødal
84eff75566 Resolve all queryset methods on managers as attributes (#1028)
* Add test case reproducing Sequence name not defined issue

* Resolve all manager methods as attribute

This changes to logic for resolving methods from the base QuerySet class
on managers from copying the methods to use the attribute approach
that's already used for methods from custom querysets. This resolves the
phantom type errors that stem from the copying.

* Disable cache in test case

Make sure the test will fail regardless of which mypy.ini file is being using.

Co-authored-by: Petter Friberg <petter@5monkeys.se>

* Update comments related to copying methods

* Use a predefined list of manager methods to update

The list of manager methods that returns a queryset, and thus need to
have it's return type changed, is small and well defined. Using a
predefined list of methods rather than trying to detect these at runtime
makes the code much more readable and probably faster as well.

Also add `extra()` to the methods tested in
from_queryset_includes_methods_returning_queryset, and sort the methods
alphabetically.

* Revert changes in .github/workflows/tests.yml

With cache_disable: true on the test case this is no longer needed to
reproduce the bug.

* Remove unsued imports and change type of constant

 - Remove unused imports left behind
 - Change MANAGER_METHODS_RETURNING_QUERYSET to Final[FrozenSet[str]]

* Import Final from typing_extensions

Was added in 3.8, we still support 3.7

* Sort imports properly

* Remove explicit typing of final frozenset

Co-authored-by: Nikita Sobolev <mail@sobolevn.me>

* Add comment for test case

* Fix typo

* Rename variable

Co-authored-by: Petter Friberg <petter@5monkeys.se>
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
2022-06-30 10:19:33 +03:00
sterliakov
6226381484 Recover after #909 (#925)
* Fix stubs related to `(Async)RequestFactory` and `(Async)Client`

* Revert incorrect removal.

* Allow set as `unique_together`, use shared type alias.

* Revert `Q.__init__` to use only `*args, **kwargs` to remove false-positive with `Q(**{...})`

* Add abstract methods to `HttpResponseBase` to create common interface.

* Remove monkey-patched attributes from `HttpResponseBase` subclasses.

* Add QueryDict mutability checks (+ plugin support)

* Fix lint

* Return back GenericForeignKey to `Options.get_fields`

* Minor fixup

* Make plugin code typecheck with `--warn-unreachable`, minor performance increase.

* Better types for `{unique, index}_together` and Options.

* Fix odd type of `URLResolver.urlconf_name` which isn't a str actually.

* Better types for field migration operations.

* Revert form.files to `MultiValueDict[str, UploadedFile]`

* Compatibility fix (#916)

* Do not assume that `Annotated` is always related to django-stubs (fixes #893)

* Restrict `FormView.get_form` return type to `_FormT` (class type argument). Now it is resolved to `form_class` argument if present, but also errors if it is not subclass of _FormT

* Fix CI (make test runnable on 3.8)

* Fix CI (make test runnable on 3.8 _again_)
2022-04-28 13:01:37 +03:00
Sigurd Ljødal
dc4c0d9ee4 Emit error instead of raising on union custom QuerySet (#907)
* Add reproducer for failing case

* Emit warning instead of crashing when encountering enum

* Remove prints, slightly tweak error message

* Remove unused import

* Run black and isort

* Run isort on .pyi file

* Remove unrelated issue from test case
2022-04-01 22:07:55 +03:00
Petter Friberg
92e5f202ac Cache dynamically created manager nodes (#840)
- Non plugin generated, "cross_ref"s points to dynamically
  created managers (e.g. `Model.objects`) and can make Mypy fail on
  cached runs
2022-03-31 10:21:21 +03:00
Petter Friberg
515e382d4a Fix .filter-kwargs lookup crash during cached runs (#828)
* Fix .filter-kwargs lookup crash during cached runs

* Update mypy_django_plugin/lib/helpers.py

Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
2022-01-24 13:24:09 +03:00
Petter Friberg
edec5a1c99 Notify when Manager.from_queryset happens inside model class body (#824)
* Refactor to more easily support additional config options

* Notify when Manager.from_queryset happens inside model class body

- A warning will be emitted whenever `Manager.from_queryset` happens
  inside of a model class body

* Resolve generated default manager types before final iteration

A default manager on a model should always exist, eventually. Although,
we extend to look through dynamically generated managers on each
iteration instead of deferring until the final iteration.
2022-01-21 19:46:56 +03:00
Petter Friberg
a9e41a8ba9 Fix suggested changes from #820 (#821) 2022-01-16 21:13:47 +03:00
Petter Friberg
99f28387fb Set custom queryset methods as manager attrs instead of method copies (#820)
Instead of copying methods over from a QuerySet passed to a basemanager
when invoking '<BaseManager>.from_queryset', any QuerySet methods are
declared as attributes on the manager.

This allows us to properly lookup any QuerySet method types via a
'get_attribute_hook' and will thus remove disorienting phantom errors
occuring from mypy trying to resolve types only existing in the module
where the _original_ (and real) queryset method was declared.
2022-01-16 12:14:33 +03:00
Seth Yastrov
8da8ab4862 Fix/673/from queryset then custom qs method (#680)
* Fix `MyModel.objects.filter(...).my_method()`

* Fix regression: `MyModel.objects.filter(...).my_method()` no longer worked when using from_queryset

This also fixes the self-type of the copied-over methods of the manager generated by from_queryset.
Previously it was not parameterized by the model class, but used Any.

The handling of unbound types is not tested here as I have not been able to
find a way to create a test case for it. It has been manually tested
against an internal codebase.

* Remove unneeded defer.
2021-07-30 01:01:39 +03:00
Seth Yastrov
cfd69c0acc QuerySet.annotate improvements (#398)
* QuerySet.annotate returns self-type. Attribute access falls back to Any.

- QuerySets that have an annotated model do not report errors during .filter() when called with invalid fields.
- QuerySets that have an annotated model return ordinary dict rather than TypedDict for .values()
- QuerySets that have an annotated model return Any rather than typed Tuple for .values_list()

* Fix .annotate so it reuses existing annotated types. Fixes error in typechecking Django testsuite.

* Fix self-typecheck error

* Fix flake8

* Fix case of .values/.values_list before .annotate.

* Extra ignores for Django 2.2 tests (false positives due to tests assuming QuerySet.first() won't return None)

Fix mypy self-check.

* More tests + more precise typing in case annotate called before values_list.

Cleanup tests.

* Test and fix annotate in combination with values/values_list with no params.

* Remove line that does nothing :)

* Formatting fixes

* Address code review

* Fix quoting in tests after mypy changed things

* Use Final

* Use typing_extensions.Final

* Fixes after ValuesQuerySet -> _ValuesQuerySet refactor. Still not passing tests yet.

* Fix inheritance of _ValuesQuerySet and remove unneeded type ignores.

This allows the test
"annotate_values_or_values_list_before_or_after_annotate_broadens_type"
to pass.

* Make it possible to annotate user code with "annotated models", using PEP 583 Annotated type.

* Add docs

* Make QuerySet[_T] an external alias to _QuerySet[_T, _T].

This currently has the drawback that error messages display the internal type _QuerySet, with both type arguments.

See also discussion on #661 and #608.

Fixes #635: QuerySet methods on Managers (like .all()) now return QuerySets rather than Managers.

Address code review by @sobolevn.

* Support passing TypedDicts to WithAnnotations

* Add an example of an error to README regarding WithAnnotations + TypedDict.

* Fix runtime behavior of ValuesQuerySet alias (you can't extend Any, for example).

Fix some edge case with from_queryset after QuerySet changed to be an
alias to _QuerySet. Can't make a minimal test case as this only occurred
on a large internal codebase.

* Fix issue when using from_queryset in some cases when having an argument with a type annotation on the QuerySet.

The mypy docstring on anal_type says not to call defer() after it.
2021-07-23 16:15:15 +03:00
Patrick Gingras
f182b39c91 Copy decorated queryset methods to manager too (#646)
* copy decorated queryset methods to manager too

* added test for from_manager with decorated queryset methods
2021-06-16 10:15:32 +03:00
Cesar Canassa
77f9926ce1 fix tests for mypy 0.900 (#641) 2021-06-12 01:05:46 +03:00
Na'aman Hirschfeld
44151c485d updated package setup (#485)
* updated package setup

* updated to use python 3.9

* fixed test runner

* fixed typecheck tests

* fixed discrepencies

* added override to runner

* updated travis

* updated pre-commit hooks

* updated dep
2020-10-29 11:59:48 +03:00
Dima Boger
b3ed9e4827 Add inheritance QuerySet support for from_queryset (#275)
* Add testcase for queryset inheritance

* Add PoC

* Add condition for stop to looping over mro

* Change harcoded queryset class name to constant from fullnames
2019-12-16 20:16:41 +03:00
Maksim Kurnikov
d0c25e3bce Allow to run from_queryset() with BaseManager, Manager (#271)
* allow to run from_queryset() with BaseManager, Manager

* fix tests
2019-12-13 20:16:33 +03:00
Maksim Kurnikov
ade48b6546 Add support for BaseManager.from_queryset() (#251)
* add support for BaseManager.from_queryset()

* cleanups

* lint fixes
2019-12-12 05:35:56 +03:00