diff options
| -rw-r--r-- | mitmproxy/addonmanager.py | 14 | ||||
| -rw-r--r-- | test/mitmproxy/test_addonmanager.py | 5 | 
2 files changed, 16 insertions, 3 deletions
| diff --git a/mitmproxy/addonmanager.py b/mitmproxy/addonmanager.py index ec82d650..9094288b 100644 --- a/mitmproxy/addonmanager.py +++ b/mitmproxy/addonmanager.py @@ -1,3 +1,4 @@ +import types  import typing  import traceback  import contextlib @@ -229,11 +230,18 @@ class AddonManager:          for a in traverse([addon]):              func = getattr(a, name, None)              if func: -                if not callable(func): +                if callable(func): +                    func(*args, **kwargs) +                elif isinstance(func, types.ModuleType): +                    # we gracefully exclude module imports with the same name as hooks. +                    # For example, a user may have "from mitmproxy import log" in an addon, +                    # which has the same name as the "log" hook. In this particular case, +                    # we end up in an error loop because we "log" this error. +                    pass +                else:                      raise exceptions.AddonManagerError( -                        "Addon handler %s not callable" % name +                        "Addon handler {} ({}) not callable".format(name, a)                      ) -                func(*args, **kwargs)      def trigger(self, name, *args, **kwargs):          """ diff --git a/test/mitmproxy/test_addonmanager.py b/test/mitmproxy/test_addonmanager.py index 678bc1b7..5bff61d1 100644 --- a/test/mitmproxy/test_addonmanager.py +++ b/test/mitmproxy/test_addonmanager.py @@ -117,6 +117,11 @@ def test_simple():          a.trigger("tick")          tctx.master.has_log("not callable") +        tctx.master.clear() +        a.get("one").tick = addons +        a.trigger("tick") +        assert not tctx.master.has_log("not callable") +          a.remove(a.get("one"))          assert not a.get("one") | 
