Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[django-filter] Absorb django-filter-stubs into typeshed #10919

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

intgr
Copy link
Contributor

@intgr intgr commented Oct 20, 2023

As described in #10918, I have added stubs from django-filter-stubs project. Upstream issue: DavisRayM/django-filter-stubs#13

Please don't use squash merge to merge this (unless there's explicit decision to reconsider #10918). I have preserved original commit authors. There really weren't many changes in stubs files.

@AlexWaygood
Copy link
Member

pre-commit.ci autofix

@github-actions

This comment has been minimized.

@intgr intgr force-pushed the add-types-django-filter branch from ecdac04 to 1e34eaa Compare October 22, 2023 10:13
@github-actions

This comment has been minimized.

@intgr intgr force-pushed the add-types-django-filter branch from 9cf4747 to 1549268 Compare October 22, 2023 10:31
@intgr intgr marked this pull request as ready for review October 22, 2023 10:32
@intgr intgr force-pushed the add-types-django-filter branch from 6b08536 to 63e9ab6 Compare October 22, 2023 10:34
@intgr
Copy link
Contributor Author

intgr commented Oct 22, 2023

This should be more or less ready for initial merge. If we can get this merged, I can look into the stubtest allowlist issues separately. Unless you think I should fix them immediately here?

Some questions:

  1. The stubs depend on django-stubs and djangorestframework-stubs. If we continue with this merge, these need to be added to stub_uploader allowlist. Nikita Sobolev can vouch for the fact that these dependencies aren't evil 😈

    Opened PR: Add django-stubs, djangorestframework-stubs to allowlist typeshed-internal/stub_uploader#111

  2. stubtest gets exception django.core.exceptions.ImproperlyConfigured from poking around in some django-filter internals. I could just allowlist these.

    But if we could somehow set DJANGO_SETTINGS_MODULE env variable for the stubtest run (to some empty Python module even), then we wouldn't need to suppress them. Is there any precedent to this?

  3. Upstream used Any for incomplete types. Should I convert all of these to _typeshed.Incomplete or not bother with this?

@github-actions

This comment has been minimized.

Copy link
Contributor Author

@intgr intgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some further questions. Personally I'd prefer to get this merged first and then do further improvements in follow-up PRs.

from django import forms

from .conf import settings as settings
from .constants import EMPTY_VALUES as EMPTY_VALUES
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are lots of re-exports that shouldn't be re-exported. Should I clean these up before initial merge, or in follow-up?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follow-up is fine imo

def __init__(self, *args: Any, **kwargs: Any) -> None: ...

class TimeRangeField(RangeField):
widget: Any = ...
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I clean up attribute assignments?

Suggested change
widget: Any = ...
widget: Any

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to do this in a follow-up imo

@AlexWaygood
Copy link
Member

(Writing from my phone, I have limited access to a laptop with Internet until Tuesday)

In general, I think it's fine to tackle issues with these stubs in followup PRs, now you've got CI passing (thanks!). Most things in stubs/peewee/ are still unannotated; we still have many allowlist entries for types-redisdjango-filter will hardly be unique in its stubs not being quite up to the standard of, say, our stdlib stubs.

For your question (1) — I can't remember off the top of my head what the exact rules are, but unfortunately adding django-stubs and djangorestframework-stubs to the stub_uploader allowlist might not be sufficient to get CI passing here. I think the stub_uploader might also check that all external dependencies listed in the requires field are actually dependencies of the runtime django-filter package, as an additional security check. I might be misremembering, though.

For your question (2), I think we're reasonably open to adding special-casing for specific stubs packages if it means we can run stubtest on them in CI. If you look at tests/stubtest_third_party.py, we already have some special-casing hardcoded into the script so that we can run stubtest on types-uwisgi in CI

@intgr
Copy link
Contributor Author

intgr commented Oct 22, 2023

For your question (1) [...] unfortunately adding django-stubs and djangorestframework-stubs to the stub_uploader allowlist might not be sufficient to get CI passinghere. I think the stub_uploader might also check that all external dependencies listed in the requires field are actually dependencies of the runtime django-filter package

Yep, that's also mentioned in typeshed-internal/stub_uploader#90 (comment)

Ideally these wouldn't be hard dependencies of the pacakge, but would only be installed in CI when testing. But there seems to be no such option currently?

Users of django who want to use types-django-filter are likely to have Django's stubs installed anyway. And if they don't, then types-django-filter is just less useful, but still better than nothing.

There are two different stubs packages for Django: django-stubs and django-types and we shouldn't force that choice.

@github-actions

This comment has been minimized.

@intgr intgr force-pushed the add-types-django-filter branch from 0bc7b19 to 63e9ab6 Compare October 22, 2023 12:45
@github-actions

This comment has been minimized.

@intgr
Copy link
Contributor Author

intgr commented Oct 23, 2023

I think anything else we can fix/improve afterwards, but the stub_uploader error is a blocker: #10919 (comment)

One idea would be to create a new METADATA.toml option e.g. test_requires = [...] that's only used in CI and not subject to the strict checks as requires = [...] is. What do you think?

@AlexWaygood
Copy link
Member

One idea would be to create a new METADATA.toml option e.g. test_requires = [...] that's only used in CI and not subject to the strict checks as requires = [...] is. What do you think?

I'd prefer to avoid doing that, if at all possible. In 99% of cases in typeshed, if an external package is needed to make our tests pass, it's also needed for the stubs to make sense when they're installed by a user. I worry that by adding this option to our METADATA.toml files, we'd encourage people to add "test-only" dependencies which would mean our stubs would start behaving very differently under the conditions of our tests than they actually do when installed by users. We want to avoid that -- we want our tests to represent as closely as possible how our stubs packages behave when they're installed by users.

I believe that if a stubs package from typeshed imports a type that mypy can't resolve (because a dependency is missing), the imported type will just get silently resolved as Any -- mypy won't complain about it! So the user will get no warning that the stubs they installed aren't working as intended.

For the specific case of types-django-filter, maybe it's extremely unlikely that people will have types-django-filter installed without having django-stubs or django-types installed. But... that still feels like a risk I'm not willing to take -- people do crazy things on the internet :)

I'm going to take a look now and see if there are any other ways of solving this problem.

@intgr
Copy link
Contributor Author

intgr commented Apr 9, 2024

Many months have gone past. Has anything changed in terms of introducing a dependency on django-stubs? Or maybe some fresh ideas to solve this blocker?

There are a few other Django-related or djangorestframework-related projects I might want to provide stubs for, but no point in undertaking that work until this blocker has been cleared. And maintaining a 3rd party stubs project outside of typeshed is a bigger commitment than I want to undertake.

This comment has been minimized.

@srittau
Copy link
Collaborator

srittau commented Jul 15, 2024

@intgr Sorry for the long process. I've added the Django stubs to the stub uploader allowlist. I see this as uncritical. There are some type errors now, though.

@intgr
Copy link
Contributor Author

intgr commented Jul 15, 2024

Thanks for helping push this forward.

Note that stub_uploader tests are giving the following error:

E stub_uploader.metadata.InvalidRequires: Expected dependency django-stubs to be listed in django-filter's requires_dist or the sdist's *.egg-info/requires.txt

This blocker was described in typeshed-internal/stub_uploader#111 (comment) / typeshed-internal/stub_uploader#90 (comment)

Do you have an idea what to do about this error? I suspect django-filter upstream will not want to add django-stubs to its dependencies.

@Ganji00
Copy link

Ganji00 commented Jul 26, 2024

@intgr maybe we can try try to make a PR with django-stubs as a dependency to django-filter?

@JelleZijlstra
Copy link
Member

Sorry for the inaction here. I feel we should be able to address this with changes in stub-uploader. (Maybe a rule that if you depend on X at runtime, the stubs may depends on X-stubs, for some trusted values of X?)

This comment has been minimized.

@hamdanal
Copy link
Contributor

Sorry for the inaction here. I feel we should be able to address this with changes in stub-uploader. (Maybe a rule that if you depend on X at runtime, the stubs may depends on X-stubs, for some trusted values of X?)

This has been addressed in typeshed-internal/stub_uploader#152. Perhaps someone can merge main to trigger ci to see if it works.

This comment has been minimized.

@intgr intgr force-pushed the add-types-django-filter branch from 8955f89 to 4e6227a Compare December 22, 2024 18:02
@@ -0,0 +1,3 @@
version = "23.3.*"
upstream_repository = "https://github.com/carltongibson/django-filter"
requires = ["django-stubs", "djangorestframework-stubs"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'd need to remove this to pass the stub_uploader CI. It doesn't look like it is used anywhere in the stubs, not sure why it was included.

Suggested change
requires = ["django-stubs", "djangorestframework-stubs"]
requires = ["django-stubs"]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was used in __init__.pyi: from . import rest_framework as rest_framework. But indeed this is totally unnecessary and is the only usage, removed.

By the way, thanks a lot for improving stub-uploader, and for letting me know about the changes!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was used in __init__.pyi: from . import rest_framework as rest_framework. But indeed this is totally unnecessary and is the only usage, removed.

This looks like a locally defined module named rest_framework, not the djangorestframework package. I don't think it should be removed.

By the way, thanks a lot for improving stub-uploader, and for letting me know about the changes!

Thank you and thanks for working on django stubs!

Copy link
Contributor Author

@intgr intgr Dec 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a locally defined module named rest_framework

Ah right you are!

I don't think it should be removed.

I don't think it does anything. It's re-exporting the module django_filter.rest_framework in django_filter/__init__.py that is already available under the exact same module path? 😄

Copy link
Contributor

@hamdanal hamdanal Dec 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it does anything. It's re-exporting the module django_filter.rest_framework in django_filter/__init__.py that is already available under the exact same module path? 😄

If you remove it then this will not work (at least with pyright):

import django_filters
django_filters.rest_framework  # <- this will be a type error and would not have autocompletion in VS Code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@intgr I still think the the removed from . import rest_framework as rest_framework must be restored. It is deliberately imported at runtime for the specific reason that would let pyright accept the code snippet I mentioned above, i.e. to avoid having to type import django_fiters.rest_framework.

See the comment here:
https://github.com/carltongibson/django-filter/blob/2494df96c6387a9fa411fcb00b696b15dfd9216b/django_filters/__init__.py#L7-L10

Copy link
Contributor Author

@intgr intgr Dec 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's silly and nobody should use it like that. The documentation and tests don't use it that way either.

But if you feel strongly about this, fair enough, I've restored it.

This comment has been minimized.

@intgr intgr force-pushed the add-types-django-filter branch from 4e6227a to dfe1fbe Compare December 22, 2024 18:14
@intgr
Copy link
Contributor Author

intgr commented Dec 22, 2024

It's a mystery to me, why Pyright fails on this file (only with older Pythons)... I didn't even touch it 😄

/home/runner/work/typeshed/typeshed/stubs/setuptools/setuptools/compat/py310.pyi:9:81 - error: Unnecessary "# pyright: ignore" rule: "reportMissingImports" (reportUnnecessaryTypeIgnoreComment)

This comment has been minimized.

@AlexWaygood
Copy link
Member

It's a mystery to me, why Pyright fails on this file (only with older Pythons)... I didn't even touch it 😄

#13101 (comment)

@AlexWaygood
Copy link
Member

See also my suggested solution for the pyright issue: #13101 (comment)

(But it should be done in a separate PR to this one)

@hamdanal
Copy link
Contributor

See also my suggested solution for the pyright issue: #13101 (comment)

(But it should be done in a separate PR to this one)

#13280

@intgr intgr force-pushed the add-types-django-filter branch from dfe1fbe to db7df55 Compare December 22, 2024 20:10

This comment has been minimized.

@intgr
Copy link
Contributor Author

intgr commented Dec 22, 2024

Nice, this now passes CI.

As a reminder, Please don't use squash merge to merge this (unless there's explicit decision to reconsider #10918). I have preserved original commit authors in the commits here.

@intgr intgr force-pushed the add-types-django-filter branch from db7df55 to 4f00327 Compare December 22, 2024 20:35
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: absorb django-filter-stubs into typeshed Consider move the repo to typeshed?
9 participants