diff --git a/src/pluggy/_manager.py b/src/pluggy/_manager.py index a52044f0..979d2d63 100644 --- a/src/pluggy/_manager.py +++ b/src/pluggy/_manager.py @@ -191,11 +191,15 @@ def parse_hookimpl_opts(self, plugin: _Plugin, name: str) -> HookimplOpts | None # pydantic model fields are like attrs and also can never be hookimpls plugin_is_pydantic_obj = hasattr(plugin, "__pydantic_core_schema__") if plugin_is_pydantic_obj and name in getattr(plugin, "model_fields", {}): - # pydantic models mess with the class and attr __signature__ - # so inspect.isroutine(...) throws exceptions and cant be used return None - method: object = getattr(plugin, name) + try: + method: object = getattr(plugin, name) + except AttributeError: + # AttributeError: '__signature__' attribute of 'Plugin' is class-only + # can happen for some special objects (e.g. proxies, pydantic, etc.) + method: object = getattr(type(plugin), name) # use class sig instead + if not inspect.isroutine(method): return None try: