# Buggy code
def lex(self, text: Union[str, bytes], first_line: int) -> None:
    """Lexically analyze a string, storing the tokens at the tok list."""
    self.i = 0
    self.line = first_line

    if isinstance(text, bytes):
        if text.startswith(b"\xef\xbb\xbf"):
            self.enc = "utf8"
            bom = True
        else:
            self.enc, enc_line = find_python_encoding(text, self.pyversion)
            bom = False
        try:
            decoded_text = text.decode(self.enc)
        except UnicodeDecodeError as err:
            self.report_unicode_decode_error(err, text)
            return
        except LookupError:
            self.report_unknown_encoding(enc_line)
            return
        text = decoded_text
        if bom:
            self.add_token(Bom(text[0]))
    self.s = text

    # Parse initial indent; otherwise first-line indent would not generate
    # an error.
    self.lex_indent()

    # Make a local copy of map as a simple optimization.
    map = self.map

    # Lex the file. Repeatedly call the lexer method for the current char.
    while self.i < len(text):
        # Get the character code of the next character to lex.
        c = ord(text[self.i])
        # Dispatch to the relevant lexer method. This will consume some
        # characters in the text, add a token to self.tok and increment
        # self.i.
        map[c]()

    # Append a break if there is no statement/block terminator at the end
    # of input.
    if len(self.tok) > 0 and (
        not isinstance(self.tok[-1], Break) and not isinstance(self.tok[-1], Dedent)
    ):
        self.add_token(Break(""))

    # Attach any dangling comments/whitespace to a final Break token.
    if self.tok and isinstance(self.tok[-1], Break):
        self.tok[-1].string += self.pre_whitespace
        self.pre_whitespace = ""

    # Close remaining open blocks with Dedent tokens.
    self.lex_indent()

    self.add_token(Eof(""))


# Traceback (IndexError)
Traceback (most recent call last):
File "/usr/local/lib/python3.5/runpy.py", line 184, in _run_module_as_main
"__main__", mod_spec)
File "/usr/local/lib/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/guido/src/mypy/mypy/__main__.py", line 5, in <module>
main(None)
File "/Users/guido/src/mypy/mypy/main.py", line 53, in main
type_check_only(sources, bin_dir, options)
File "/Users/guido/src/mypy/mypy/main.py", line 96, in type_check_only
python_path=options.python_path)
File "/Users/guido/src/mypy/mypy/build.py", line 203, in build
result = manager.process(initial_states)
File "/Users/guido/src/mypy/mypy/build.py", line 386, in process
next.process()
File "/Users/guido/src/mypy/mypy/build.py", line 710, in process
tree = self.parse(self.program_text, self.path)
File "/Users/guido/src/mypy/mypy/build.py", line 807, in parse
custom_typing_module=self.manager.custom_typing_module)
File "/Users/guido/src/mypy/mypy/parse.py", line 83, in parse
tree = parser.parse(source)
File "/Users/guido/src/mypy/mypy/parse.py", line 130, in parse
is_stub_file=self.is_stub_file)
File "/Users/guido/src/mypy/mypy/lex.py", line 170, in lex
l.lex(string, first_line)
File "/Users/guido/src/mypy/mypy/lex.py", line 377, in lex
map[c]()
IndexError: list index out of range

# Fixed code
def lex(self, text: Union[str, bytes], first_line: int) -> None:
    """Lexically analyze a string, storing the tokens at the tok list."""
    self.i = 0
    self.line = first_line

    if isinstance(text, bytes):
        if text.startswith(b"\xef\xbb\xbf"):
            self.enc = "utf8"
            bom = True
        else:
            self.enc, enc_line = find_python_encoding(text, self.pyversion)
            bom = False
        try:
            decoded_text = text.decode(self.enc)
        except UnicodeDecodeError as err:
            self.report_unicode_decode_error(err, text)
            return
        except LookupError:
            self.report_unknown_encoding(enc_line)
            return
        text = decoded_text
        if bom:
            self.add_token(Bom(text[0]))
    self.s = text

    # Parse initial indent; otherwise first-line indent would not generate
    # an error.
    self.lex_indent()

    # Use some local variables as a simple optimization.
    map = self.map
    default = self.unknown_character

    # Lex the file. Repeatedly call the lexer method for the current char.
    while self.i < len(text):
        # Get the character code of the next character to lex.
        c = text[self.i]
        # Dispatch to the relevant lexer method. This will consume some
        # characters in the text, add a token to self.tok and increment
        # self.i.
        map.get(c, default)()

    # Append a break if there is no statement/block terminator at the end
    # of input.
    if len(self.tok) > 0 and (
        not isinstance(self.tok[-1], Break) and not isinstance(self.tok[-1], Dedent)
    ):
        self.add_token(Break(""))

    # Attach any dangling comments/whitespace to a final Break token.
    if self.tok and isinstance(self.tok[-1], Break):
        self.tok[-1].string += self.pre_whitespace
        self.pre_whitespace = ""

    # Close remaining open blocks with Dedent tokens.
    self.lex_indent()

    self.add_token(Eof(""))