Skip to content

Move is_defined_in_stub to shared checker API to break import cycle #19417

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

Merged
merged 1 commit into from
Jul 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7889,6 +7889,9 @@ def has_valid_attribute(self, typ: Type, name: str) -> bool:
def get_expression_type(self, node: Expression, type_context: Type | None = None) -> Type:
return self.expr_checker.accept(node, type_context=type_context)

def is_defined_in_stub(self, typ: Instance, /) -> bool:
return self.modules[typ.type.module_name].is_stub

def check_deprecated(self, node: Node | None, context: Context) -> None:
"""Warn if deprecated and not directly imported with a `from` statement."""
if isinstance(node, Decorator):
Expand Down
4 changes: 4 additions & 0 deletions mypy/checker_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ def checking_await_set(self) -> Iterator[None]:
def get_precise_awaitable_type(self, typ: Type, local_errors: ErrorWatcher) -> Type | None:
raise NotImplementedError

@abstractmethod
def is_defined_in_stub(self, typ: Instance, /) -> bool:
raise NotImplementedError


class CheckerScope:
# We keep two stacks combined, to maintain the relative order
Expand Down
6 changes: 3 additions & 3 deletions mypy/plugins/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from typing import TypeVar, cast

import mypy.plugin # To avoid circular imports.
from mypy.checker import TypeChecker
from mypy.checker_shared import TypeCheckerSharedApi
from mypy.nodes import TypeInfo, Var
from mypy.subtypes import is_equivalent
from mypy.typeops import fixup_partial_type, make_simplified_union
Expand Down Expand Up @@ -122,8 +122,8 @@ def _infer_value_type_with_auto_fallback(


def _is_defined_in_stub(ctx: mypy.plugin.AttributeContext) -> bool:
assert isinstance(ctx.api, TypeChecker)
return isinstance(ctx.type, Instance) and ctx.api.modules[ctx.type.type.module_name].is_stub
assert isinstance(ctx.api, TypeCheckerSharedApi)
return isinstance(ctx.type, Instance) and ctx.api.is_defined_in_stub(ctx.type)


def _implements_new(info: TypeInfo) -> bool:
Expand Down