aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/optmanager.py
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@corte.si>2017-03-18 12:11:48 +1300
committerAldo Cortesi <aldo@corte.si>2017-03-19 10:32:22 +1300
commit4e24c95a61802fd6fb9a03fdffd0380d90c46e0c (patch)
treeb9a03918f7be0f373ae291a51bb9a451f3bc5aa1 /mitmproxy/optmanager.py
parent3f50d5fdbbd4c09a9b2f511f6e776930576b9633 (diff)
downloadmitmproxy-4e24c95a61802fd6fb9a03fdffd0380d90c46e0c.tar.gz
mitmproxy-4e24c95a61802fd6fb9a03fdffd0380d90c46e0c.tar.bz2
mitmproxy-4e24c95a61802fd6fb9a03fdffd0380d90c46e0c.zip
optmanager: cope with bound methods in .subscribe
Fixes #2122
Diffstat (limited to 'mitmproxy/optmanager.py')
-rw-r--r--mitmproxy/optmanager.py19
1 files changed, 14 insertions, 5 deletions
diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py
index 77990306..f1d6461d 100644
--- a/mitmproxy/optmanager.py
+++ b/mitmproxy/optmanager.py
@@ -1,9 +1,9 @@
import contextlib
import blinker
+import blinker._saferef
import pprint
import copy
import functools
-import weakref
import os
import typing
import textwrap
@@ -127,15 +127,24 @@ class OptManager:
Subscribe a callable to the .changed signal, but only for a
specified list of options. The callable should accept arguments
(options, updated), and may raise an OptionsError.
+
+ The event will automatically be unsubscribed if the callable goes out of scope.
"""
- func = weakref.proxy(func)
+ for i in opts:
+ if i not in self._options:
+ raise exceptions.OptionsError("No such option: %s" % i)
+
+ # We reuse blinker's safe reference functionality to cope with weakrefs
+ # to bound methods.
+ func = blinker._saferef.safe_ref(func)
@functools.wraps(func)
def _call(options, updated):
if updated.intersection(set(opts)):
- try:
- func(options, updated)
- except ReferenceError:
+ f = func()
+ if f:
+ f(options, updated)
+ else:
self.changed.disconnect(_call)
# Our wrapper function goes out of scope immediately, so we have to set