Type check a node in the given type context. If allow_none_return is True and this expression is a call, allow it to return None. This applies only to this expression and not any subexpressions.
(
self,
node: Expression,
type_context: Type | None = None,
allow_none_return: bool = False,
always_allow_any: bool = False,
is_callee: bool = False,
)
| 6090 | # |
| 6091 | |
| 6092 | def accept( |
| 6093 | self, |
| 6094 | node: Expression, |
| 6095 | type_context: Type | None = None, |
| 6096 | allow_none_return: bool = False, |
| 6097 | always_allow_any: bool = False, |
| 6098 | is_callee: bool = False, |
| 6099 | ) -> Type: |
| 6100 | """Type check a node in the given type context. If allow_none_return |
| 6101 | is True and this expression is a call, allow it to return None. This |
| 6102 | applies only to this expression and not any subexpressions. |
| 6103 | """ |
| 6104 | if node in self.type_overrides: |
| 6105 | # This branch is very fast, there is no point timing it. |
| 6106 | return self.type_overrides[node] |
| 6107 | # We don't use context manager here to get most precise data (and avoid overhead). |
| 6108 | record_time = False |
| 6109 | if self.collect_line_checking_stats and not self.in_expression: |
| 6110 | t0 = time.perf_counter_ns() |
| 6111 | self.in_expression = True |
| 6112 | record_time = True |
| 6113 | self.type_context.append(type_context) |
| 6114 | old_is_callee = self.is_callee |
| 6115 | self.is_callee = is_callee |
| 6116 | try: |
| 6117 | p_type_context = get_proper_type(type_context) |
| 6118 | if allow_none_return and isinstance(node, CallExpr): |
| 6119 | typ = self.visit_call_expr(node, allow_none_return=True) |
| 6120 | elif allow_none_return and isinstance(node, YieldFromExpr): |
| 6121 | typ = self.visit_yield_from_expr(node, allow_none_return=True) |
| 6122 | elif allow_none_return and isinstance(node, ConditionalExpr): |
| 6123 | typ = self.visit_conditional_expr(node, allow_none_return=True) |
| 6124 | elif allow_none_return and isinstance(node, AwaitExpr): |
| 6125 | typ = self.visit_await_expr(node, allow_none_return=True) |
| 6126 | |
| 6127 | elif ( |
| 6128 | isinstance(p_type_context, TypeType) |
| 6129 | and p_type_context.is_type_form |
| 6130 | and (node_as_type := self.try_parse_as_type_expression(node)) is not None |
| 6131 | ): |
| 6132 | typ = TypeType.make_normalized( |
| 6133 | node_as_type, |
| 6134 | line=node_as_type.line, |
| 6135 | column=node_as_type.column, |
| 6136 | is_type_form=True, |
| 6137 | ) # r-value type, when interpreted as a type expression |
| 6138 | elif ( |
| 6139 | isinstance(p_type_context, UnionType) |
| 6140 | and any( |
| 6141 | isinstance(p_item := get_proper_type(item), TypeType) and p_item.is_type_form |
| 6142 | for item in p_type_context.items |
| 6143 | ) |
| 6144 | and (node_as_type := self.try_parse_as_type_expression(node)) is not None |
| 6145 | ): |
| 6146 | typ1 = TypeType.make_normalized( |
| 6147 | node_as_type, |
| 6148 | line=node_as_type.line, |
| 6149 | column=node_as_type.column, |
no test coverage detected