# Buggy code
def clip(
    self,
    flows: typing.Sequence[flow.Flow],
    cuts: mitmproxy.types.CutSpec,
) -> None:
    """
    Send cuts to the clipboard. If there are multiple flows or cuts, the
    format is UTF-8 encoded CSV. If there is exactly one row and one
    column, the data is written to file as-is, with raw bytes preserved.
    """
    fp = io.StringIO(newline="")
    if len(cuts) == 1 and len(flows) == 1:
        v = extract(cuts[0], flows[0])
        if isinstance(v, bytes):
            fp.write(strutils.always_str(v))
        else:
            fp.write("utf8")
        ctx.log.alert("Clipped single cut.")
    else:
        writer = csv.writer(fp)
        for f in flows:
            vals = [extract(c, f) for c in cuts]
            writer.writerow(
                [strutils.always_str(v) or "" for v in vals]  # type: ignore
            )
        ctx.log.alert("Clipped %s cuts as CSV." % len(cuts))
    pyperclip.copy(fp.getvalue())


# Traceback (pyperclip.PyperclipException)
Traceback (most recent call last):
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/master.py", line 216, in run
self.loop.run()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 278, in run
self._run()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 376, in _run
self.event_loop.run()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 682, in run
self._loop()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 719, in _loop
self._watch_files[fd]()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 393, in <lambda>
event_loop, callback, self.get_available_raw_input())
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 493, in parse_input
callback(processed, processed_codes)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 403, in _update
self.process_input(keys)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 503, in process_input
k = self._topmost_widget.keypress(self.screen_size, k)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/window.py", line 309, in keypress
k = super().keypress(size, k)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1116, in keypress
return self.footer.keypress((maxcol,),key)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 149, in keypress
return self.ab.keypress(*args, **kwargs)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 104, in keypress
self.prompt_execute(self._w.get_edit_text())
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 124, in prompt_execute
msg = p(txt)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/commandexecutor.py", line 17, in __call__
ret = self.master.commands.call(cmd)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 221, in call
return self.call_args(parts[0], parts[1:])
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 212, in call_args
return self.commands[path].call(args)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 101, in call
ret = self.func(*pargs)
File "/usr/lib/python3.5/contextlib.py", line 77, in __exit__
self.gen.throw(type, value, traceback)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/master.py", line 68, in handlecontext
yield
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 101, in call
ret = self.func(*pargs)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 251, in wrapper
return function(*args, **kwargs)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/addons/cut.py", line 139, in clip
pyperclip.copy(fp.getvalue())
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/pyperclip/__init__.py", line 574, in lazy_load_stub_copy
return copy(text)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/pyperclip/__init__.py", line 284, in __call__
raise PyperclipException(EXCEPT_MSG)
pyperclip.PyperclipException:
Pyperclip could not find a copy/paste mechanism for your system.
For more information, please visit https://pyperclip.readthedocs.io/en/latest/introduction.html#not-implemented-error

# Fixed code
def clip(
    self,
    flows: typing.Sequence[flow.Flow],
    cuts: mitmproxy.types.CutSpec,
) -> None:
    """
    Send cuts to the clipboard. If there are multiple flows or cuts, the
    format is UTF-8 encoded CSV. If there is exactly one row and one
    column, the data is written to file as-is, with raw bytes preserved.
    """
    fp = io.StringIO(newline="")
    if len(cuts) == 1 and len(flows) == 1:
        v = extract(cuts[0], flows[0])
        if isinstance(v, bytes):
            fp.write(strutils.always_str(v))
        else:
            fp.write("utf8")
        ctx.log.alert("Clipped single cut.")
    else:
        writer = csv.writer(fp)
        for f in flows:
            vals = [extract(c, f) for c in cuts]
            writer.writerow(
                [strutils.always_str(v) or "" for v in vals]  # type: ignore
            )
        ctx.log.alert("Clipped %s cuts as CSV." % len(cuts))
    try:
        pyperclip.copy(fp.getvalue())
    except pyperclip.PyperclipException as e:
        ctx.log.error(str(e))