1212import mypy .checkexpr
1313from mypy import errorcodes as codes , join , message_registry , nodes , operators
1414from mypy .binder import ConditionalTypeBinder , Frame , get_declaration
15+ from mypy .checker_shared import CheckerScope , TypeCheckerSharedApi , TypeRange
1516from mypy .checkmember import (
1617 MemberContext ,
1718 analyze_class_attribute_access ,
126127from mypy .operators import flip_ops , int_op_to_method , neg_ops
127128from mypy .options import PRECISE_TUPLE_TYPES , Options
128129from mypy .patterns import AsPattern , StarredPattern
129- from mypy .plugin import CheckerPluginInterface , Plugin
130+ from mypy .plugin import Plugin
130131from mypy .plugins import dataclasses as dataclasses_plugin
131132from mypy .scope import Scope
132133from mypy .semanal import is_trivial_body , refers_to_fullname , set_callable_name
@@ -258,13 +259,6 @@ class FineGrainedDeferredNode(NamedTuple):
258259TypeMap : _TypeAlias = Optional [dict [Expression , Type ]]
259260
260261
261- # An object that represents either a precise type or a type with an upper bound;
262- # it is important for correct type inference with isinstance.
263- class TypeRange (NamedTuple ):
264- item : Type
265- is_upper_bound : bool # False => precise type
266-
267-
268262# Keeps track of partial types in a single scope. In fine-grained incremental
269263# mode partial types initially defined at the top level cannot be completed in
270264# a function, and we use the 'is_function' attribute to enforce this.
@@ -274,7 +268,7 @@ class PartialTypeScope(NamedTuple):
274268 is_local : bool
275269
276270
277- class TypeChecker (NodeVisitor [None ], CheckerPluginInterface ):
271+ class TypeChecker (NodeVisitor [None ], TypeCheckerSharedApi ):
278272 """Mypy type checker.
279273
280274 Type check mypy source files that have been semantically analyzed.
@@ -301,7 +295,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
301295 # Helper for managing conditional types
302296 binder : ConditionalTypeBinder
303297 # Helper for type checking expressions
304- expr_checker : mypy .checkexpr .ExpressionChecker
298+ _expr_checker : mypy .checkexpr .ExpressionChecker
305299
306300 pattern_checker : PatternChecker
307301
@@ -416,14 +410,18 @@ def __init__(
416410 self .allow_abstract_call = False
417411
418412 # Child checker objects for specific AST node types
419- self .expr_checker = mypy .checkexpr .ExpressionChecker (
413+ self ._expr_checker = mypy .checkexpr .ExpressionChecker (
420414 self , self .msg , self .plugin , per_line_checking_time_ns
421415 )
422416 self .pattern_checker = PatternChecker (self , self .msg , self .plugin , options )
423417
418+ @property
419+ def expr_checker (self ) -> mypy .checkexpr .ExpressionChecker :
420+ return self ._expr_checker
421+
424422 @property
425423 def type_context (self ) -> list [Type | None ]:
426- return self .expr_checker .type_context
424+ return self ._expr_checker .type_context
427425
428426 def reset (self ) -> None :
429427 """Cleanup stale state that might be left over from a typechecking run.
@@ -8527,75 +8525,6 @@ def is_node_static(node: Node | None) -> bool | None:
85278525 return None
85288526
85298527
8530- class CheckerScope :
8531- # We keep two stacks combined, to maintain the relative order
8532- stack : list [TypeInfo | FuncItem | MypyFile ]
8533-
8534- def __init__ (self , module : MypyFile ) -> None :
8535- self .stack = [module ]
8536-
8537- def current_function (self ) -> FuncItem | None :
8538- for e in reversed (self .stack ):
8539- if isinstance (e , FuncItem ):
8540- return e
8541- return None
8542-
8543- def top_level_function (self ) -> FuncItem | None :
8544- """Return top-level non-lambda function."""
8545- for e in self .stack :
8546- if isinstance (e , FuncItem ) and not isinstance (e , LambdaExpr ):
8547- return e
8548- return None
8549-
8550- def active_class (self ) -> TypeInfo | None :
8551- if isinstance (self .stack [- 1 ], TypeInfo ):
8552- return self .stack [- 1 ]
8553- return None
8554-
8555- def enclosing_class (self , func : FuncItem | None = None ) -> TypeInfo | None :
8556- """Is there a class *directly* enclosing this function?"""
8557- func = func or self .current_function ()
8558- assert func , "This method must be called from inside a function"
8559- index = self .stack .index (func )
8560- assert index , "CheckerScope stack must always start with a module"
8561- enclosing = self .stack [index - 1 ]
8562- if isinstance (enclosing , TypeInfo ):
8563- return enclosing
8564- return None
8565-
8566- def active_self_type (self ) -> Instance | TupleType | None :
8567- """An instance or tuple type representing the current class.
8568-
8569- This returns None unless we are in class body or in a method.
8570- In particular, inside a function nested in method this returns None.
8571- """
8572- info = self .active_class ()
8573- if not info and self .current_function ():
8574- info = self .enclosing_class ()
8575- if info :
8576- return fill_typevars (info )
8577- return None
8578-
8579- def current_self_type (self ) -> Instance | TupleType | None :
8580- """Same as active_self_type() but handle functions nested in methods."""
8581- for item in reversed (self .stack ):
8582- if isinstance (item , TypeInfo ):
8583- return fill_typevars (item )
8584- return None
8585-
8586- @contextmanager
8587- def push_function (self , item : FuncItem ) -> Iterator [None ]:
8588- self .stack .append (item )
8589- yield
8590- self .stack .pop ()
8591-
8592- @contextmanager
8593- def push_class (self , info : TypeInfo ) -> Iterator [None ]:
8594- self .stack .append (info )
8595- yield
8596- self .stack .pop ()
8597-
8598-
85998528TKey = TypeVar ("TKey" )
86008529TValue = TypeVar ("TValue" )
86018530
0 commit comments