# Buggy code
def configure(self, options, updated):
    if "scripts" in updated:
        for s in options.scripts:
            if options.scripts.count(s) > 1:
                raise exceptions.OptionsError("Duplicate script: %s" % s)

        for a in ctx.master.addons.chain[:]:
            if isinstance(a, Script) and a.name not in options.scripts:
                ctx.log.info("Un-loading script: %s" % a.name)
                ctx.master.addons.remove(a)

        # The machinations below are to ensure that:
        #   - Scripts remain in the same order
        #   - Scripts are listed directly after the script addon. This is
        #   needed to ensure that interactions with, for instance, flow
        #   serialization remains correct.
        #   - Scripts are not initialized un-necessarily. If only a
        #   script's order in the script list has changed, it should simply
        #   be moved.

        current = {}
        for a in ctx.master.addons.chain[:]:
            if isinstance(a, Script):
                current[a.name] = a
                ctx.master.addons.chain.remove(a)

        ordered = []
        newscripts = []
        for s in options.scripts:
            if s in current:
                ordered.append(current[s])
            else:
                ctx.log.info("Loading script: %s" % s)
                sc = Script(s)
                ordered.append(sc)
                newscripts.append(sc)

        ochain = ctx.master.addons.chain
        pos = ochain.index(self)
        ctx.master.addons.chain = ochain[: pos + 1] + ordered + ochain[pos + 1 :]

        for s in newscripts:
            ctx.master.addons.startup(s)


# Traceback (mitmproxy.exceptions.OptionsError)
Traceback (most recent call last):
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/master.py", line 292, in run
self.loop.run()
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/main_loop.py", line 278, in run
self._run()
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/main_loop.py", line 376, in _run
self.event_loop.run()
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/main_loop.py", line 682, in run
self._loop()
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/main_loop.py", line 719, in _loop
self._watch_files[fd]()
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/raw_display.py", line 393, in <lambda>
event_loop, callback, self.get_available_raw_input())
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/raw_display.py", line 493, in parse_input
callback(processed, processed_codes)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/main_loop.py", line 403, in _update
self.process_input(keys)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/main_loop.py", line 503, in process_input
k = self._topmost_widget.keypress(self.screen_size, k)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/window.py", line 84, in keypress
k = super().keypress(size, k)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/urwid/container.py", line 1116, in keypress
return self.footer.keypress((maxcol,),key)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/statusbar.py", line 155, in keypress
return self.master.ab.keypress(*args, **kwargs)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/statusbar.py", line 110, in keypress
self.prompt_execute(self._w.get_edit_text())
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/statusbar.py", line 133, in prompt_execute
msg = p(txt)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/statusbar.py", line 21, in __call__
return self.callback(pth, *self.args)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/tools/console/master.py", line 150, in run_script_once
sc.run_once(command, [f])
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/addons/script.py", line 208, in run_once
sc = Script(command)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/addons/script.py", line 136, in __init__
self.path, self.args = parse_command(command)
File "/usr/local/var/pyenv/versions/3.5.0/lib/python3.5/site-packages/mitmproxy-2.0.0-py3.5.egg/mitmproxy/addons/script.py", line 37, in parse_command
raise exceptions.OptionsError("Not a file: %s" % args[0])
mitmproxy.exceptions.OptionsError: Not a file: /Users/wuten/Desktop

mitmproxy has crashed!
Please lodge a bug report at:
https://github.com/mitmproxy/mitmproxy
Shutting down...

# Fixed code
def configure(self, options, updated):
    if "scripts" in updated:
        for s in options.scripts:
            if options.scripts.count(s) > 1:
                raise exceptions.OptionsError("Duplicate script: %s" % s)

        for a in ctx.master.addons.chain[:]:
            if isinstance(a, Script) and a.name not in options.scripts:
                ctx.log.info("Un-loading script: %s" % a.name)
                ctx.master.addons.remove(a)

        # The machinations below are to ensure that:
        #   - Scripts remain in the same order
        #   - Scripts are listed directly after the script addon. This is
        #   needed to ensure that interactions with, for instance, flow
        #   serialization remains correct.
        #   - Scripts are not initialized un-necessarily. If only a
        #   script's order in the script list has changed, it should simply
        #   be moved.

        current = {}
        for a in ctx.master.addons.chain[:]:
            if isinstance(a, Script):
                current[a.name] = a
                ctx.master.addons.chain.remove(a)

        ordered = []
        newscripts = []
        for s in options.scripts:
            if s in current:
                ordered.append(current[s])
            else:
                ctx.log.info("Loading script: %s" % s)
                try:
                    sc = Script(s)
                except ValueError as e:
                    raise exceptions.OptionsError(str(e))
                ordered.append(sc)
                newscripts.append(sc)

        ochain = ctx.master.addons.chain
        pos = ochain.index(self)
        ctx.master.addons.chain = ochain[: pos + 1] + ordered + ochain[pos + 1 :]

        for s in newscripts:
            ctx.master.addons.startup(s)