MCPcopy Index your code
hub / github.com/python/mypy / TypedDictAnalyzer

Class TypedDictAnalyzer

mypy/semanal_typeddict.py:62–631  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

60
61
62class TypedDictAnalyzer:
63 def __init__(
64 self, options: Options, api: SemanticAnalyzerInterface, msg: MessageBuilder
65 ) -> None:
66 self.options = options
67 self.api = api
68 self.msg = msg
69
70 def analyze_typeddict_classdef(self, defn: ClassDef) -> tuple[bool, TypeInfo | None]:
71 """Analyze a class that may define a TypedDict.
72
73 Assume that base classes have been analyzed already.
74
75 Note: Unlike normal classes, we won't create a TypeInfo until
76 the whole definition of the TypeDict (including the body and all
77 key names and types) is complete. This is mostly because we
78 store the corresponding TypedDictType in the TypeInfo.
79
80 Return (is this a TypedDict, new TypeInfo). Specifics:
81 * If we couldn't finish due to incomplete reference anywhere in
82 the definition, return (True, None).
83 * If this is not a TypedDict, return (False, None).
84 """
85 possible = False
86 for base_expr in defn.base_type_exprs:
87 if isinstance(base_expr, CallExpr):
88 base_expr = base_expr.callee
89 if isinstance(base_expr, IndexExpr):
90 base_expr = base_expr.base
91 if isinstance(base_expr, RefExpr):
92 self.api.accept(base_expr)
93 if base_expr.fullname in TPDICT_NAMES or self.is_typeddict(base_expr):
94 possible = True
95 if isinstance(base_expr.node, TypeInfo) and base_expr.node.is_final:
96 err = message_registry.CANNOT_INHERIT_FROM_FINAL
97 self.fail(err.format(base_expr.node.name).value, defn, code=err.code)
98 if not possible:
99 return False, None
100 existing_info = None
101 if isinstance(defn.analyzed, TypedDictExpr):
102 existing_info = defn.analyzed.info
103
104 field_types: dict[str, Type] | None
105 if (
106 len(defn.base_type_exprs) == 1
107 and isinstance(defn.base_type_exprs[0], RefExpr)
108 and defn.base_type_exprs[0].fullname in TPDICT_NAMES
109 ):
110 # Building a new TypedDict
111 field_types, statements, required_keys, readonly_keys = (
112 self.analyze_typeddict_classdef_fields(defn)
113 )
114 if field_types is None:
115 return True, None # Defer
116 if self.api.is_func_scope() and "@" not in defn.name:
117 defn.name += "@" + str(defn.line)
118 info = self.build_typeddict_typeinfo(
119 defn.name, field_types, required_keys, readonly_keys, defn.line, existing_info

Callers 1

file_contextMethod · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…