Current Path: > > lib64 > python3.8 >
Operation : Linux premium107.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 Software : Apache Server IP : 198.54.126.246 | Your IP: 216.73.216.181 Domains : 1034 Domain(s) Permission : [ 0755 ]
| Name | Type | Size | Last Modified | Actions |
|---|---|---|---|---|
| __pycache__ | Directory | - | - | |
| asyncio | Directory | - | - | |
| collections | Directory | - | - | |
| concurrent | Directory | - | - | |
| config-3.8-x86_64-linux-gnu | Directory | - | - | |
| ctypes | Directory | - | - | |
| curses | Directory | - | - | |
| dbm | Directory | - | - | |
| distutils | Directory | - | - | |
| Directory | - | - | ||
| encodings | Directory | - | - | |
| ensurepip | Directory | - | - | |
| html | Directory | - | - | |
| http | Directory | - | - | |
| importlib | Directory | - | - | |
| json | Directory | - | - | |
| lib-dynload | Directory | - | - | |
| lib2to3 | Directory | - | - | |
| logging | Directory | - | - | |
| multiprocessing | Directory | - | - | |
| pydoc_data | Directory | - | - | |
| site-packages | Directory | - | - | |
| sqlite3 | Directory | - | - | |
| tkinter | Directory | - | - | |
| turtledemo | Directory | - | - | |
| unittest | Directory | - | - | |
| urllib | Directory | - | - | |
| venv | Directory | - | - | |
| wsgiref | Directory | - | - | |
| xml | Directory | - | - | |
| xmlrpc | Directory | - | - | |
| LICENSE.txt | File | 13937 bytes | June 06 2023 13:32:21. | |
| __future__.py | File | 5147 bytes | June 06 2023 13:32:21. | |
| __phello__.foo.py | File | 64 bytes | June 06 2023 13:32:21. | |
| _bootlocale.py | File | 1801 bytes | June 06 2023 13:32:21. | |
| _collections_abc.py | File | 26100 bytes | June 06 2023 13:32:21. | |
| _compat_pickle.py | File | 8749 bytes | June 06 2023 13:32:21. | |
| _compression.py | File | 5340 bytes | June 06 2023 13:32:21. | |
| _dummy_thread.py | File | 6027 bytes | June 06 2023 13:32:21. | |
| _markupbase.py | File | 14598 bytes | June 06 2023 13:32:21. | |
| _osx_support.py | File | 21774 bytes | June 06 2023 13:32:21. | |
| _py_abc.py | File | 6189 bytes | June 06 2023 13:32:21. | |
| _pydecimal.py | File | 228666 bytes | June 06 2023 13:32:21. | |
| _pyio.py | File | 93177 bytes | June 06 2023 13:32:21. | |
| _sitebuiltins.py | File | 3115 bytes | June 06 2023 13:32:21. | |
| _strptime.py | File | 25268 bytes | June 06 2023 13:32:21. | |
| _sysconfigdata__linux_x86_64-linux-gnu.py | File | 38510 bytes | October 17 2023 18:12:19. | |
| _sysconfigdata_d_linux_x86_64-linux-gnu.py | File | 38237 bytes | October 17 2023 18:03:44. | |
| _threading_local.py | File | 7220 bytes | June 06 2023 13:32:21. | |
| _weakrefset.py | File | 5735 bytes | June 06 2023 13:32:21. | |
| abc.py | File | 4489 bytes | June 06 2023 13:32:21. | |
| aifc.py | File | 32814 bytes | June 06 2023 13:32:21. | |
| antigravity.py | File | 477 bytes | June 06 2023 13:32:21. | |
| argparse.py | File | 96015 bytes | June 06 2023 13:32:21. | |
| ast.py | File | 19234 bytes | June 06 2023 13:32:21. | |
| asynchat.py | File | 11328 bytes | June 06 2023 13:32:21. | |
| asyncore.py | File | 20094 bytes | June 06 2023 13:32:21. | |
| base64.py | File | 20382 bytes | June 06 2023 13:32:21. | |
| bdb.py | File | 32056 bytes | June 06 2023 13:32:21. | |
| binhex.py | File | 13954 bytes | June 06 2023 13:32:21. | |
| bisect.py | File | 2214 bytes | June 06 2023 13:32:21. | |
| bz2.py | File | 12558 bytes | June 06 2023 13:32:21. | |
| cProfile.py | File | 7010 bytes | June 06 2023 13:32:21. | |
| calendar.py | File | 24832 bytes | June 06 2023 13:32:21. | |
| cgi.py | File | 33934 bytes | October 17 2023 18:02:14. | |
| cgitb.py | File | 12096 bytes | June 06 2023 13:32:21. | |
| chunk.py | File | 5435 bytes | June 06 2023 13:32:21. | |
| cmd.py | File | 14860 bytes | June 06 2023 13:32:21. | |
| code.py | File | 10622 bytes | June 06 2023 13:32:21. | |
| codecs.py | File | 36667 bytes | June 06 2023 13:32:21. | |
| codeop.py | File | 6330 bytes | June 06 2023 13:32:21. | |
| colorsys.py | File | 4064 bytes | June 06 2023 13:32:21. | |
| compileall.py | File | 13678 bytes | June 06 2023 13:32:21. | |
| configparser.py | File | 54374 bytes | June 06 2023 13:32:21. | |
| contextlib.py | File | 24995 bytes | June 06 2023 13:32:21. | |
| contextvars.py | File | 129 bytes | June 06 2023 13:32:21. | |
| copy.py | File | 8661 bytes | June 06 2023 13:32:21. | |
| copyreg.py | File | 7135 bytes | June 06 2023 13:32:21. | |
| crypt.py | File | 3610 bytes | June 06 2023 13:32:21. | |
| csv.py | File | 16144 bytes | June 06 2023 13:32:21. | |
| dataclasses.py | File | 49973 bytes | June 06 2023 13:32:21. | |
| datetime.py | File | 88287 bytes | June 06 2023 13:32:21. | |
| decimal.py | File | 320 bytes | June 06 2023 13:32:21. | |
| difflib.py | File | 84058 bytes | June 06 2023 13:32:21. | |
| dis.py | File | 20570 bytes | June 06 2023 13:32:21. | |
| doctest.py | File | 104543 bytes | June 06 2023 13:32:21. | |
| dummy_threading.py | File | 2815 bytes | June 06 2023 13:32:21. | |
| enum.py | File | 38136 bytes | June 06 2023 13:32:21. | |
| filecmp.py | File | 9830 bytes | June 06 2023 13:32:21. | |
| fileinput.py | File | 14709 bytes | June 06 2023 13:32:21. | |
| fnmatch.py | File | 4079 bytes | June 06 2023 13:32:21. | |
| formatter.py | File | 15143 bytes | June 06 2023 13:32:21. | |
| fractions.py | File | 24329 bytes | June 06 2023 13:32:21. | |
| ftplib.py | File | 35129 bytes | June 06 2023 13:32:21. | |
| functools.py | File | 37406 bytes | June 06 2023 13:32:21. | |
| genericpath.py | File | 4975 bytes | June 06 2023 13:32:21. | |
| getopt.py | File | 7489 bytes | June 06 2023 13:32:21. | |
| getpass.py | File | 5994 bytes | June 06 2023 13:32:21. | |
| gettext.py | File | 27138 bytes | June 06 2023 13:32:21. | |
| glob.py | File | 5697 bytes | June 06 2023 13:32:21. | |
| gzip.py | File | 21413 bytes | June 06 2023 13:32:21. | |
| hashlib.py | File | 8333 bytes | October 17 2023 18:02:14. | |
| heapq.py | File | 22877 bytes | June 06 2023 13:32:21. | |
| hmac.py | File | 7850 bytes | October 17 2023 18:02:14. | |
| imaplib.py | File | 53606 bytes | June 06 2023 13:32:21. | |
| imghdr.py | File | 3808 bytes | June 06 2023 13:32:21. | |
| imp.py | File | 10536 bytes | June 06 2023 13:32:21. | |
| inspect.py | File | 118550 bytes | June 06 2023 13:32:21. | |
| io.py | File | 3541 bytes | June 06 2023 13:32:21. | |
| ipaddress.py | File | 71644 bytes | June 06 2023 13:32:21. | |
| keyword.py | File | 945 bytes | June 06 2023 13:32:21. | |
| linecache.py | File | 5330 bytes | June 06 2023 13:32:21. | |
| locale.py | File | 78191 bytes | June 06 2023 13:32:21. | |
| lzma.py | File | 12983 bytes | June 06 2023 13:32:21. | |
| mailbox.py | File | 78661 bytes | June 06 2023 13:32:21. | |
| mailcap.py | File | 9067 bytes | June 06 2023 13:32:21. | |
| mimetypes.py | File | 21664 bytes | June 06 2023 13:32:21. | |
| modulefinder.py | File | 24430 bytes | June 06 2023 13:32:21. | |
| netrc.py | File | 5566 bytes | June 06 2023 13:32:21. | |
| nntplib.py | File | 43261 bytes | June 06 2023 13:32:21. | |
| ntpath.py | File | 27734 bytes | June 06 2023 13:32:21. | |
| nturl2path.py | File | 2887 bytes | June 06 2023 13:32:21. | |
| numbers.py | File | 10244 bytes | June 06 2023 13:32:21. | |
| opcode.py | File | 5808 bytes | June 06 2023 13:32:21. | |
| operator.py | File | 10711 bytes | June 06 2023 13:32:21. | |
| optparse.py | File | 60369 bytes | June 06 2023 13:32:21. | |
| os.py | File | 38995 bytes | June 06 2023 13:32:21. | |
| pathlib.py | File | 52610 bytes | June 06 2023 13:32:21. | |
| pdb.py | File | 62738 bytes | June 06 2023 13:32:21. | |
| pickle.py | File | 64467 bytes | June 06 2023 13:32:21. | |
| pickletools.py | File | 93486 bytes | June 06 2023 13:32:21. | |
| pipes.py | File | 8916 bytes | June 06 2023 13:32:21. | |
| pkgutil.py | File | 21500 bytes | June 06 2023 13:32:21. | |
| platform.py | File | 40425 bytes | June 06 2023 13:32:21. | |
| plistlib.py | File | 32220 bytes | June 06 2023 13:32:21. | |
| poplib.py | File | 15077 bytes | June 06 2023 13:32:21. | |
| posixpath.py | File | 15627 bytes | June 06 2023 13:32:21. | |
| pprint.py | File | 21484 bytes | June 06 2023 13:32:21. | |
| profile.py | File | 23546 bytes | June 06 2023 13:32:21. | |
| pstats.py | File | 27345 bytes | June 06 2023 13:32:21. | |
| pty.py | File | 4807 bytes | June 06 2023 13:32:21. | |
| py_compile.py | File | 8203 bytes | October 17 2023 18:02:14. | |
| pyclbr.py | File | 15255 bytes | June 06 2023 13:32:21. | |
| pydoc.py | File | 106700 bytes | October 17 2023 18:12:57. | |
| queue.py | File | 11356 bytes | June 06 2023 13:32:21. | |
| quopri.py | File | 7252 bytes | June 06 2023 13:32:21. | |
| random.py | File | 28802 bytes | June 06 2023 13:32:21. | |
| re.py | File | 15861 bytes | June 06 2023 13:32:21. | |
| reprlib.py | File | 5267 bytes | June 06 2023 13:32:21. | |
| rlcompleter.py | File | 7097 bytes | June 06 2023 13:32:21. | |
| runpy.py | File | 12052 bytes | June 06 2023 13:32:21. | |
| sched.py | File | 6442 bytes | June 06 2023 13:32:21. | |
| secrets.py | File | 2038 bytes | June 06 2023 13:32:21. | |
| selectors.py | File | 18561 bytes | June 06 2023 13:32:21. | |
| shelve.py | File | 8527 bytes | June 06 2023 13:32:21. | |
| shlex.py | File | 13325 bytes | June 06 2023 13:32:21. | |
| shutil.py | File | 51761 bytes | June 06 2023 13:32:21. | |
| signal.py | File | 2273 bytes | June 06 2023 13:32:21. | |
| site.py | File | 21838 bytes | October 17 2023 18:02:14. | |
| smtpd.py | File | 34709 bytes | June 06 2023 13:32:21. | |
| smtplib.py | File | 45001 bytes | June 06 2023 13:32:21. | |
| sndhdr.py | File | 7099 bytes | June 06 2023 13:32:21. | |
| socket.py | File | 35243 bytes | June 06 2023 13:32:21. | |
| socketserver.py | File | 27296 bytes | June 06 2023 13:32:21. | |
| sre_compile.py | File | 26695 bytes | June 06 2023 13:32:21. | |
| sre_constants.py | File | 7154 bytes | June 06 2023 13:32:21. | |
| sre_parse.py | File | 40230 bytes | June 06 2023 13:32:21. | |
| ssl.py | File | 50760 bytes | June 06 2023 13:32:21. | |
| stat.py | File | 5485 bytes | June 06 2023 13:32:21. | |
| statistics.py | File | 39690 bytes | June 06 2023 13:32:21. | |
| string.py | File | 10535 bytes | June 06 2023 13:32:21. | |
| stringprep.py | File | 12917 bytes | June 06 2023 13:32:21. | |
| struct.py | File | 257 bytes | June 06 2023 13:32:21. | |
| subprocess.py | File | 78250 bytes | June 06 2023 13:32:21. | |
| sunau.py | File | 18375 bytes | June 06 2023 13:32:21. | |
| symbol.py | File | 2109 bytes | October 17 2023 18:04:15. | |
| symtable.py | File | 8021 bytes | June 06 2023 13:32:21. | |
| sysconfig.py | File | 24896 bytes | October 17 2023 18:12:55. | |
| tabnanny.py | File | 11406 bytes | June 06 2023 13:32:21. | |
| tarfile.py | File | 106473 bytes | October 17 2023 18:02:14. | |
| telnetlib.py | File | 23254 bytes | June 06 2023 13:32:21. | |
| tempfile.py | File | 27537 bytes | June 06 2023 13:32:21. | |
| textwrap.py | File | 19407 bytes | June 06 2023 13:32:21. | |
| this.py | File | 1003 bytes | June 06 2023 13:32:21. | |
| threading.py | File | 50820 bytes | June 06 2023 13:32:21. | |
| timeit.py | File | 13480 bytes | June 06 2023 13:32:21. | |
| token.py | File | 2368 bytes | June 06 2023 13:32:21. | |
| tokenize.py | File | 25841 bytes | June 06 2023 13:32:21. | |
| trace.py | File | 29870 bytes | June 06 2023 13:32:21. | |
| traceback.py | File | 23611 bytes | June 06 2023 13:32:21. | |
| tracemalloc.py | File | 17076 bytes | June 06 2023 13:32:21. | |
| tty.py | File | 879 bytes | June 06 2023 13:32:21. | |
| turtle.py | File | 143716 bytes | June 06 2023 13:32:21. | |
| types.py | File | 9713 bytes | June 06 2023 13:32:21. | |
| typing.py | File | 68962 bytes | June 06 2023 13:32:21. | |
| uu.py | File | 7277 bytes | October 17 2023 18:12:57. | |
| uuid.py | File | 30515 bytes | October 17 2023 18:02:14. | |
| warnings.py | File | 19688 bytes | June 06 2023 13:32:21. | |
| wave.py | File | 18230 bytes | June 06 2023 13:32:21. | |
| weakref.py | File | 21387 bytes | June 06 2023 13:32:21. | |
| webbrowser.py | File | 24083 bytes | June 06 2023 13:32:21. | |
| xdrlib.py | File | 5913 bytes | June 06 2023 13:32:21. | |
| zipapp.py | File | 7535 bytes | June 06 2023 13:32:21. | |
| zipfile.py | File | 87728 bytes | June 06 2023 13:32:21. | |
| zipimport.py | File | 30765 bytes | June 06 2023 13:32:21. |
"""Tokenization help for Python programs.
tokenize(readline) is a generator that breaks a stream of bytes into
Python tokens. It decodes the bytes according to PEP-0263 for
determining source file encoding.
It accepts a readline-like method which is called repeatedly to get the
next line of input (or b"" for EOF). It generates 5-tuples with these
members:
the token type (see token.py)
the token (a string)
the starting (row, column) indices of the token (a 2-tuple of ints)
the ending (row, column) indices of the token (a 2-tuple of ints)
the original line (string)
It is designed to match the working of the Python tokenizer exactly, except
that it produces COMMENT tokens for comments and gives type OP for all
operators. Additionally, all token lists start with an ENCODING token
which tells you which encoding was used to decode the bytes stream.
"""
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
__credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, '
'Skip Montanaro, Raymond Hettinger, Trent Nelson, '
'Michael Foord')
from builtins import open as _builtin_open
from codecs import lookup, BOM_UTF8
import collections
from io import TextIOWrapper
import itertools as _itertools
import re
import sys
from token import *
from token import EXACT_TOKEN_TYPES
cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII)
import token
__all__ = token.__all__ + ["tokenize", "generate_tokens", "detect_encoding",
"untokenize", "TokenInfo"]
del token
class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')):
def __repr__(self):
annotated_type = '%d (%s)' % (self.type, tok_name[self.type])
return ('TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' %
self._replace(type=annotated_type))
@property
def exact_type(self):
if self.type == OP and self.string in EXACT_TOKEN_TYPES:
return EXACT_TOKEN_TYPES[self.string]
else:
return self.type
def group(*choices): return '(' + '|'.join(choices) + ')'
def any(*choices): return group(*choices) + '*'
def maybe(*choices): return group(*choices) + '?'
# Note: we use unicode matching for names ("\w") but ascii matching for
# number literals.
Whitespace = r'[ \f\t]*'
Comment = r'#[^\r\n]*'
Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
Name = r'\w+'
Hexnumber = r'0[xX](?:_?[0-9a-fA-F])+'
Binnumber = r'0[bB](?:_?[01])+'
Octnumber = r'0[oO](?:_?[0-7])+'
Decnumber = r'(?:0(?:_?0)*|[1-9](?:_?[0-9])*)'
Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
Exponent = r'[eE][-+]?[0-9](?:_?[0-9])*'
Pointfloat = group(r'[0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?',
r'\.[0-9](?:_?[0-9])*') + maybe(Exponent)
Expfloat = r'[0-9](?:_?[0-9])*' + Exponent
Floatnumber = group(Pointfloat, Expfloat)
Imagnumber = group(r'[0-9](?:_?[0-9])*[jJ]', Floatnumber + r'[jJ]')
Number = group(Imagnumber, Floatnumber, Intnumber)
# Return the empty string, plus all of the valid string prefixes.
def _all_string_prefixes():
# The valid string prefixes. Only contain the lower case versions,
# and don't contain any permutations (include 'fr', but not
# 'rf'). The various permutations will be generated.
_valid_string_prefixes = ['b', 'r', 'u', 'f', 'br', 'fr']
# if we add binary f-strings, add: ['fb', 'fbr']
result = {''}
for prefix in _valid_string_prefixes:
for t in _itertools.permutations(prefix):
# create a list with upper and lower versions of each
# character
for u in _itertools.product(*[(c, c.upper()) for c in t]):
result.add(''.join(u))
return result
def _compile(expr):
return re.compile(expr, re.UNICODE)
# Note that since _all_string_prefixes includes the empty string,
# StringPrefix can be the empty string (making it optional).
StringPrefix = group(*_all_string_prefixes())
# Tail end of ' string.
Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
# Tail end of " string.
Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
# Tail end of ''' string.
Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
# Tail end of """ string.
Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
Triple = group(StringPrefix + "'''", StringPrefix + '"""')
# Single-line ' or " string.
String = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
# Sorting in reverse order puts the long operators before their prefixes.
# Otherwise if = came before ==, == would get recognized as two instances
# of =.
Special = group(*map(re.escape, sorted(EXACT_TOKEN_TYPES, reverse=True)))
Funny = group(r'\r?\n', Special)
PlainToken = group(Number, Funny, String, Name)
Token = Ignore + PlainToken
# First (or only) line of ' or " string.
ContStr = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
group("'", r'\\\r?\n'),
StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
group('"', r'\\\r?\n'))
PseudoExtras = group(r'\\\r?\n|\Z', Comment, Triple)
PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
# For a given string prefix plus quotes, endpats maps it to a regex
# to match the remainder of that string. _prefix can be empty, for
# a normal single or triple quoted string (with no prefix).
endpats = {}
for _prefix in _all_string_prefixes():
endpats[_prefix + "'"] = Single
endpats[_prefix + '"'] = Double
endpats[_prefix + "'''"] = Single3
endpats[_prefix + '"""'] = Double3
# A set of all of the single and triple quoted string prefixes,
# including the opening quotes.
single_quoted = set()
triple_quoted = set()
for t in _all_string_prefixes():
for u in (t + '"', t + "'"):
single_quoted.add(u)
for u in (t + '"""', t + "'''"):
triple_quoted.add(u)
tabsize = 8
class TokenError(Exception): pass
class StopTokenizing(Exception): pass
class Untokenizer:
def __init__(self):
self.tokens = []
self.prev_row = 1
self.prev_col = 0
self.encoding = None
def add_whitespace(self, start):
row, col = start
if row < self.prev_row or row == self.prev_row and col < self.prev_col:
raise ValueError("start ({},{}) precedes previous end ({},{})"
.format(row, col, self.prev_row, self.prev_col))
row_offset = row - self.prev_row
if row_offset:
self.tokens.append("\\\n" * row_offset)
self.prev_col = 0
col_offset = col - self.prev_col
if col_offset:
self.tokens.append(" " * col_offset)
def untokenize(self, iterable):
it = iter(iterable)
indents = []
startline = False
for t in it:
if len(t) == 2:
self.compat(t, it)
break
tok_type, token, start, end, line = t
if tok_type == ENCODING:
self.encoding = token
continue
if tok_type == ENDMARKER:
break
if tok_type == INDENT:
indents.append(token)
continue
elif tok_type == DEDENT:
indents.pop()
self.prev_row, self.prev_col = end
continue
elif tok_type in (NEWLINE, NL):
startline = True
elif startline and indents:
indent = indents[-1]
if start[1] >= len(indent):
self.tokens.append(indent)
self.prev_col = len(indent)
startline = False
self.add_whitespace(start)
self.tokens.append(token)
self.prev_row, self.prev_col = end
if tok_type in (NEWLINE, NL):
self.prev_row += 1
self.prev_col = 0
return "".join(self.tokens)
def compat(self, token, iterable):
indents = []
toks_append = self.tokens.append
startline = token[0] in (NEWLINE, NL)
prevstring = False
for tok in _itertools.chain([token], iterable):
toknum, tokval = tok[:2]
if toknum == ENCODING:
self.encoding = tokval
continue
if toknum in (NAME, NUMBER):
tokval += ' '
# Insert a space between two consecutive strings
if toknum == STRING:
if prevstring:
tokval = ' ' + tokval
prevstring = True
else:
prevstring = False
if toknum == INDENT:
indents.append(tokval)
continue
elif toknum == DEDENT:
indents.pop()
continue
elif toknum in (NEWLINE, NL):
startline = True
elif startline and indents:
toks_append(indents[-1])
startline = False
toks_append(tokval)
def untokenize(iterable):
"""Transform tokens back into Python source code.
It returns a bytes object, encoded using the ENCODING
token, which is the first token sequence output by tokenize.
Each element returned by the iterable must be a token sequence
with at least two elements, a token number and token value. If
only two tokens are passed, the resulting output is poor.
Round-trip invariant for full input:
Untokenized source will match input source exactly
Round-trip invariant for limited input:
# Output bytes will tokenize back to the input
t1 = [tok[:2] for tok in tokenize(f.readline)]
newcode = untokenize(t1)
readline = BytesIO(newcode).readline
t2 = [tok[:2] for tok in tokenize(readline)]
assert t1 == t2
"""
ut = Untokenizer()
out = ut.untokenize(iterable)
if ut.encoding is not None:
out = out.encode(ut.encoding)
return out
def _get_normal_name(orig_enc):
"""Imitates get_normal_name in tokenizer.c."""
# Only care about the first 12 characters.
enc = orig_enc[:12].lower().replace("_", "-")
if enc == "utf-8" or enc.startswith("utf-8-"):
return "utf-8"
if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
return "iso-8859-1"
return orig_enc
def detect_encoding(readline):
"""
The 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 tokenize() generator.
It will call readline a maximum of twice, and return the encoding used
(as a string) and a list of any lines (left as 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-0263. If both a bom and a cookie are present,
but disagree, a SyntaxError will be raised. If the encoding cookie is an
invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
'utf-8-sig' is returned.
If no encoding is specified, then the default of 'utf-8' will be returned.
"""
try:
filename = readline.__self__.name
except AttributeError:
filename = None
bom_found = False
encoding = None
default = 'utf-8'
def read_or_stop():
try:
return readline()
except StopIteration:
return b''
def find_cookie(line):
try:
# Decode as UTF-8. Either the line is an encoding declaration,
# in which case it should be pure ASCII, or it must be UTF-8
# per default encoding.
line_string = line.decode('utf-8')
except UnicodeDecodeError:
msg = "invalid or missing encoding declaration"
if filename is not None:
msg = '{} for {!r}'.format(msg, filename)
raise SyntaxError(msg)
match = cookie_re.match(line_string)
if not match:
return None
encoding = _get_normal_name(match.group(1))
try:
codec = lookup(encoding)
except LookupError:
# This behaviour mimics the Python interpreter
if filename is None:
msg = "unknown encoding: " + encoding
else:
msg = "unknown encoding for {!r}: {}".format(filename,
encoding)
raise SyntaxError(msg)
if bom_found:
if encoding != 'utf-8':
# This behaviour mimics the Python interpreter
if filename is None:
msg = 'encoding problem: utf-8'
else:
msg = 'encoding problem for {!r}: utf-8'.format(filename)
raise SyntaxError(msg)
encoding += '-sig'
return encoding
first = read_or_stop()
if first.startswith(BOM_UTF8):
bom_found = True
first = first[3:]
default = 'utf-8-sig'
if not first:
return default, []
encoding = find_cookie(first)
if encoding:
return encoding, [first]
if not blank_re.match(first):
return default, [first]
second = read_or_stop()
if not second:
return default, [first]
encoding = find_cookie(second)
if encoding:
return encoding, [first, second]
return default, [first, second]
def open(filename):
"""Open a file in read only mode using the encoding detected by
detect_encoding().
"""
buffer = _builtin_open(filename, 'rb')
try:
encoding, lines = detect_encoding(buffer.readline)
buffer.seek(0)
text = TextIOWrapper(buffer, encoding, line_buffering=True)
text.mode = 'r'
return text
except:
buffer.close()
raise
def tokenize(readline):
"""
The tokenize() generator requires one argument, readline, which
must be a callable object which provides the same interface as the
readline() method of built-in file objects. Each call to the function
should return one line of input as bytes. Alternatively, readline
can be a callable function terminating with StopIteration:
readline = open(myfile, 'rb').__next__ # Example of alternate readline
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 is the
physical line.
The first token sequence will always be an ENCODING token
which tells you which encoding was used to decode the bytes stream.
"""
encoding, consumed = detect_encoding(readline)
empty = _itertools.repeat(b"")
rl_gen = _itertools.chain(consumed, iter(readline, b""), empty)
return _tokenize(rl_gen.__next__, encoding)
def _tokenize(readline, encoding):
lnum = parenlev = continued = 0
numchars = '0123456789'
contstr, needcont = '', 0
contline = None
indents = [0]
if encoding is not None:
if encoding == "utf-8-sig":
# BOM will already have been stripped.
encoding = "utf-8"
yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '')
last_line = b''
line = b''
while True: # loop over lines in stream
try:
# We capture the value of the line variable here because
# readline uses the empty string '' to signal end of input,
# hence `line` itself will always be overwritten at the end
# of this loop.
last_line = line
line = readline()
except StopIteration:
line = b''
if encoding is not None:
line = line.decode(encoding)
lnum += 1
pos, max = 0, len(line)
if contstr: # continued string
if not line:
raise TokenError("EOF in multi-line string", strstart)
endmatch = endprog.match(line)
if endmatch:
pos = end = endmatch.end(0)
yield TokenInfo(STRING, contstr + line[:end],
strstart, (lnum, end), contline + line)
contstr, needcont = '', 0
contline = None
elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
yield TokenInfo(ERRORTOKEN, contstr + line,
strstart, (lnum, len(line)), contline)
contstr = ''
contline = None
continue
else:
contstr = contstr + line
contline = contline + line
continue
elif parenlev == 0 and not continued: # new statement
if not line: break
column = 0
while pos < max: # measure leading whitespace
if line[pos] == ' ':
column += 1
elif line[pos] == '\t':
column = (column//tabsize + 1)*tabsize
elif line[pos] == '\f':
column = 0
else:
break
pos += 1
if pos == max:
break
if line[pos] in '#\r\n': # skip comments or blank lines
if line[pos] == '#':
comment_token = line[pos:].rstrip('\r\n')
yield TokenInfo(COMMENT, comment_token,
(lnum, pos), (lnum, pos + len(comment_token)), line)
pos += len(comment_token)
yield TokenInfo(NL, line[pos:],
(lnum, pos), (lnum, len(line)), line)
continue
if column > indents[-1]: # count indents or dedents
indents.append(column)
yield TokenInfo(INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
while column < indents[-1]:
if column not in indents:
raise IndentationError(
"unindent does not match any outer indentation level",
("<tokenize>", lnum, pos, line))
indents = indents[:-1]
yield TokenInfo(DEDENT, '', (lnum, pos), (lnum, pos), line)
else: # continued statement
if not line:
raise TokenError("EOF in multi-line statement", (lnum, 0))
continued = 0
while pos < max:
pseudomatch = _compile(PseudoToken).match(line, pos)
if pseudomatch: # scan for tokens
start, end = pseudomatch.span(1)
spos, epos, pos = (lnum, start), (lnum, end), end
if start == end:
continue
token, initial = line[start:end], line[start]
if (initial in numchars or # ordinary number
(initial == '.' and token != '.' and token != '...')):
yield TokenInfo(NUMBER, token, spos, epos, line)
elif initial in '\r\n':
if parenlev > 0:
yield TokenInfo(NL, token, spos, epos, line)
else:
yield TokenInfo(NEWLINE, token, spos, epos, line)
elif initial == '#':
assert not token.endswith("\n")
yield TokenInfo(COMMENT, token, spos, epos, line)
elif token in triple_quoted:
endprog = _compile(endpats[token])
endmatch = endprog.match(line, pos)
if endmatch: # all on one line
pos = endmatch.end(0)
token = line[start:pos]
yield TokenInfo(STRING, token, spos, (lnum, pos), line)
else:
strstart = (lnum, start) # multiple lines
contstr = line[start:]
contline = line
break
# Check up to the first 3 chars of the token to see if
# they're in the single_quoted set. If so, they start
# a string.
# We're using the first 3, because we're looking for
# "rb'" (for example) at the start of the token. If
# we switch to longer prefixes, this needs to be
# adjusted.
# Note that initial == token[:1].
# Also note that single quote checking must come after
# triple quote checking (above).
elif (initial in single_quoted or
token[:2] in single_quoted or
token[:3] in single_quoted):
if token[-1] == '\n': # continued string
strstart = (lnum, start)
# Again, using the first 3 chars of the
# token. This is looking for the matching end
# regex for the correct type of quote
# character. So it's really looking for
# endpats["'"] or endpats['"'], by trying to
# skip string prefix characters, if any.
endprog = _compile(endpats.get(initial) or
endpats.get(token[1]) or
endpats.get(token[2]))
contstr, needcont = line[start:], 1
contline = line
break
else: # ordinary string
yield TokenInfo(STRING, token, spos, epos, line)
elif initial.isidentifier(): # ordinary name
yield TokenInfo(NAME, token, spos, epos, line)
elif initial == '\\': # continued stmt
continued = 1
else:
if initial in '([{':
parenlev += 1
elif initial in ')]}':
parenlev -= 1
yield TokenInfo(OP, token, spos, epos, line)
else:
yield TokenInfo(ERRORTOKEN, line[pos],
(lnum, pos), (lnum, pos+1), line)
pos += 1
# Add an implicit NEWLINE if the input doesn't end in one
if last_line and last_line[-1] not in '\r\n':
yield TokenInfo(NEWLINE, '', (lnum - 1, len(last_line)), (lnum - 1, len(last_line) + 1), '')
for indent in indents[1:]: # pop remaining indent levels
yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '')
yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '')
def generate_tokens(readline):
"""Tokenize a source reading Python code as unicode strings.
This has the same API as tokenize(), except that it expects the *readline*
callable to return str objects instead of bytes.
"""
return _tokenize(readline, None)
def main():
import argparse
# Helper error handling routines
def perror(message):
sys.stderr.write(message)
sys.stderr.write('\n')
def error(message, filename=None, location=None):
if location:
args = (filename,) + location + (message,)
perror("%s:%d:%d: error: %s" % args)
elif filename:
perror("%s: error: %s" % (filename, message))
else:
perror("error: %s" % message)
sys.exit(1)
# Parse the arguments and options
parser = argparse.ArgumentParser(prog='python -m tokenize')
parser.add_argument(dest='filename', nargs='?',
metavar='filename.py',
help='the file to tokenize; defaults to stdin')
parser.add_argument('-e', '--exact', dest='exact', action='store_true',
help='display token names using the exact type')
args = parser.parse_args()
try:
# Tokenize the input
if args.filename:
filename = args.filename
with _builtin_open(filename, 'rb') as f:
tokens = list(tokenize(f.readline))
else:
filename = "<stdin>"
tokens = _tokenize(sys.stdin.readline, None)
# Output the tokenization
for token in tokens:
token_type = token.type
if args.exact:
token_type = token.exact_type
token_range = "%d,%d-%d,%d:" % (token.start + token.end)
print("%-20s%-15s%-15r" %
(token_range, tok_name[token_type], token.string))
except IndentationError as err:
line, column = err.args[1][1:3]
error(err.args[0], filename, (line, column))
except TokenError as err:
line, column = err.args[1]
error(err.args[0], filename, (line, column))
except SyntaxError as err:
error(err, filename)
except OSError as err:
error(err)
except KeyboardInterrupt:
print("interrupted\n")
except Exception as err:
perror("unexpected error: %s" % err)
raise
if __name__ == "__main__":
main()
SILENT KILLER Tool