Repository: mitmproxy/mitmproxy

Issue:
Script Reloader Tests fail on OSX
The script reloader tests currently fail on OSX and are thereby disabled. The feature is awesome though, so we should get them running. Maybe just forcing the polling reloader [on OSX] could do the job.



Discussion:

Resolving patch:
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -666,7 +666,7 @@ def unload_script(self, script_obj):
         script.reloader.unwatch(script_obj)
         self.scripts.remove(script_obj)
 
-    def load_script(self, command, use_reloader=False):
+    def load_script(self, command, use_reloader=True):
         """
             Loads a script. Returns an error description if something went
             wrong.
@@ -1040,14 +1040,14 @@ def handle_script_change(self, s):
             s.unload()
         except script.ScriptException as e:
             ok = False
-            self.add_event('Error reloading "{}": {}'.format(s.filename, str(e)))
+            self.add_event('Error reloading "{}": {}'.format(s.filename, str(e)), 'error')
         try:
             s.load()
         except script.ScriptException as e:
             ok = False
-            self.add_event('Error reloading "{}": {}'.format(s.filename, str(e)))
+            self.add_event('Error reloading "{}": {}'.format(s.filename, str(e)), 'error')
         else:
-            self.add_event('"{}" reloaded.'.format(s.filename))
+            self.add_event('"{}" reloaded.'.format(s.filename), 'info')
         return ok
 
     def shutdown(self):
diff --git a/libmproxy/script/reloader.py b/libmproxy/script/reloader.py
--- a/libmproxy/script/reloader.py
+++ b/libmproxy/script/reloader.py
@@ -1,6 +1,12 @@
 import os
-from watchdog.events import PatternMatchingEventHandler
-from watchdog.observers import Observer
+import sys
+from watchdog.events import RegexMatchingEventHandler 
+if sys.platform == 'darwin':
+    from watchdog.observers.polling import PollingObserver as Observer
+else:
+    from watchdog.observers import Observer
+# The OSX reloader in watchdog 0.8.3 breaks when unobserving paths. 
+# We use the PollingObserver instead.
 
 _observers = {}
 
@@ -9,7 +15,8 @@ def watch(script, callback):
     if script in _observers:
         raise RuntimeError("Script already observed")
     script_dir = os.path.dirname(os.path.abspath(script.args[0]))
-    event_handler = _ScriptModificationHandler(callback)
+    script_name = os.path.basename(script.args[0])
+    event_handler = _ScriptModificationHandler(callback, filename=script_name)
     observer = Observer()
     observer.schedule(event_handler, script_dir)
     observer.start()
@@ -23,18 +30,17 @@ def unwatch(script):
         observer.join()
 
 
-class _ScriptModificationHandler(PatternMatchingEventHandler):
-    def __init__(self, callback):
-        # We could enumerate all relevant *.py files (as werkzeug does it),
-        # but our case looks like it isn't as simple as enumerating sys.modules.
-        # This should be good enough for now.
+class _ScriptModificationHandler(RegexMatchingEventHandler):
+    def __init__(self, callback, filename='.*'):
+
         super(_ScriptModificationHandler, self).__init__(
             ignore_directories=True,
-            patterns=["*.py"]
+            regexes=['.*'+filename]
         )
         self.callback = callback
 
     def on_modified(self, event):
         self.callback()
 
-__all__ = ["watch", "unwatch"]
\ No newline at end of file
+__all__ = ["watch", "unwatch"]
+


Test patch: