aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/optmanager.py20
-rw-r--r--mitmproxy/tools/console/options.py17
-rw-r--r--test/mitmproxy/test_optmanager.py37
3 files changed, 58 insertions, 16 deletions
diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py
index 20492f82..0421d4be 100644
--- a/mitmproxy/optmanager.py
+++ b/mitmproxy/optmanager.py
@@ -1,6 +1,7 @@
import contextlib
import blinker
import pprint
+import inspect
from mitmproxy import exceptions
from mitmproxy.utils import typecheck
@@ -12,6 +13,10 @@ from mitmproxy.utils import typecheck
class OptManager:
"""
+ OptManager is the base class from which Options objects are derived.
+ Note that the __init__ method of all child classes must force all
+ arguments to be positional only, by including a "*" argument.
+
.changed is a blinker Signal that triggers whenever options are
updated. If any handler in the chain raises an exceptions.OptionsError
exception, all changes are rolled back, the exception is suppressed,
@@ -26,6 +31,15 @@ class OptManager:
# ._initialized = True as the final operation.
instance = super().__new__(cls)
instance.__dict__["_opts"] = {}
+
+ defaults = {}
+ for klass in reversed(inspect.getmro(cls)):
+ for p in inspect.signature(klass.__init__).parameters.values():
+ if p.kind in (p.KEYWORD_ONLY, p.POSITIONAL_OR_KEYWORD):
+ if not p.default == p.empty:
+ defaults[p.name] = p.default
+ instance.__dict__["_defaults"] = defaults
+
return instance
def __init__(self):
@@ -78,6 +92,12 @@ class OptManager:
def get(self, k, d=None):
return self._opts.get(k, d)
+ def reset(self):
+ """
+ Restore defaults for all options.
+ """
+ self.update(**self._defaults)
+
def update(self, **kwargs):
updated = set(kwargs.keys())
for k, v in kwargs.items():
diff --git a/mitmproxy/tools/console/options.py b/mitmproxy/tools/console/options.py
index 824041dc..9d698161 100644
--- a/mitmproxy/tools/console/options.py
+++ b/mitmproxy/tools/console/options.py
@@ -160,22 +160,7 @@ class Options(urwid.WidgetWrap):
return super().keypress(size, key)
def clearall(self):
- self.master.options.update(
- anticache = False,
- anticomp = False,
- ignore_hosts = (),
- tcp_hosts = (),
- replay_kill_extra = False,
- no_upstream_cert = False,
- refresh_server_playback = True,
- replacements = [],
- scripts = [],
- setheaders = [],
- showhost = False,
- stickyauth = None,
- stickycookie = None,
- default_contentview = "auto",
- )
+ self.master.options.reset()
signals.update_settings.send(self)
signals.status_message.send(
message = "All select.Options cleared",
diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py
index 3c845707..47e40d98 100644
--- a/test/mitmproxy/test_optmanager.py
+++ b/test/mitmproxy/test_optmanager.py
@@ -12,6 +12,43 @@ class TO(optmanager.OptManager):
super().__init__()
+class TD(optmanager.OptManager):
+ def __init__(self, one="done", two="dtwo", three="error"):
+ self.one = one
+ self.two = two
+ self.three = three
+ super().__init__()
+
+
+class TD2(TD):
+ def __init__(self, *, three="dthree", four="dfour", **kwargs):
+ self.three = three
+ self.four = four
+ super().__init__(**kwargs)
+
+
+def test_defaults():
+ o = TD2()
+ assert o._defaults == {
+ "one": "done",
+ "two": "dtwo",
+ "three": "dthree",
+ "four": "dfour",
+ }
+ newvals = dict(
+ one="xone",
+ two="xtwo",
+ three="xthree",
+ four="xfour",
+ )
+ o.update(**newvals)
+ for k, v in newvals.items():
+ assert v == o.get(k)
+ o.reset()
+ for k, v in o._defaults.items():
+ assert v == o.get(k)
+
+
def test_options():
o = TO(two="three")
assert o.keys() == set(["one", "two"])