mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-04 23:17:20 +08:00
fix: 插件重载窗口期装饰器包装类方法误判直调导致 missing event TypeError
事件绑定解析在 owner_class 为 None 时仅靠限定名区分自由函数与类方法声明, 装饰器包装的方法限定名含 <locals> 被误判为自由函数 unbound 直调,把 event 吞进 self 触发 TypeError。局部作用域限定名无法区分包装方法与局部自由函数, 按调用约定兜底:签名首参为 self/cls 才视为类方法声明跳过执行。
This commit is contained in:
@@ -59,9 +59,27 @@ class EventBindingResolver:
|
||||
|
||||
@staticmethod
|
||||
def is_class_method_declaration(handler: Callable) -> bool:
|
||||
"""判断处理器是否声明在类体内(限定名含类前缀且非局部闭包)。"""
|
||||
"""判断处理器是否声明在类体内(限定名含类前缀或签名首参为 self/cls)。
|
||||
|
||||
模块级顶层自由函数的限定名不含 ``.``;类方法、装饰器包装和嵌套函数
|
||||
的限定名含 ``.``。局部作用域自由函数(如测试内联 handler)限定名形如
|
||||
``func.<locals>.handler``,与装饰器包装方法 ``SiteStatistic.<locals>.
|
||||
wrapper`` 无法靠限定名区分,需按调用约定兜底:签名首参为 self/cls
|
||||
才视为类方法声明。模块卸载后残留的类方法一旦被 unbound 直调,会把
|
||||
event 吞进 self 触发 missing event TypeError,因此必须跳过等待重载自愈。
|
||||
"""
|
||||
parts = handler.__qualname__.split(".")
|
||||
return len(parts) >= 2 and "<locals>" not in parts
|
||||
if len(parts) < 2:
|
||||
return False
|
||||
if "<locals>" not in parts:
|
||||
return True
|
||||
try:
|
||||
parameters = list(inspect.signature(handler).parameters.values())
|
||||
except (TypeError, ValueError):
|
||||
return True
|
||||
if not parameters:
|
||||
return True
|
||||
return parameters[0].name in ("self", "cls")
|
||||
|
||||
@staticmethod
|
||||
def owner_class(handler: Callable) -> Optional[Type[Any]]:
|
||||
|
||||
Reference in New Issue
Block a user