-
-
Notifications
You must be signed in to change notification settings - Fork 454
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
Increase priority of mypy internal Django settings import #2127
Increase priority of mypy internal Django settings import #2127
Conversation
reveal_type(settings.CIRCULAR_WITHOUT_HINT) # E: Import cycle from Django settings module prevents type inference for 'CIRCULAR_WITHOUT_HINT' [misc] # N: Revealed type is "Any" | ||
reveal_type(settings.CIRCULAR_WITHOUT_HINT) # N: Revealed type is "builtins.int" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can come up with another test case that produces the "Import cycle from Django settings module prevents type inference" error?
Would be nice to have test coverage for this code still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, agreed but I'm not sure what that test could look like either.
If I've read the plugin code correctly it only interferes when the type checking haven't inferred a type of the settings module at the stage where plugin is invoked.
I tried importing like import django.conf
, since that seemed to have lower priority. Then I get the error, but I'm not sure if that could be because get_additional_deps
doesn't consider that style of importing properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking again I don't think it's anything with get_additional_deps
. Perhaps that's enough to add for now at least.
All I did was to keep the test_setting_circular_import
test case and change from django.conf import settings
to import django.conf
.
Perhaps you could add that case to the suite in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, updated the testcase as you suggested, thanks!
IMMEDIATE_VALUE = 123 | ||
CIRCULAR_WITH_HINT: int = function_returning_int() | ||
CIRCULAR_WITHOUT_HINT_FUNCTION = function_returning_int() | ||
CIRCULAR_WITHOUT_HINT_CONST = const_with_circular_import # E: Cannot determine type of "const_with_circular_import" [has-type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I managed to coax a different error out of mypy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, I think that's totally unresolvable for mypy since there's no type hint involved at all for the type checker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right, it used settings.IMMEDIATE_VALUE
. Then there's actually a chance for it to figure it out
idk what to do with this but it seems to help my case at least $ git diff
diff --git a/mypy_django_plugin/transformers/settings.py b/mypy_django_plugin/transformers/settings.py
index f821b971..61d50617 100644
--- a/mypy_django_plugin/transformers/settings.py
+++ b/mypy_django_plugin/transformers/settings.py
@@ -38,10 +38,7 @@ def get_type_of_settings_attribute(
sym = module.names.get(setting_name)
if sym is not None:
if sym.type is None:
- ctx.api.fail(
- f"Import cycle from Django settings module prevents type inference for {setting_name!r}",
- ctx.context,
- )
+ typechecker_api.handle_cannot_determine_type(setting_name, ctx.context)
return ctx.default_attr_type
return sym.type
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we should add the test I mentioned?
It's fine for me to merge this as is
We could investigate I'm not familiar with it either though |
Cool, indeed @asottile-sentry's suggestion fixes the root cause of the issue, by deferring the analysis to a later pass. def handle_cannot_determine_type(self, name: str, context: Context) -> None:
node = self.scope.top_non_lambda_function()
if self.pass_num < self.last_pass and isinstance(node, FuncDef):
# Don't report an error yet. Just defer. Note that we don't defer
# lambdas because they are coupled to the surrounding function
# through the binder and the inferred type of the lambda, so it
# would get messy. But I think it's still useful to increase the priority of settings import, as this reduces the number of passes mypy needs to make and hopefully speeds things up. Apparently it's not a rare case. For the sake of clear git history, let's merge this and then |
fwiw I needed both of the improvements to make sentry's cycle warnings go away -- though we have some pretty badly cyclic stuff :/ |
It seems that |
UGH! We have a catch-22. This actually regresses one of my projects where one settings file imports a "base" config file Changing |
seems fine with that yeah, PRI_MYPY is too low though |
As discussed in #2097 (reply in thread):
PRI_MYPY
inget_additional_deps
hook #2024.PRI_HIGH
level.Related issues