|
130 | 130 | WhileStmt,
|
131 | 131 | WithStmt,
|
132 | 132 | YieldExpr,
|
| 133 | + get_func_def, |
133 | 134 | is_final_node,
|
134 | 135 | )
|
135 | 136 | from mypy.operators import flip_ops, int_op_to_method, neg_ops
|
@@ -703,6 +704,12 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
|
703 | 704 | # TODO: keep precise type for callables with tricky but valid signatures.
|
704 | 705 | setter_type = fallback_setter_type
|
705 | 706 | defn.items[0].var.setter_type = setter_type
|
| 707 | + if isinstance(defn.type, Overloaded): |
| 708 | + # Update legacy property type for decorated properties. |
| 709 | + getter_type = self.extract_callable_type(defn.items[0].var.type, defn) |
| 710 | + if getter_type is not None: |
| 711 | + getter_type.definition = defn.items[0] |
| 712 | + defn.type.items[0] = getter_type |
706 | 713 | for i, fdef in enumerate(defn.items):
|
707 | 714 | assert isinstance(fdef, Decorator)
|
708 | 715 | if defn.is_property:
|
@@ -730,7 +737,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
|
730 | 737 | assert isinstance(item, Decorator)
|
731 | 738 | item_type = self.extract_callable_type(item.var.type, item)
|
732 | 739 | if item_type is not None:
|
733 |
| - item_type.definition = item.func |
| 740 | + item_type.definition = item |
734 | 741 | item_types.append(item_type)
|
735 | 742 | if item_types:
|
736 | 743 | defn.type = Overloaded(item_types)
|
@@ -2501,8 +2508,9 @@ def check_override(
|
2501 | 2508 |
|
2502 | 2509 | override_ids = override.type_var_ids()
|
2503 | 2510 | type_name = None
|
2504 |
| - if isinstance(override.definition, FuncDef): |
2505 |
| - type_name = override.definition.info.name |
| 2511 | + definition = get_func_def(override) |
| 2512 | + if isinstance(definition, FuncDef): |
| 2513 | + type_name = definition.info.name |
2506 | 2514 |
|
2507 | 2515 | def erase_override(t: Type) -> Type:
|
2508 | 2516 | return erase_typevars(t, ids_to_erase=override_ids)
|
@@ -3509,6 +3517,7 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
|
3509 | 3517 | continue
|
3510 | 3518 |
|
3511 | 3519 | base_type, base_node = self.node_type_from_base(lvalue_node.name, base, lvalue)
|
| 3520 | + # TODO: if the r.h.s. is a descriptor, we should check setter override as well. |
3512 | 3521 | custom_setter = is_custom_settable_property(base_node)
|
3513 | 3522 | if isinstance(base_type, PartialType):
|
3514 | 3523 | base_type = None
|
@@ -4494,6 +4503,8 @@ def set_inferred_type(self, var: Var, lvalue: Lvalue, type: Type) -> None:
|
4494 | 4503 | if isinstance(p_type, Overloaded):
|
4495 | 4504 | # TODO: in theory we can have a property with a deleter only.
|
4496 | 4505 | var.is_settable_property = True
|
| 4506 | + assert isinstance(definition, Decorator), definition |
| 4507 | + var.setter_type = definition.var.setter_type |
4497 | 4508 |
|
4498 | 4509 | def set_inference_error_fallback_type(self, var: Var, lvalue: Lvalue, type: Type) -> None:
|
4499 | 4510 | """Store best known type for variable if type inference failed.
|
@@ -5356,6 +5367,8 @@ def visit_decorator_inner(
|
5356 | 5367 | self.check_untyped_after_decorator(sig, e.func)
|
5357 | 5368 | self.require_correct_self_argument(sig, e.func)
|
5358 | 5369 | sig = set_callable_name(sig, e.func)
|
| 5370 | + if isinstance(sig, CallableType): |
| 5371 | + sig.definition = e |
5359 | 5372 | e.var.type = sig
|
5360 | 5373 | e.var.is_ready = True
|
5361 | 5374 | if e.func.is_property:
|
@@ -8654,17 +8667,21 @@ def visit_type_alias_type(self, t: TypeAliasType) -> Type:
|
8654 | 8667 | return t.copy_modified(args=[a.accept(self) for a in t.args])
|
8655 | 8668 |
|
8656 | 8669 |
|
8657 |
| -def is_classmethod_node(node: Node | None) -> bool | None: |
| 8670 | +def is_classmethod_node(node: SymbolNode | None) -> bool | None: |
8658 | 8671 | """Find out if a node describes a classmethod."""
|
| 8672 | + if isinstance(node, Decorator): |
| 8673 | + node = node.func |
8659 | 8674 | if isinstance(node, FuncDef):
|
8660 | 8675 | return node.is_class
|
8661 | 8676 | if isinstance(node, Var):
|
8662 | 8677 | return node.is_classmethod
|
8663 | 8678 | return None
|
8664 | 8679 |
|
8665 | 8680 |
|
8666 |
| -def is_node_static(node: Node | None) -> bool | None: |
| 8681 | +def is_node_static(node: SymbolNode | None) -> bool | None: |
8667 | 8682 | """Find out if a node describes a static function method."""
|
| 8683 | + if isinstance(node, Decorator): |
| 8684 | + node = node.func |
8668 | 8685 | if isinstance(node, FuncDef):
|
8669 | 8686 | return node.is_static
|
8670 | 8687 | if isinstance(node, Var):
|
|
0 commit comments