def find_obfuscatables(tokens, obfunc, ignore_length=False):
global keyword_args<EOL>keyword_args = analyze.enumerate_keyword_args(tokens)<EOL>global imported_modules<EOL>imported_modules = analyze.enumerate_imports(tokens)<EOL>skip_line = False<EOL>skip_next = False<EOL>obfuscatables = []<EOL>for index, tok in enumerate(tokens):<EOL><INDENT>token_type = tok[<NUM_LIT:0>]<EOL>if token_type == tokenize.NEWLINE:<EOL><INDENT>skip_line = False<EOL><DEDENT>if skip_line:<EOL><INDENT>continue<EOL><DEDENT>result = obfunc(tokens, index, ignore_length=ignore_length)<EOL>if result:<EOL><INDENT>if skip_next:<EOL><INDENT>skip_next = False<EOL><DEDENT>elif result == '<STR_LIT>':<EOL><INDENT>skip_line = True<EOL><DEDENT>elif result == '<STR_LIT>':<EOL><INDENT>skip_next = True<EOL><DEDENT>elif result in obfuscatables:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>obfuscatables.append(result)<EOL><DEDENT><DEDENT>else: <EOL><INDENT>skip_next = False <EOL><DEDENT><DEDENT>return obfuscatables<EOL>
Iterates over *tokens*, which must be an equivalent output to what
tokenize.generate_tokens() produces, calling *obfunc* on each with the
following parameters:

    - **tokens:**     The current list of tokens.
    - **index:**      The current position in the list.

*obfunc* is expected to return the token string if that token can be safely
obfuscated **or** one of the following optional values which will instruct
find_obfuscatables() how to proceed:

    - **'__skipline__'**   Keep skipping tokens until a newline is reached.
    - **'__skipnext__'**   Skip the next token in the sequence.

If *ignore_length* is ``True`` then single-character obfuscatables will
be obfuscated anyway (even though it wouldn't save any space).