From eafff2ae439adb25e368b02c6f5e5bad1ec95a5c Mon Sep 17 00:00:00 2001 From: Chase Sterling Date: Fri, 8 Jul 2016 21:30:20 -0400 Subject: [PATCH 1/2] Cause an error when trying to hook invalid HookMixin method --- realms/lib/hook.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/realms/lib/hook.py b/realms/lib/hook.py index 61d2885..f4e012a 100644 --- a/realms/lib/hook.py +++ b/realms/lib/hook.py @@ -25,9 +25,12 @@ class HookMixinMeta(type): def __new__(cls, name, bases, attrs): super_new = super(HookMixinMeta, cls).__new__ + hookable = [] for key, value in attrs.items(): if callable(value): attrs[key] = hook_func(key, value) + hookable.append(key) + attrs['_hookable'] = hookable return super_new(cls, name, bases, attrs) @@ -37,9 +40,12 @@ class HookMixin(object): _pre_hooks = {} _post_hooks = {} + _hookable = [] @classmethod def after(cls, method_name): + assert method_name in cls._hookable, "'%s' not a hookable method of '%s'" % (method_name, cls.__name__) + def outer(f, *args, **kwargs): cls._post_hooks.setdefault(method_name, []).append((f, args, kwargs)) return f @@ -47,6 +53,8 @@ class HookMixin(object): @classmethod def before(cls, method_name): + assert method_name in cls._hookable, "'%s' not a hookable method of '%s'" % (method_name, cls.__name__) + def outer(f, *args, **kwargs): cls._pre_hooks.setdefault(method_name, []).append((f, args, kwargs)) return f From 533e52945d60ebdde9c7e9acc19c7f96b41bb028 Mon Sep 17 00:00:00 2001 From: Chase Sterling Date: Wed, 13 Jul 2016 21:05:49 -0400 Subject: [PATCH 2/2] Disallow _private methods to be hooked --- realms/lib/hook.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/realms/lib/hook.py b/realms/lib/hook.py index f4e012a..0327263 100644 --- a/realms/lib/hook.py +++ b/realms/lib/hook.py @@ -27,6 +27,9 @@ class HookMixinMeta(type): hookable = [] for key, value in attrs.items(): + # Disallow hooking methods which start with an underscore (allow __init__ etc. still) + if key.startswith('_') and not key.startswith('__'): + continue if callable(value): attrs[key] = hook_func(key, value) hookable.append(key)