Process a series of decorators. Only preserve certain special decorators such as @abstractmethod.
(self, o: Decorator)
| 762 | self.visit_func_def(o.func) |
| 763 | |
| 764 | def process_decorator(self, o: Decorator) -> None: |
| 765 | """Process a series of decorators. |
| 766 | |
| 767 | Only preserve certain special decorators such as @abstractmethod. |
| 768 | """ |
| 769 | o.func.is_overload = False |
| 770 | for decorator in o.original_decorators: |
| 771 | d = decorator |
| 772 | if isinstance(d, CallExpr): |
| 773 | d = d.callee |
| 774 | if not isinstance(d, (NameExpr, MemberExpr)): |
| 775 | continue |
| 776 | qualname = get_qualified_name(d) |
| 777 | fullname = self.get_fullname(d) |
| 778 | if fullname in ( |
| 779 | "builtins.property", |
| 780 | "builtins.staticmethod", |
| 781 | "builtins.classmethod", |
| 782 | "functools.cached_property", |
| 783 | ): |
| 784 | self.add_decorator(qualname, require_name=True) |
| 785 | elif fullname in ( |
| 786 | "asyncio.coroutine", |
| 787 | "asyncio.coroutines.coroutine", |
| 788 | "types.coroutine", |
| 789 | ): |
| 790 | o.func.is_awaitable_coroutine = True |
| 791 | self.add_decorator(qualname, require_name=True) |
| 792 | elif fullname == "abc.abstractmethod": |
| 793 | self.add_decorator(qualname, require_name=True) |
| 794 | o.func.abstract_status = IS_ABSTRACT |
| 795 | elif fullname in ( |
| 796 | "abc.abstractproperty", |
| 797 | "abc.abstractstaticmethod", |
| 798 | "abc.abstractclassmethod", |
| 799 | ): |
| 800 | abc_module = qualname.rpartition(".")[0] |
| 801 | if not abc_module: |
| 802 | self.import_tracker.add_import("abc") |
| 803 | builtin_decorator_replacement = fullname[len("abc.abstract") :] |
| 804 | self.add_decorator(builtin_decorator_replacement, require_name=False) |
| 805 | self.add_decorator(f"{abc_module or 'abc'}.abstractmethod", require_name=True) |
| 806 | o.func.abstract_status = IS_ABSTRACT |
| 807 | elif fullname in OVERLOAD_NAMES: |
| 808 | self.add_decorator(qualname, require_name=True) |
| 809 | o.func.is_overload = True |
| 810 | elif qualname.endswith((".setter", ".deleter")): |
| 811 | self.add_decorator(qualname, require_name=False) |
| 812 | elif fullname in DATACLASS_TRANSFORM_NAMES: |
| 813 | p = AliasPrinter(self) |
| 814 | self._decorators.append(f"@{decorator.accept(p)}") |
| 815 | elif isinstance(decorator, (NameExpr, MemberExpr)): |
| 816 | p = AliasPrinter(self) |
| 817 | self._decorators.append(f"@{decorator.accept(p)}") |
| 818 | |
| 819 | def get_fullname(self, expr: Expression) -> str: |
| 820 | """Return the expression's full name.""" |
no test coverage detected