12
12
import mypy .checkexpr
13
13
from mypy import errorcodes as codes , join , message_registry , nodes , operators
14
14
from mypy .binder import ConditionalTypeBinder , Frame , get_declaration
15
+ from mypy .checker_shared import CheckerScope , TypeCheckerSharedApi , TypeRange
15
16
from mypy .checkmember import (
16
17
MemberContext ,
17
18
analyze_class_attribute_access ,
126
127
from mypy .operators import flip_ops , int_op_to_method , neg_ops
127
128
from mypy .options import PRECISE_TUPLE_TYPES , Options
128
129
from mypy .patterns import AsPattern , StarredPattern
129
- from mypy .plugin import CheckerPluginInterface , Plugin
130
+ from mypy .plugin import Plugin
130
131
from mypy .plugins import dataclasses as dataclasses_plugin
131
132
from mypy .scope import Scope
132
133
from mypy .semanal import is_trivial_body , refers_to_fullname , set_callable_name
@@ -258,13 +259,6 @@ class FineGrainedDeferredNode(NamedTuple):
258
259
TypeMap : _TypeAlias = Optional [dict [Expression , Type ]]
259
260
260
261
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
-
268
262
# Keeps track of partial types in a single scope. In fine-grained incremental
269
263
# mode partial types initially defined at the top level cannot be completed in
270
264
# a function, and we use the 'is_function' attribute to enforce this.
@@ -274,7 +268,7 @@ class PartialTypeScope(NamedTuple):
274
268
is_local : bool
275
269
276
270
277
- class TypeChecker (NodeVisitor [None ], CheckerPluginInterface ):
271
+ class TypeChecker (NodeVisitor [None ], TypeCheckerSharedApi ):
278
272
"""Mypy type checker.
279
273
280
274
Type check mypy source files that have been semantically analyzed.
@@ -301,7 +295,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
301
295
# Helper for managing conditional types
302
296
binder : ConditionalTypeBinder
303
297
# Helper for type checking expressions
304
- expr_checker : mypy .checkexpr .ExpressionChecker
298
+ _expr_checker : mypy .checkexpr .ExpressionChecker
305
299
306
300
pattern_checker : PatternChecker
307
301
@@ -416,14 +410,18 @@ def __init__(
416
410
self .allow_abstract_call = False
417
411
418
412
# Child checker objects for specific AST node types
419
- self .expr_checker = mypy .checkexpr .ExpressionChecker (
413
+ self ._expr_checker = mypy .checkexpr .ExpressionChecker (
420
414
self , self .msg , self .plugin , per_line_checking_time_ns
421
415
)
422
416
self .pattern_checker = PatternChecker (self , self .msg , self .plugin , options )
423
417
418
+ @property
419
+ def expr_checker (self ) -> mypy .checkexpr .ExpressionChecker :
420
+ return self ._expr_checker
421
+
424
422
@property
425
423
def type_context (self ) -> list [Type | None ]:
426
- return self .expr_checker .type_context
424
+ return self ._expr_checker .type_context
427
425
428
426
def reset (self ) -> None :
429
427
"""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:
8527
8525
return None
8528
8526
8529
8527
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
-
8599
8528
TKey = TypeVar ("TKey" )
8600
8529
TValue = TypeVar ("TValue" )
8601
8530
0 commit comments