Type check lambda expression.
(self, e: LambdaExpr)
| 5574 | return AnyType(TypeOfAny.from_error) |
| 5575 | |
| 5576 | def visit_lambda_expr(self, e: LambdaExpr) -> Type: |
| 5577 | """Type check lambda expression.""" |
| 5578 | old_in_lambda = self.in_lambda_expr |
| 5579 | self.in_lambda_expr = True |
| 5580 | self.chk.check_default_params(e, body_is_trivial=False) |
| 5581 | inferred_type, type_override = self.infer_lambda_type_using_context(e) |
| 5582 | if not inferred_type: |
| 5583 | self.chk.return_types.append(AnyType(TypeOfAny.special_form)) |
| 5584 | # Type check everything in the body except for the final return |
| 5585 | # statement (it can contain tuple unpacking before return). |
| 5586 | with ( |
| 5587 | self.chk.binder.frame_context(can_skip=True, fall_through=0), |
| 5588 | self.chk.scope.push_function(e), |
| 5589 | ): |
| 5590 | # If in empty context, reset argument types (from previous passes), |
| 5591 | # in the other branch argument types are set by check_func_def(). |
| 5592 | for arg in e.arguments: |
| 5593 | arg.variable.type = None |
| 5594 | # Lambdas can have more than one element in body, |
| 5595 | # when we add "fictional" AssignmentStatement nodes, like in: |
| 5596 | # `lambda (a, b): a` |
| 5597 | for stmt in e.body.body[:-1]: |
| 5598 | stmt.accept(self.chk) |
| 5599 | # Only type check the return expression, not the return statement. |
| 5600 | # There's no useful type context. |
| 5601 | ret_type = self.accept(e.expr(), allow_none_return=True) |
| 5602 | fallback = self.named_type("builtins.function") |
| 5603 | self.chk.return_types.pop() |
| 5604 | self.in_lambda_expr = old_in_lambda |
| 5605 | return callable_type(e, fallback, ret_type) |
| 5606 | else: |
| 5607 | # Type context available. |
| 5608 | self.chk.return_types.append(inferred_type.ret_type) |
| 5609 | with self.chk.tscope.function_scope(e): |
| 5610 | self.chk.check_func_item(e, type_override=type_override) |
| 5611 | if not self.chk.has_type(e.expr()): |
| 5612 | # TODO: return expression must be accepted before exiting function scope. |
| 5613 | with self.chk.binder.frame_context(can_skip=True, fall_through=0): |
| 5614 | self.accept(e.expr(), allow_none_return=True) |
| 5615 | ret_type = self.chk.lookup_type(e.expr()) |
| 5616 | self.chk.return_types.pop() |
| 5617 | self.in_lambda_expr = old_in_lambda |
| 5618 | return replace_callable_return_type(inferred_type, ret_type) |
| 5619 | |
| 5620 | def infer_lambda_type_using_context( |
| 5621 | self, e: LambdaExpr |
nothing calls this directly
no test coverage detected