def remove_comments(tokens):
preserved_shebang = "<STR_LIT>"<EOL>preserved_encoding = "<STR_LIT>"<EOL>for tok in tokens[<NUM_LIT:0>:<NUM_LIT:4>]: <EOL><INDENT>line = tok[<NUM_LIT:4>]<EOL>if analyze.shebang.match(line): <EOL><INDENT>preserved_shebang = line<EOL><DEDENT>elif analyze.encoding.match(line):<EOL><INDENT>preserved_encoding = line<EOL><DEDENT><DEDENT>prev_tok_type = <NUM_LIT:0><EOL>for index, tok in enumerate(tokens):<EOL><INDENT>token_type = tok[<NUM_LIT:0>]<EOL>if token_type == tokenize.COMMENT:<EOL><INDENT>tokens[index][<NUM_LIT:1>] = '<STR_LIT>' <EOL><DEDENT>prev_tok_type = token_type<EOL><DEDENT>if preserved_shebang: <EOL><INDENT>io_obj = io.StringIO(preserved_shebang + preserved_encoding)<EOL>preserved = [list(a) for a in tokenize.generate_tokens(io_obj.readline)]<EOL>preserved.pop() <EOL>preserved.reverse() <EOL>for item in preserved:<EOL><INDENT>tokens.insert(<NUM_LIT:0>, item)<EOL><DEDENT><DEDENT>
Removes comments from *tokens* which is expected to be a list equivalent of
tokenize.generate_tokens() (so we can update in-place).

.. note::

    * If the comment makes up the whole line, the newline will also be removed (so you don't end up with lots of blank lines).
    * Preserves shebangs and encoding strings.