diff --git a/docs/scripts/events.py b/docs/scripts/events.py old mode 100644 new mode 100755 index d7c26ca81..2623818a3 --- a/docs/scripts/events.py +++ b/docs/scripts/events.py @@ -49,7 +49,8 @@ def category(name: str, hooks: List[Type[events.MitmproxyEvent]]) -> None: first = False else: print() - assert hook.name not in known + if hook.name in known: + raise RuntimeError(f"Already documented: {hook}") known.add(hook.name) doc = inspect.getdoc(hook) print(f"def {hook.name}({', '.join(str(p) for p in params)}):") diff --git a/mitmproxy/events.py b/mitmproxy/events.py index b7a5d2e9e..c3236c5bc 100644 --- a/mitmproxy/events.py +++ b/mitmproxy/events.py @@ -9,7 +9,6 @@ if TYPE_CHECKING: import mitmproxy.log -@dataclass class MitmproxyEvent: name: ClassVar[str] @@ -28,7 +27,7 @@ class MitmproxyEvent: def __init_subclass__(cls, **kwargs): # initialize .name attribute. HttpRequestHook -> http_request - if not getattr(cls, "name", None): + if cls.__dict__.get("name", None) is None: name = cls.__name__.replace("Hook", "").replace("Event", "") cls.name = re.sub('(?!^)([A-Z]+)', r'_\1', name).lower() if cls.name in all_events: diff --git a/mitmproxy/proxy/commands.py b/mitmproxy/proxy/commands.py index 45d74610e..e33ca93ac 100644 --- a/mitmproxy/proxy/commands.py +++ b/mitmproxy/proxy/commands.py @@ -97,9 +97,6 @@ class Hook(Command, mitmproxy.events.MitmproxyEvent): raise TypeError("Hook may not be instantiated directly.") return super().__new__(cls, *args, **kwargs) - def __repr__(self): - return f"Hook({self.name})" - class GetSocket(ConnectionCommand): """ diff --git a/test/mitmproxy/proxy/test_commands.py b/test/mitmproxy/proxy/test_commands.py index 98f344431..90d35e4d6 100644 --- a/test/mitmproxy/proxy/test_commands.py +++ b/test/mitmproxy/proxy/test_commands.py @@ -24,15 +24,9 @@ def test_hook(): commands.Hook() @dataclass - class FooHook(commands.Hook): + class TestHook(commands.Hook): data: bytes - f = FooHook(b"foo") - assert repr(f) + f = TestHook(b"foo") assert f.args() == [b"foo"] - assert FooHook in all_events.values() - - with pytest.raises(RuntimeError, match="Two conflicting event classes"): - @dataclass - class FooHook2(commands.Hook): - name = "foo" + assert TestHook in all_events.values() diff --git a/test/mitmproxy/test_events.py b/test/mitmproxy/test_events.py new file mode 100644 index 000000000..80209e334 --- /dev/null +++ b/test/mitmproxy/test_events.py @@ -0,0 +1,36 @@ +from dataclasses import dataclass + +import pytest + +from mitmproxy import events + + +def test_event(): + with pytest.raises(TypeError, match="may not be instantiated directly"): + events.MitmproxyEvent() + + class NoDataClass(events.MitmproxyEvent): + pass + + with pytest.raises(TypeError, match="not a dataclass"): + NoDataClass() + + @dataclass + class FooEvent(events.MitmproxyEvent): + data: bytes + + e = FooEvent(b"foo") + assert repr(e) + assert e.args() == [b"foo"] + assert FooEvent in events.all_events.values() + + with pytest.raises(RuntimeError, match="Two conflicting event classes"): + @dataclass + class FooEvent2(events.MitmproxyEvent): + name = "foo" + + @dataclass + class AnotherABC(events.MitmproxyEvent): + name = "" + + assert AnotherABC not in events.all_events.values() \ No newline at end of file