# Buggy code
def _read_set_cookie_pairs(s: str, off=0) -> Tuple[List[TPairs], int]:
    """
    Read pairs of lhs=rhs values from SetCookie headers while handling multiple cookies.

    off: start offset
    specials: attributes that are treated specially
    """
    cookies = []  # type: List[TPairs]
    pairs = []  # type: TPairs

    while True:
        lhs, off = _read_key(s, off, ";=,")
        lhs = lhs.lstrip()

        if lhs:
            rhs = None
            if off < len(s) and s[off] == "=":
                rhs, off = _read_value(s, off + 1, ";,")

                # Special handliing of attributes
                if lhs.lower() == "expires":
                    # 'expires' values can contain commas in them so they need to
                    # be handled separately.

                    # We actually bank on the fact that the expires value WILL
                    # contain a comma. Things will fail, if they don't.

                    # '3' is just a heuristic we use to determine whether we've
                    # only read a part of the expires value and we should read more.
                    if len(rhs) <= 3:
                        trail, off = _read_value(s, off + 1, ";,")
                        rhs = rhs + "," + trail

            pairs.append([lhs, rhs])

            # comma marks the beginning of a new cookie
            if off < len(s) and s[off] == ",":
                cookies.append(pairs)
                pairs = []

        off += 1

        if not off < len(s):
            break

    if pairs or not cookies:
        cookies.append(pairs)

    return cookies, off


# Traceback (AttributeError)
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 710, in _loop
self._entering_idle()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 671, in _entering_idle
callback()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 564, in entering_idle
self.draw_screen()
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 578, in draw_screen
canvas = self._topmost_widget.render(self.screen_size, focus=True)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1083, in render
focus and self.focus_part == 'body')
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/decoration.py", line 225, in render
canv = self._original_widget.render(size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1083, in render
focus and self.focus_part == 'body')
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 1750, in render
canv = get_delegate(self).render(size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 1750, in render
canv = get_delegate(self).render(size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1083, in render
focus and self.focus_part == 'body')
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 141, in cached_render
canv = fn(self, size, focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/listbox.py", line 455, in render
(maxcol, maxrow), focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/listbox.py", line 337, in calculate_visible
self._set_focus_complete( (maxcol, maxrow), focus )
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/listbox.py", line 702, in _set_focus_complete
(maxcol,maxrow), focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/listbox.py", line 672, in _set_focus_first_selectable
(maxcol, maxrow), focus=focus)
File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/listbox.py", line 340, in calculate_visible
focus_widget, focus_pos = self.body.get_focus()
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/grideditor/base.py", line 227, in get_focus
self.lst[self.focus]
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/grideditor/base.py", line 83, in __init__
w = self.editor.columns[i].Display(v)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/grideditor/col_text.py", line 18, in Display
return TDisplay(data, self.encoding_args)
File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/grideditor/col_text.py", line 31, in __init__
super().__init__(data.encode(*self.encoding_args))
AttributeError: 'NoneType' object has no attribute 'encode'

# Fixed code
def _read_set_cookie_pairs(s: str, off=0) -> Tuple[List[TPairs], int]:
    """
    Read pairs of lhs=rhs values from SetCookie headers while handling multiple cookies.

    off: start offset
    specials: attributes that are treated specially
    """
    cookies = []  # type: List[TPairs]
    pairs = []  # type: TPairs

    while True:
        lhs, off = _read_key(s, off, ";=,")
        lhs = lhs.lstrip()

        rhs = ""
        if off < len(s) and s[off] == "=":
            rhs, off = _read_value(s, off + 1, ";,")

            # Special handling of attributes
            if lhs.lower() == "expires":
                # 'expires' values can contain commas in them so they need to
                # be handled separately.

                # We actually bank on the fact that the expires value WILL
                # contain a comma. Things will fail, if they don't.

                # '3' is just a heuristic we use to determine whether we've
                # only read a part of the expires value and we should read more.
                if len(rhs) <= 3:
                    trail, off = _read_value(s, off + 1, ";,")
                    rhs = rhs + "," + trail
        if rhs or lhs:
            pairs.append([lhs, rhs])

            # comma marks the beginning of a new cookie
            if off < len(s) and s[off] == ",":
                cookies.append(pairs)
                pairs = []

        off += 1

        if not off < len(s):
            break

    if pairs or not cookies:
        cookies.append(pairs)

    return cookies, off