(self, node: Decorator)
| 654 | return modname, node |
| 655 | |
| 656 | def extract_from_decorator(self, node: Decorator) -> FuncDef | None: |
| 657 | for dec in node.decorators: |
| 658 | typ = None |
| 659 | if isinstance(dec, RefExpr) and isinstance(dec.node, (Var, FuncDef)): |
| 660 | typ = get_proper_type(dec.node.type) |
| 661 | elif ( |
| 662 | isinstance(dec, CallExpr) |
| 663 | and isinstance(dec.callee, RefExpr) |
| 664 | and isinstance(dec.callee.node, (Decorator, FuncDef, Var)) |
| 665 | and isinstance((call_tp := get_proper_type(dec.callee.node.type)), CallableType) |
| 666 | ): |
| 667 | typ = get_proper_type(call_tp.ret_type) |
| 668 | |
| 669 | if isinstance(typ, Instance): |
| 670 | call_method = typ.type.get_method("__call__") |
| 671 | if isinstance(call_method, FuncDef) and isinstance(call_method.type, FunctionLike): |
| 672 | typ = bind_self(call_method.type, None) |
| 673 | |
| 674 | if not isinstance(typ, FunctionLike): |
| 675 | return None |
| 676 | for ct in typ.items: |
| 677 | if not ( |
| 678 | len(ct.arg_types) == 1 |
| 679 | and _arg_accepts_function(get_proper_type(ct.arg_types[0])) |
| 680 | and ct.arg_types[0] == ct.ret_type |
| 681 | ): |
| 682 | return None |
| 683 | |
| 684 | return node.func |
| 685 | |
| 686 | def try_type(self, func: FuncDef, typ: ProperType) -> list[str]: |
| 687 | """Recheck a function while assuming it has type typ. |
no test coverage detected