| :mod:`tokenize` --- Tokenizer for Python source | 
 | =============================================== | 
 |  | 
 | .. module:: tokenize | 
 |    :synopsis: Lexical scanner for Python source code. | 
 | .. moduleauthor:: Ka Ping Yee | 
 | .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org> | 
 |  | 
 | **Source code:** :source:`Lib/tokenize.py` | 
 |  | 
 | -------------- | 
 |  | 
 | The :mod:`tokenize` module provides a lexical scanner for Python source code, | 
 | implemented in Python.  The scanner in this module returns comments as tokens | 
 | as well, making it useful for implementing "pretty-printers," including | 
 | colorizers for on-screen displays. | 
 |  | 
 | To simplify token stream handling, all :ref:`operators` and :ref:`delimiters` | 
 | tokens are returned using the generic :data:`token.OP` token type.  The exact | 
 | type can be determined by checking the ``exact_type`` property on the | 
 | :term:`named tuple` returned from :func:`tokenize.tokenize`. | 
 |  | 
 | Tokenizing Input | 
 | ---------------- | 
 |  | 
 | The primary entry point is a :term:`generator`: | 
 |  | 
 | .. function:: tokenize(readline) | 
 |  | 
 |    The :func:`.tokenize` generator requires one argument, *readline*, which | 
 |    must be a callable object which provides the same interface as the | 
 |    :meth:`io.IOBase.readline` method of file objects.  Each call to the | 
 |    function should return one line of input as bytes. | 
 |  | 
 |    The generator produces 5-tuples with these members: the token type; the | 
 |    token string; a 2-tuple ``(srow, scol)`` of ints specifying the row and | 
 |    column where the token begins in the source; a 2-tuple ``(erow, ecol)`` of | 
 |    ints specifying the row and column where the token ends in the source; and | 
 |    the line on which the token was found. The line passed (the last tuple item) | 
 |    is the *logical* line; continuation lines are included.  The 5 tuple is | 
 |    returned as a :term:`named tuple` with the field names: | 
 |    ``type string start end line``. | 
 |  | 
 |    The returned :term:`named tuple` has an additional property named | 
 |    ``exact_type`` that contains the exact operator type for | 
 |    :data:`token.OP` tokens.  For all other token types ``exact_type`` | 
 |    equals the named tuple ``type`` field. | 
 |  | 
 |    .. versionchanged:: 3.1 | 
 |       Added support for named tuples. | 
 |  | 
 |    .. versionchanged:: 3.3 | 
 |       Added support for ``exact_type``. | 
 |  | 
 |    :func:`.tokenize` determines the source encoding of the file by looking for a | 
 |    UTF-8 BOM or encoding cookie, according to :pep:`263`. | 
 |  | 
 |  | 
 | All constants from the :mod:`token` module are also exported from | 
 | :mod:`tokenize`, as are three additional token type values: | 
 |  | 
 | .. data:: COMMENT | 
 |  | 
 |    Token value used to indicate a comment. | 
 |  | 
 |  | 
 | .. data:: NL | 
 |  | 
 |    Token value used to indicate a non-terminating newline.  The NEWLINE token | 
 |    indicates the end of a logical line of Python code; NL tokens are generated | 
 |    when a logical line of code is continued over multiple physical lines. | 
 |  | 
 |  | 
 | .. data:: ENCODING | 
 |  | 
 |     Token value that indicates the encoding used to decode the source bytes | 
 |     into text. The first token returned by :func:`.tokenize` will always be an | 
 |     ENCODING token. | 
 |  | 
 |  | 
 | Another function is provided to reverse the tokenization process. This is | 
 | useful for creating tools that tokenize a script, modify the token stream, and | 
 | write back the modified script. | 
 |  | 
 |  | 
 | .. function:: untokenize(iterable) | 
 |  | 
 |     Converts tokens back into Python source code.  The *iterable* must return | 
 |     sequences with at least two elements, the token type and the token string. | 
 |     Any additional sequence elements are ignored. | 
 |  | 
 |     The reconstructed script is returned as a single string.  The result is | 
 |     guaranteed to tokenize back to match the input so that the conversion is | 
 |     lossless and round-trips are assured.  The guarantee applies only to the | 
 |     token type and token string as the spacing between tokens (column | 
 |     positions) may change. | 
 |  | 
 |     It returns bytes, encoded using the ENCODING token, which is the first | 
 |     token sequence output by :func:`.tokenize`. | 
 |  | 
 |  | 
 | :func:`.tokenize` needs to detect the encoding of source files it tokenizes. The | 
 | function it uses to do this is available: | 
 |  | 
 | .. function:: detect_encoding(readline) | 
 |  | 
 |     The :func:`detect_encoding` function is used to detect the encoding that | 
 |     should be used to decode a Python source file. It requires one argument, | 
 |     readline, in the same way as the :func:`.tokenize` generator. | 
 |  | 
 |     It will call readline a maximum of twice, and return the encoding used | 
 |     (as a string) and a list of any lines (not decoded from bytes) it has read | 
 |     in. | 
 |  | 
 |     It detects the encoding from the presence of a UTF-8 BOM or an encoding | 
 |     cookie as specified in :pep:`263`. If both a BOM and a cookie are present, | 
 |     but disagree, a SyntaxError will be raised. Note that if the BOM is found, | 
 |     ``'utf-8-sig'`` will be returned as an encoding. | 
 |  | 
 |     If no encoding is specified, then the default of ``'utf-8'`` will be | 
 |     returned. | 
 |  | 
 |     Use :func:`.open` to open Python source files: it uses | 
 |     :func:`detect_encoding` to detect the file encoding. | 
 |  | 
 |  | 
 | .. function:: open(filename) | 
 |  | 
 |    Open a file in read only mode using the encoding detected by | 
 |    :func:`detect_encoding`. | 
 |  | 
 |    .. versionadded:: 3.2 | 
 |  | 
 | .. exception:: TokenError | 
 |  | 
 |    Raised when either a docstring or expression that may be split over several | 
 |    lines is not completed anywhere in the file, for example:: | 
 |  | 
 |       """Beginning of | 
 |       docstring | 
 |  | 
 |    or:: | 
 |  | 
 |       [1, | 
 |        2, | 
 |        3 | 
 |  | 
 | Note that unclosed single-quoted strings do not cause an error to be | 
 | raised. They are tokenized as ``ERRORTOKEN``, followed by the tokenization of | 
 | their contents. | 
 |  | 
 |  | 
 | .. _tokenize-cli: | 
 |  | 
 | Command-Line Usage | 
 | ------------------ | 
 |  | 
 | .. versionadded:: 3.3 | 
 |  | 
 | The :mod:`tokenize` module can be executed as a script from the command line. | 
 | It is as simple as: | 
 |  | 
 | .. code-block:: sh | 
 |  | 
 |    python -m tokenize [-e] [filename.py] | 
 |  | 
 | The following options are accepted: | 
 |  | 
 | .. program:: tokenize | 
 |  | 
 | .. cmdoption:: -h, --help | 
 |  | 
 |    show this help message and exit | 
 |  | 
 | .. cmdoption:: -e, --exact | 
 |  | 
 |    display token names using the exact type | 
 |  | 
 | If :file:`filename.py` is specified its contents are tokenized to stdout. | 
 | Otherwise, tokenization is performed on stdin. | 
 |  | 
 | Examples | 
 | ------------------ | 
 |  | 
 | Example of a script rewriter that transforms float literals into Decimal | 
 | objects:: | 
 |  | 
 |     from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP | 
 |     from io import BytesIO | 
 |  | 
 |     def decistmt(s): | 
 |         """Substitute Decimals for floats in a string of statements. | 
 |  | 
 |         >>> from decimal import Decimal | 
 |         >>> s = 'print(+21.3e-5*-.1234/81.7)' | 
 |         >>> decistmt(s) | 
 |         "print (+Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7'))" | 
 |  | 
 |         The format of the exponent is inherited from the platform C library. | 
 |         Known cases are "e-007" (Windows) and "e-07" (not Windows).  Since | 
 |         we're only showing 12 digits, and the 13th isn't close to 5, the | 
 |         rest of the output should be platform-independent. | 
 |  | 
 |         >>> exec(s)  #doctest: +ELLIPSIS | 
 |         -3.21716034272e-0...7 | 
 |  | 
 |         Output from calculations with Decimal should be identical across all | 
 |         platforms. | 
 |  | 
 |         >>> exec(decistmt(s)) | 
 |         -3.217160342717258261933904529E-7 | 
 |         """ | 
 |         result = [] | 
 |         g = tokenize(BytesIO(s.encode('utf-8')).readline)  # tokenize the string | 
 |         for toknum, tokval, _, _, _ in g: | 
 |             if toknum == NUMBER and '.' in tokval:  # replace NUMBER tokens | 
 |                 result.extend([ | 
 |                     (NAME, 'Decimal'), | 
 |                     (OP, '('), | 
 |                     (STRING, repr(tokval)), | 
 |                     (OP, ')') | 
 |                 ]) | 
 |             else: | 
 |                 result.append((toknum, tokval)) | 
 |         return untokenize(result).decode('utf-8') | 
 |  | 
 | Example of tokenizing from the command line.  The script:: | 
 |  | 
 |     def say_hello(): | 
 |         print("Hello, World!") | 
 |  | 
 |     say_hello() | 
 |  | 
 | will be tokenized to the following output where the first column is the range | 
 | of the line/column coordinates where the token is found, the second column is | 
 | the name of the token, and the final column is the value of the token (if any) | 
 |  | 
 | .. code-block:: sh | 
 |  | 
 |     $ python -m tokenize hello.py | 
 |     0,0-0,0:            ENCODING       'utf-8' | 
 |     1,0-1,3:            NAME           'def' | 
 |     1,4-1,13:           NAME           'say_hello' | 
 |     1,13-1,14:          OP             '(' | 
 |     1,14-1,15:          OP             ')' | 
 |     1,15-1,16:          OP             ':' | 
 |     1,16-1,17:          NEWLINE        '\n' | 
 |     2,0-2,4:            INDENT         '    ' | 
 |     2,4-2,9:            NAME           'print' | 
 |     2,9-2,10:           OP             '(' | 
 |     2,10-2,25:          STRING         '"Hello, World!"' | 
 |     2,25-2,26:          OP             ')' | 
 |     2,26-2,27:          NEWLINE        '\n' | 
 |     3,0-3,1:            NL             '\n' | 
 |     4,0-4,0:            DEDENT         '' | 
 |     4,0-4,9:            NAME           'say_hello' | 
 |     4,9-4,10:           OP             '(' | 
 |     4,10-4,11:          OP             ')' | 
 |     4,11-4,12:          NEWLINE        '\n' | 
 |     5,0-5,0:            ENDMARKER      '' | 
 |  | 
 | The exact token type names can be displayed using the ``-e`` option: | 
 |  | 
 | .. code-block:: sh | 
 |  | 
 |     $ python -m tokenize -e hello.py | 
 |     0,0-0,0:            ENCODING       'utf-8' | 
 |     1,0-1,3:            NAME           'def' | 
 |     1,4-1,13:           NAME           'say_hello' | 
 |     1,13-1,14:          LPAR           '(' | 
 |     1,14-1,15:          RPAR           ')' | 
 |     1,15-1,16:          COLON          ':' | 
 |     1,16-1,17:          NEWLINE        '\n' | 
 |     2,0-2,4:            INDENT         '    ' | 
 |     2,4-2,9:            NAME           'print' | 
 |     2,9-2,10:           LPAR           '(' | 
 |     2,10-2,25:          STRING         '"Hello, World!"' | 
 |     2,25-2,26:          RPAR           ')' | 
 |     2,26-2,27:          NEWLINE        '\n' | 
 |     3,0-3,1:            NL             '\n' | 
 |     4,0-4,0:            DEDENT         '' | 
 |     4,0-4,9:            NAME           'say_hello' | 
 |     4,9-4,10:           LPAR           '(' | 
 |     4,10-4,11:          RPAR           ')' | 
 |     4,11-4,12:          NEWLINE        '\n' | 
 |     5,0-5,0:            ENDMARKER      '' |