diff --git a/mitmproxy/addons/script.py b/mitmproxy/addons/script.py index e90dd8855..b4274f8c3 100644 --- a/mitmproxy/addons/script.py +++ b/mitmproxy/addons/script.py @@ -52,11 +52,19 @@ class Script: def tick(self): if time.time() - self.last_load > self.ReloadInterval: - mtime = os.stat(self.fullpath).st_mtime + try: + mtime = os.stat(self.fullpath).st_mtime + except FileNotFoundError: + scripts = ctx.options.scripts + scripts.remove(self.path) + ctx.options.update(scripts=scripts) + return + if mtime > self.last_mtime: ctx.log.info("Loading script: %s" % self.path) if self.ns: ctx.master.addons.remove(self.ns) + del sys.modules[self.ns.__name__] self.ns = load_script(ctx, self.fullpath) if self.ns: # We're already running, so we have to explicitly register and diff --git a/test/mitmproxy/addons/test_script.py b/test/mitmproxy/addons/test_script.py index dd5349cb7..03b1f6208 100644 --- a/test/mitmproxy/addons/test_script.py +++ b/test/mitmproxy/addons/test_script.py @@ -1,6 +1,7 @@ import traceback import sys import time +import os import pytest from unittest import mock @@ -183,6 +184,20 @@ class TestScriptLoader: scripts = ["one", "one"] ) + def test_script_deletion(self): + tdir = tutils.test_data.path("mitmproxy/data/addonscripts/") + with open(tdir + "/dummy.py", 'w') as f: + f.write("\n") + with taddons.context() as tctx: + sl = script.ScriptLoader() + tctx.master.addons.add(sl) + tctx.configure(sl, scripts=[tutils.test_data.path("mitmproxy/data/addonscripts/dummy.py")]) + + os.remove(tutils.test_data.path("mitmproxy/data/addonscripts/dummy.py")) + tctx.invoke(sl, "tick") + assert not tctx.options.scripts + assert not sl.addons + def test_order(self): rec = tutils.test_data.path("mitmproxy/data/addonscripts/recorder") sc = script.ScriptLoader()